Qt Widget In-Depth

Post on 12-May-2015

11496 Views

Category:

Technology

4 Downloads

Preview:

Click to see full reader

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

Transcript

Qt Widgets In-DepthQWidget Under The Surface

About Me

• Marius Bugge Monsen

• Qt Developer

• Qt Widgets Team Lead

• Widgets and Window Systems

• Flags and Attributes

• The Future of Qt Widgets

Widgets and Window Systemsby extranoise on flickr

• Widgets and Window Systems

• Window Systems

• Windows and Widgets

• Updates and Painting

• Events and Loops

• Widgets and Window Systems

• Window Systems

• Windows and Widgets

• Updates and Painting

• Events and Loops

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

• X11

• Desktop Window Manager (MS Windows)

• Quartz Compositor (Mac OS X)

• QWS

• S60 Window Manager

Window Surface

Surface

Surface

Screen

Window System

Window System

Window System Qt Application

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

IPC

• Widgets and Window Systems

• Window Systems

• Windows and Widgets

• Updates and Painting

• Events and Loops

Surface

Surface

Surface

Surface

Surface Surface

Window

Widget

Widget

Window

• Widgets and Window Systems

• Window Systems

• Windows and Widgets

• Updates and Painting

• Events and Loops

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

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

Backing StoreWindow System Painting Code

Text

Text

Text

Text

• Client Side

• Top-Level Window

• Backing Store

• Pixmap

• Server Side

• Window

• Pixmap

• Client Side

• Window

• Backing Store

• Pixmap

• Server Side

• Window

• Pixmap

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); ...}

• Widgets and Window Systems

• Window Systems

• Windows and Widgets

• Updates and Painting

• Events and Loops

• Spontaneous Events

• Application Events

Any

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

Event

Window System

Qt Event Loop

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

Event HandlerSocket Qt Event Dispatcher

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

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

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);}

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

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); ...}

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);}

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 ... }}

• select()

• poll status of file descriptors

• blocks until timeout

X11

Qt Event Loop

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

Event HandlerSocket Qt Event DispatcherXLib Queue

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

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

postEvent()

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

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

sendEvent()

• Event Propagation

C

A

B

D

D

C

A B

D

C

A B

D

C

A B

D

C

A B

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

• Widgets Propagate Events

... 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; ...

• Input Events Are Propagated

• Input Events are propagated if

• event->isAccepted() == false

• receiver->event(e) == false

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);}

Flags and Attributes

by Dan Queiroz on flickr

• Flags and Attributes

• Window Types

• Window Hints

• Widget States

• Widget Attributes

• QWidget

• QPaintDevice

• QObject

• QWindowSurface

• Flags and Attributes

• Window Types

• Window Hints

• Widget States

• Widget Attributes

• Window Types

• Widget

• Window

• Dialog

• Sheet (Mac)

• Drawer (Mac)

• Popup

• ToolTip

• SplashScreen

• Desktop

• SubWindow (MDI)

• Flags and Attributes

• Window Types

• Window Hints

• Widget States

• Widget Attributes

• CustomizeWindowHint

• WindowTitleHint

• WindowSystemMenuHint

• WindowMinimizeButtonHint

• WindowMaximizeButtonHint

• WindowMinMaxButtonHint

• WindowCloseButtonHint

• WindowContextHelpButtonHint

• MacWindowToolBarButtonHint

• BypassGraphicsProxyWidget

• WindowShadeButtonHint

• WindowStaysOnTopHint

• WindowStaysOnBottomHint

• WindowOkButtonHint (WinCE)

• WindowCancelButtonHint (WinCE)

• Flags and Attributes

• Window Types

• Window Hints

• Widget States

• Widget Attributes

• WindowState

• WindowNoState

• WindowMinimized

• WindowMaximized

• WindowFullScreen

• WindowActive

• Flags and Attributes

• Window Types

• Window Hints

• Widget States

• Widget Attributes

• Qt::Widget Attribute

• 124 Attributes

• setAttribute()

• testAttribute()

• Qt::WA_AcceptDrops

• QWidget::setAcceptDrops()

Tips and Tricksby robclimbing on flickr

• Qt::WA_StaticContents

Static Contents

Exposed

Expo

sed

• Qt::WA_NoSystemBackground

• Qt::WA_OpaquePaintEvent

• QWidget::autoFillBackground

• Qt::WA_OpaquePaintEvent

• QWidget::scroll()

• QWidget::autoFillBackground

• Qt::WA_OpaquePaintEvent

Scrolled

Exposed

Concealed

• Qt::WA_TranslucentBackground

#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();}

The Future of Qt Widgetsby jeff_c on flickr

• The story of two APIs ...

• QWidget

• Widget Hierarchy

• QGraphicsItem

• Scene Graph

• QWidget

• Alien Widgets

• Graphics Effects

• Disable Clipping ?

• Disable Move Events ?

• Transformations ?

• Is it possible ?

• Is it possible in Qt 4.x ?

Thank you!

Questions?

Bonus Material

Qt Developer DaysWindow System

Scene Graph IPCWindow Surface

QGraphicsScene QTcpSocketQSharedMemory

• Server

• Window

• Server

• Connections

• Scene Graph

• Window

• Surface

• Geometry

• Id

Server

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

Client

Server

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

Client

?

Protocol

• Message

• Request

• Reply

• Event

#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

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

Event

Lighthouse

• Research!

• Qt Graphicssystem Interface

• Makes Qt ports easy

• QGraphicsSystem

• QGraphicsSystemScreen

• QWindowSurface

• QGraphicsSystem

• Window Surfaces

• Server Communication

• QGraphicsSystemScreen

• Screen Information

• Depth

• Resolution

• Size

• QWindowSurface

• Surface

• Geometry

• Id

Demo

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

Source Code

top related