Qt Widgets In-Depth
    QWidget 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
by extranoise on flickr




Widgets and Window Systems
• 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
QWS       SunView
MiniGUI                             Metisse
     Rio    Microwindows
DM                          Fresco/Berlin
     8 1/2 GEM                        ManaGeR
HP Windows                  OOHG
               Xynth
                        MicroXwin       Intuition
Y             FBUI
     NeWS
                     NeXT DPS           Quartz
Wayland      Twin
                     OPIE           X
• 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


                IPC     #include<QtGui>
                        int main(int argc, char *argv[])
                        {
                          QApplication a(argc,argv);
                          QWidget w;
                          w.show();
                          return a.exec();
                        }
• Widgets and Window Systems
 • Window Systems
 • Windows and Widgets
 • Updates and Painting
 • Events and Loops
Surface


          Surface


Surface
Surface


Surface             Surface
Widget


         Window


Widget
Window
• Widgets and Window Systems
 • Window Systems
 • Windows and Widgets
 • Updates and Painting
 • Events and Loops
Window System   Paint    Painting Code
                            #include<QtGui>
                            int main(int argc, char
                            *argv[])
                            {
                              QApplication a
                            (argc,argv);
                              QWidget w;
                              w.show();
                              return a.exec();
                            }




                Update
Window System   Backing Store   Painting Code
                                   #include<QtGui>
                                   int main(int argc, char
                                   *argv[])
                                   {
                                     QApplication a
                                   (argc,argv);
                                     QWidget w;
                                     w.show();
                                     return a.exec();
                                   }
Text


Text
Text


Text
• Client Side
 • Top-Level Window
   • Backing Store
   • Pixmap
• Server Side
 • Window
 • Pixmap
• Client Side        • Server Side
 • Window             • Window
   • Backing Store    • Pixmap
   • 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
Input   Event   bool W::event(QEvent *e)
                      {

Any                     if (e->type() == t)
                            foobar();
                        return false;
                      }
Window System      Socket       Qt Event Dispatcher Event Handler
                                                        bool
                                                        W::event
                                                        (QEvent *e)
                                                        {
                                                          if (e-
                                                        >type() ==




                Qt Event Loop
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      Socket       XLib Queue   Qt Event Dispatcher Event Handler
                                                           bool
                                                           W::event
                                                           (QEvent *e)
                                                           {
                                                             if (e-
                                                           >type() ==




      Qt Event Loop
postEvent()       Qt Event Queue   Event Loop   Event Handler
   #include<Q                                       bool
   tGui>                                            W::event
   int main(int                                     (QEvent *e)
   argc, char                                       {
   *argv[])                                           if (e-
   {                                                >type() ==
sendEvent()       Event Handler
   #include<Q         bool
   tGui>              W::event
   int main(int       (QEvent *e)
   argc, char         {
   *argv[])             if (e-
   {                  >type() ==
• Event Propagation
D

A

    C
        B
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);
}
by Dan Queiroz on flickr




Flags and Attributes
• 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           •   MacWindowToolBarButtonHint

•   WindowTitleHint               •   BypassGraphicsProxyWidget

•   WindowSystemMenuHint          •   WindowShadeButtonHint

•   WindowMinimizeButtonHint      •   WindowStaysOnTopHint

•   WindowMaximizeButtonHint      •   WindowStaysOnBottomHint

•   WindowMinMaxButtonHint        •   WindowOkButtonHint (WinCE)

•   WindowCloseButtonHint         •   WindowCancelButtonHint (WinCE)

•   WindowContextHelpButtonHint
• 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()
by robclimbing on flickr




Tips and Tricks
• Qt::WA_StaticContents
Exposed
Static Contents




    Exposed
• Qt::WA_NoSystemBackground
• Qt::WA_OpaquePaintEvent
• QWidget::autoFillBackground
• Qt::WA_OpaquePaintEvent
• QWidget::scroll()
 • QWidget::autoFillBackground
 • Qt::WA_OpaquePaintEvent
Concealed




Scrolled




Exposed
• 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();
}
by jeff_c on flickr




The Future of Qt Widgets
• 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 Days
 Window System
Window Surface   Scene Graph   IPC
QSharedMemory QGraphicsScene   QTcpSocket
• Server
• Window
• Server
 • Connections
 • Scene Graph
• Window
 • Surface
 • Geometry
 • Id
Server       Client

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




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




Response   #include<QtGui>
           int main(int argc, char
           *argv[])
           {
             QApplication a
           (argc,argv);
             QWidget w;
             w.show();
             return a.exec();
           }
Event   bool W::event(QEvent *e)
        {
          if (e->type() == t)
              foobar();
          return false;
        }
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
Source Code


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

Qt Widget In-Depth