Upload
qt-project
View
11.507
Download
4
Tags:
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
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