109
Qt Widgets In-Depth QWidget Under The Surface

Qt Widget In-Depth

Embed Size (px)

DESCRIPTION

Everything you want to know about QWidget, but were afraid to ask. QWidget is the base-class for all Qt's user interface objects. This talk will take an in-depth look at how QWidget works internally and how it interacts with the native windowing system. Presentation by Marius Bugge Monsen held during Qt Developer Days 2009. http://qt.nokia.com/developer/learning/elearning

Citation preview

Page 1: Qt Widget In-Depth

Qt Widgets In-DepthQWidget Under The Surface

Page 2: Qt Widget In-Depth

About Me

• Marius Bugge Monsen

• Qt Developer

• Qt Widgets Team Lead

Page 3: Qt Widget In-Depth

• Widgets and Window Systems

• Flags and Attributes

• The Future of Qt Widgets

Page 4: Qt Widget In-Depth

Widgets and Window Systemsby extranoise on flickr

Page 5: Qt Widget In-Depth

• Widgets and Window Systems

• Window Systems

• Windows and Widgets

• Updates and Painting

• Events and Loops

Page 6: Qt Widget In-Depth

• Widgets and Window Systems

• Window Systems

• Windows and Widgets

• Updates and Painting

• Events and Loops

Page 7: Qt Widget In-Depth

Rio

8 1/2Fresco/Berlin

FBUI

HP WindowsManaGeR

Metisse

MicroXwinNeWS

NeXT DPS

QWS

Quartz

SunView

TwinWayland X

Xynth

Y

DM

GEM

OPIE

Intuition

Microwindows

MiniGUI

OOHG

Page 8: Qt Widget In-Depth

• X11

• Desktop Window Manager (MS Windows)

• Quartz Compositor (Mac OS X)

• QWS

• S60 Window Manager

Page 9: Qt Widget In-Depth

Window Surface

Page 10: Qt Widget In-Depth

Surface

Surface

Page 11: Qt Widget In-Depth

Screen

Page 12: Qt Widget In-Depth

Window System

Page 13: Qt Widget In-Depth

Window System

Page 14: Qt Widget In-Depth

Window System Qt Application

#include<QtGui>int main(int argc, char *argv[]){ QApplication a(argc,argv); QWidget w; w.show(); return a.exec();}

IPC

Page 15: Qt Widget In-Depth

• Widgets and Window Systems

• Window Systems

• Windows and Widgets

• Updates and Painting

• Events and Loops

Page 16: Qt Widget In-Depth

Surface

Surface

Surface

Page 17: Qt Widget In-Depth

Surface

Surface Surface

Page 18: Qt Widget In-Depth
Page 19: Qt Widget In-Depth

Window

Widget

Widget

Page 20: Qt Widget In-Depth

Window

Page 21: Qt Widget In-Depth

• Widgets and Window Systems

• Window Systems

• Windows and Widgets

• Updates and Painting

• Events and Loops

Page 22: Qt Widget In-Depth

Paint#include<QtGui>int main(int argc, char *argv[]){ QApplication a(argc,argv); QWidget w; w.show(); return a.exec();}

Update

Window System Painting Code

Page 23: Qt Widget In-Depth

#include<QtGui>int main(int argc, char *argv[]){ QApplication a(argc,argv); QWidget w; w.show(); return a.exec();}

Backing StoreWindow System Painting Code

Page 24: Qt Widget In-Depth

Text

Text

Page 25: Qt Widget In-Depth

Text

Text

Page 26: Qt Widget In-Depth

• Client Side

• Top-Level Window

• Backing Store

• Pixmap

Page 27: Qt Widget In-Depth

• Server Side

• Window

• Pixmap

Page 28: Qt Widget In-Depth

• Client Side

• Window

• Backing Store

• Pixmap

• Server Side

• Window

• Pixmap

Page 29: Qt Widget In-Depth

void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags, QPainter *sharedPainter, QWidgetBackingStore *backingStore){ ... //actually send the paint event QPaintEvent e(toBePainted); QCoreApplication::sendSpontaneousEvent(q, &e); ...}

Page 30: Qt Widget In-Depth

• Widgets and Window Systems

• Window Systems

• Windows and Widgets

• Updates and Painting

• Events and Loops

Page 31: Qt Widget In-Depth

• Spontaneous Events

• Application Events

Page 32: Qt Widget In-Depth

Any

Inputbool W::event(QEvent *e){ if (e->type() == t) foobar(); return false;}

Event

Page 33: Qt Widget In-Depth

Window System

Qt Event Loop

bool W::event(QEvent *e){ if (e->type() ==

Event HandlerSocket Qt Event Dispatcher

Page 34: Qt Widget In-Depth

int QCoreApplication::exec(){ ... QEventLoop eventLoop; self->d_func()->in_exec = true; self->d_func()->aboutToQuitEmitted = false; int returnCode = eventLoop.exec(); ...}

Page 35: Qt Widget In-Depth

int QEventLoop::exec(ProcessEventsFlags flags){ ... try { while (!d->exit) processEvents(flags | WaitForMoreEvents | EventLoopExec); } catch (...) { ... --d->threadData->loopLevel; return d->returnCode;}

Page 36: Qt Widget In-Depth

bool QEventLoop::processEvents(ProcessEventsFlags flags){ Q_D(QEventLoop); if (!d->threadData->eventDispatcher) return false; if (flags & DeferredDeletion) QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); return d->threadData->eventDispatcher->processEvents(flags);}

Page 37: Qt Widget In-Depth

bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags){ ... // we are awake, broadcast it emit awake(); QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); ... nevents = d->doSelect(flags, tm); ...}

Page 38: Qt Widget In-Depth

int QEventDispatcherUNIXPrivate::doSelect( QEventLoop::ProcessEventsFlags flags, timeval *timeout){ ... // Process timers and socket notifiers - the common UNIX stuff ... nsel = q->select(highest + 1, &sn_vec[0].select_fds, &sn_vec[1].select_fds, &sn_vec[2].select_fds, timeout); ...}

Page 39: Qt Widget In-Depth

int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timeval *timeout){ return qt_safe_select(nfds, readfds, writefds, exceptfds, timeout);}

Page 40: Qt Widget In-Depth

int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, const struct timeval *orig_timeout){ ... // loop and recalculate the timeout as needed int ret; forever { ret = ::select(nfds, fdread, fdwrite, fdexcept, &timeout); if (ret != -1 || errno != EINTR) return ret; // recalculate the timeout ... }}

Page 41: Qt Widget In-Depth

• select()

• poll status of file descriptors

• blocks until timeout

Page 42: Qt Widget In-Depth

X11

Qt Event Loop

bool W::event(QEvent *e){ if (e->type() ==

Event HandlerSocket Qt Event DispatcherXLib Queue

Page 43: Qt Widget In-Depth

Qt Event Queue Event Loopbool W::event(QEvent *e){ if (e->type() ==

Event Handler#include<QtGui>int main(int argc, char *argv[]){

postEvent()

Page 44: Qt Widget In-Depth

bool W::event(QEvent *e){ if (e->type() ==

Event Handler#include<QtGui>int main(int argc, char *argv[]){

sendEvent()

Page 45: Qt Widget In-Depth

• Event Propagation

Page 46: Qt Widget In-Depth

C

A

B

D

Page 47: Qt Widget In-Depth

D

C

A B

Page 48: Qt Widget In-Depth

D

C

A B

Page 49: Qt Widget In-Depth

D

C

A B

Page 50: Qt Widget In-Depth

D

C

A B

Page 51: Qt Widget In-Depth

bool QApplication::notify(QObject *receiver, QEvent *e){ ... bool res = false; if (!receiver->isWidgetType()) { res = d->notify_helper(receiver, e); } else switch (e->type()) { ...}

Page 52: Qt Widget In-Depth

• Widgets Propagate Events

Page 53: Qt Widget In-Depth

... case QEvent::StatusTip: case QEvent::WhatsThisClicked: { QWidget *w = static_cast<QWidget *>(receiver); while (w) { res = d->notify_helper(w, e); if ((res && e->isAccepted()) || w->isWindow()) break; w = w->parentWidget(); } } break; ...

Page 54: Qt Widget In-Depth

• Input Events Are Propagated

Page 55: Qt Widget In-Depth

• Input Events are propagated if

• event->isAccepted() == false

• receiver->event(e) == false

Page 56: Qt Widget In-Depth

bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event){ // send to all application event filters if (sendThroughApplicationEventFilters(receiver, event)) return true; // send to all receiver event filters if (sendThroughObjectEventFilters(receiver, event)) return true; // deliver the event return receiver->event(event);}

Page 57: Qt Widget In-Depth

Flags and Attributes

by Dan Queiroz on flickr

Page 58: Qt Widget In-Depth

• Flags and Attributes

• Window Types

• Window Hints

• Widget States

• Widget Attributes

Page 59: Qt Widget In-Depth

• QWidget

• QPaintDevice

• QObject

• QWindowSurface

Page 60: Qt Widget In-Depth

• Flags and Attributes

• Window Types

• Window Hints

• Widget States

• Widget Attributes

Page 61: Qt Widget In-Depth

• Window Types

• Widget

• Window

Page 62: Qt Widget In-Depth

• Dialog

• Sheet (Mac)

• Drawer (Mac)

• Popup

• ToolTip

• SplashScreen

• Desktop

• SubWindow (MDI)

Page 63: Qt Widget In-Depth
Page 64: Qt Widget In-Depth

• Flags and Attributes

• Window Types

• Window Hints

• Widget States

• Widget Attributes

Page 65: Qt Widget In-Depth

• CustomizeWindowHint

• WindowTitleHint

• WindowSystemMenuHint

• WindowMinimizeButtonHint

• WindowMaximizeButtonHint

• WindowMinMaxButtonHint

• WindowCloseButtonHint

• WindowContextHelpButtonHint

• MacWindowToolBarButtonHint

• BypassGraphicsProxyWidget

• WindowShadeButtonHint

• WindowStaysOnTopHint

• WindowStaysOnBottomHint

• WindowOkButtonHint (WinCE)

• WindowCancelButtonHint (WinCE)

Page 66: Qt Widget In-Depth

• Flags and Attributes

• Window Types

• Window Hints

• Widget States

• Widget Attributes

Page 67: Qt Widget In-Depth

• WindowState

• WindowNoState

• WindowMinimized

• WindowMaximized

• WindowFullScreen

• WindowActive

Page 68: Qt Widget In-Depth

• Flags and Attributes

• Window Types

• Window Hints

• Widget States

• Widget Attributes

Page 69: Qt Widget In-Depth

• Qt::Widget Attribute

• 124 Attributes

• setAttribute()

• testAttribute()

Page 70: Qt Widget In-Depth

• Qt::WA_AcceptDrops

• QWidget::setAcceptDrops()

Page 71: Qt Widget In-Depth

Tips and Tricksby robclimbing on flickr

Page 72: Qt Widget In-Depth

• Qt::WA_StaticContents

Page 73: Qt Widget In-Depth

Static Contents

Exposed

Expo

sed

Page 74: Qt Widget In-Depth

• Qt::WA_NoSystemBackground

Page 75: Qt Widget In-Depth

• Qt::WA_OpaquePaintEvent

Page 76: Qt Widget In-Depth

• QWidget::autoFillBackground

• Qt::WA_OpaquePaintEvent

Page 77: Qt Widget In-Depth
Page 78: Qt Widget In-Depth

• QWidget::scroll()

• QWidget::autoFillBackground

• Qt::WA_OpaquePaintEvent

Page 79: Qt Widget In-Depth

Scrolled

Exposed

Concealed

Page 80: Qt Widget In-Depth

• Qt::WA_TranslucentBackground

Page 81: Qt Widget In-Depth

#include <QtGui>

int main(int argc, char *argv[]){ QApplication app(argc, argv); QPixmap skin("transparency.png"); QLabel widget; widget.setPixmap(skin); widget.setWindowFlags(Qt::Window |Qt::CustomizeWindowHint |Qt::FramelessWindowHint); widget.setAttribute(Qt::WA_TranslucentBackground); widget.resize(skin.size()); widget.show(); return app.exec();}

Page 82: Qt Widget In-Depth
Page 83: Qt Widget In-Depth

The Future of Qt Widgetsby jeff_c on flickr

Page 84: Qt Widget In-Depth

• The story of two APIs ...

Page 85: Qt Widget In-Depth

• QWidget

• Widget Hierarchy

• QGraphicsItem

• Scene Graph

Page 86: Qt Widget In-Depth

• QWidget

• Alien Widgets

• Graphics Effects

• Disable Clipping ?

• Disable Move Events ?

• Transformations ?

Page 87: Qt Widget In-Depth

• Is it possible ?

Page 88: Qt Widget In-Depth

• Is it possible in Qt 4.x ?

Page 89: Qt Widget In-Depth

Thank you!

Questions?

Page 90: Qt Widget In-Depth

Bonus Material

Page 91: Qt Widget In-Depth

Qt Developer DaysWindow System

Page 92: Qt Widget In-Depth

Scene Graph IPCWindow Surface

Page 93: Qt Widget In-Depth

QGraphicsScene QTcpSocketQSharedMemory

Page 94: Qt Widget In-Depth

• Server

• Window

Page 95: Qt Widget In-Depth

• Server

• Connections

• Scene Graph

Page 96: Qt Widget In-Depth

• Window

• Surface

• Geometry

• Id

Page 97: Qt Widget In-Depth

Server

#include<QtGui>int main(int argc, char *argv[]){ QApplication a(argc,argv); QWidget w; w.show(); return a.exec();}

Client

Page 98: Qt Widget In-Depth

Server

#include<QtGui>int main(int argc, char *argv[]){ QApplication a(argc,argv); QWidget w; w.show(); return a.exec();}

Client

?

Protocol

Page 99: Qt Widget In-Depth

• Message

• Request

• Reply

• Event

Page 100: Qt Widget In-Depth

#include<QtGui>int main(int argc, char *argv[]){ QApplication a(argc,argv); QWidget w; w.show(); return a.exec();}

Request

#include<QtGui>int main(int argc, char *argv[]){ QApplication a(argc,argv); QWidget w; w.show(); return a.exec();}

Response

Page 101: Qt Widget In-Depth

bool W::event(QEvent *e){ if (e->type() == t) foobar(); return false;}

Event

Page 102: Qt Widget In-Depth

Lighthouse

Page 103: Qt Widget In-Depth

• Research!

• Qt Graphicssystem Interface

• Makes Qt ports easy

Page 104: Qt Widget In-Depth

• QGraphicsSystem

• QGraphicsSystemScreen

• QWindowSurface

Page 105: Qt Widget In-Depth

• QGraphicsSystem

• Window Surfaces

• Server Communication

Page 106: Qt Widget In-Depth

• QGraphicsSystemScreen

• Screen Information

• Depth

• Resolution

• Size

Page 107: Qt Widget In-Depth

• QWindowSurface

• Surface

• Geometry

• Id

Page 108: Qt Widget In-Depth

Demo

Page 109: Qt Widget In-Depth

• git://gitorious.org/+qt-developers/qt/lighthouse.git

Source Code