KEMBAR78
05 - Qt External Interaction and Graphics | PDF
Qt – External Interaction and Graphics



Andreas Jakl
Senior Technical Consultant
Forum Nokia

                                     20 September, 2010
                                                 v3.0.0
Contents
  – Events
  – Low Level Painting
  – Graphics View Framework
  – Optimizing Images
Events
Events
• UI applications are event-based
    – Wait for user to interact
    – Then start working on the requested task
• Alternative
    – Polling for status changes
      “Is the user pressing a button?”
→ Events save processing time, thus battery life

                                                   Picture credits: Pearson Scott Foresman
                                                                             Public domain
Events vs. Signals?
•   Signals
     – For using widgets
     – e.g., push button should
       return clicked() signal, not
       low-level mouse or key events
•   Events
     – For implementing widgets
             •   Modifying existing widgets
             •   New widgets
     – e.g., implement own push button: handle mouse and key events and emit clicked()
       signal when necessary
Events and Signals
• Mouse button’s way to become a clicked() signal
                               QCoreApplication::exec()
    Mouse button   Operating
                                 QEventLoop::exec()
      released      system

                                               QEvent sent through event dispatcher
                                QPushButton::event()
                                                                           QAbstractButton::
                               QAbstractButton::event()
                                                                         mouseReleasedEvent()
                                  QWidget::event()
                                                                         → emit clicked() signal
                                  QObject::event()
                                                                      Signal & slots connection

                                                                    Custom slot that handles button
                                                                                  click
Event Loop
• Threads in Qt can have an event loop
   – Initial thread starts its loop through QCoreApplication::exec()
   – Other threads: QThread::exec()
• Events
   – Derived from QEvent
   – Source:
       •   Window system (QMouseEvent, QKeyEvent)
       •   Generated by Qt itself (QTimerEvent)

   – Handled by QObject subclass (especially widgets)
QEvent
• Get type of event through QEvent::type()
    – 100+ events defined through enum values in Qt
    – Own events can be defined
• Event is an instance of a QEvent subclass
    – Adds additional information about event
    – e.g., QMouseEvent: buttons, position, ...
Handling Events in Widgets
       – Events delivered to event() function of QObject
       – Calls appropriate virtual event handler functions
qwidget.cpp
 bool QWidget::event(QEvent *event)
 {
     Q_D(QWidget);
     // ...
     switch (event->type()) {
     case QEvent::MouseMove:
         mouseMoveEvent((QMouseEvent*)event);
         break;                                 You only need to
     case QEvent::Paint:
         paintEvent((QPaintEvent*)event);       override virtual, pre-
                                                defined handler method
         break;
     case QEvent::Close:
         closeEvent((QCloseEvent*)event);
         break;                                 from QWidget base class
         // ...
     default:
         return QObject::event(event);
     }
     return true;
 }
Example: Ticker
• Scrolling text
    – 1 Pixel / 30 ms
    – Demonstrates Timer events
• Handles 4 events
    – Paint event: manual drawing of the text
    – Timer event: regular call-backs
    – Show event: start timer when widget is shown
    – Hide event: end timer when widget becomes invisible
Ticker – General Definition
ticker.h                                                ticker.cpp
 #ifndef TICKER_H                                        #include "ticker.h"
 #define TICKER_H
                                                         Ticker::Ticker(QWidget* parent)
 #include <QtGui>                                                : QWidget(parent)
                                                         {
 class Ticker : public QWidget                               m_offset = 0;
 {                                                           m_timerId = 0;
     Q_OBJECT                                            }
     Q_PROPERTY(QString text READ text WRITE setText)
                                                         void Ticker::setText(const QString &newText)
 public:                                                 {
     Ticker(QWidget* parent = 0);                            m_text = newText;
     void setText(const QString &newText);                   update();
     QString text() const { return m_text; }                 updateGeometry();
     QSize sizeHint() const;                             }

 protected:                                              // Return recommended size of this widget
     void paintEvent(QPaintEvent* event);                QSize Ticker::sizeHint() const
     void timerEvent(QTimerEvent* event);                {
     void showEvent(QShowEvent* event);                      // Determine size required by the text
     void hideEvent(QHideEvent* event);                      // First argument isn't needed here -> 0
                                                             return fontMetrics().size(0, text());
 private:                                                }
     QString m_text;
     int m_offset;
     int m_timerId;
 };

 #endif // TICKER_H
Ticker – Event Handling
ticker.cpp                                                 ticker.cpp
 void Ticker::paintEvent(QPaintEvent* /*event*/)            void Ticker::timerEvent(QTimerEvent* event)
 {                                                          {
     QPainter painter(this);                                    // Called by the system at intervals
                                                                if (event->timerId() == m_timerId)
       // Get required width of the text                        {
       int textWidth = fontMetrics().width(text());                 // Increase offset by 1 to simulate movement
       if (textWidth < 1)                                           ++m_offset;
           return;                                                  if (m_offset >= fontMetrics().width(text()))
                                                                         m_offset = 0;
       // Draw the text as many times as necessary                  // Call to QWidget::scroll(), moves existing
       // to fill the entire width of the widget                    // pixels on-screen and only paints new area.
       // (taking offset into account)                              // Also possible: call update() to redraw
       int x = -m_offset;                                           // the whole widget.
       while (x < width())                                          scroll(-1, 0);
       {                                                        } else {
           painter.drawText(x, 0, textWidth, height(),              // Event not from the timer we are
              Qt::AlignLeft | Qt::AlignVCenter, text());            // interested in -> pass to base class
           x += textWidth;                                          QWidget::timerEvent(event);
       }                                                        }
 }                                                          }

 void Ticker::showEvent(QShowEvent* /*event*/)              void Ticker::hideEvent(QHideEvent* /*event*/)
 {                                                          {
     // Starts a timer. Returned ID number can be               // Stop the timer
     // used to identify timer later                            killTimer(m_timerId);
     m_timerId = startTimer(30);                                m_timerId = 0;
 }                                                          }
Event Filters
• Look at / intercept events delivered to other object
    – e.g., dialogs filter key presses for widgets to modify Return-key handling

    – Set up through QObject::installEventFilter()
    – Target object gets events before monitored object
    – Accepts or rejects events: allow / deny further event processing

          monitoredObj->installEventFilter(targetObj);
Ways to Influence Event Handling I
1.   Incoming event first goes to virtual function QCoreApplication::notify()
     –    Override notify()
     –   Get all events before any event filters can intercept
     –   Only one subclass of QCoreApplication can be active at a time
2.   Install an event filter on QCoreApplication::instance()
     –    implement eventFilter()
     –   Get events after sent out by notify()
     –   As powerful as option 1, also allows multiple application-global event
         filters
Ways to Influence Event Handling II
3.    Event filter on target object
     –  implement eventFilter()
     – Gets all events (except Tab, Shift+Tab) before actual target object
4.    Event handler of target object
     –  override QObject::event()
     – Gets events after event filter
     – Don’t forget to call event handler of base class for unhandled events!
5.    Re-implement event handling functions
     –  implement paintEvent(), mousePressEvent()
     – Easiest, most common, but least powerful
Low Level Painting
Painting
• Low-level drawing handled through QPainter
• Draws on paint devices (QPaintDevice):
    – QWidget: most common use case
    – QImage: optimized for I/O and direct pixel manipulation
    – QPixmap: optimized for showing images on screen
            •   QBitmap: convenience for monochrome QPixmap –
                e.g., QCursor, QBrush, QRegion
    – QPicture: records and replays QPainter commands
    – QPrinter: paint on a printer
    – ...
QPainter
•   Can draw:
     – Geometric shapes with pen/brush
     – Fonts
     – Bezier curves
     – Images
•   Features:
     – Anti-aliasing
     – Alpha blending
     – Gradient filling
     – Vector paths
     – Linear transformations
Example: Drawing
  – Draws line between coordinates of two mouse clicks
  – Uses image to store drawing
  – Text written directly on Widget surface
Drawing
mainWidget.cpp
 MainWidget::MainWidget() {
    // Use standard colors of system
    setBackgroundRole(QPalette::Base);
    lastX = -1;
    lastY = -1;
    resize( 300, 200 );
    bgImg = new QPixmap(300, 200);
    bgImg->fill(QColor(255, 255, 255));
 }

 void MainWidget::mousePressEvent(QMouseEvent* event) {
     if (event->button() == Qt::LeftButton && lastX > -1 && lastY > -1) {
         // Create painter object for our image
         QPainter painter(bgImg);
         // Draw a line from previous pos to new position                   mainWidget.h
         painter.setPen(QPen(Qt::red, 3));
         painter.drawLine(lastX, lastY, event->x(), event->y());             class MainWidget : public QWidget {
         update();                                                           Q_OBJECT
     }                                                                       public:
     lastX = event->x();                                                        MainWidget();
     lastY = event->y();
 }
                                                                             protected:
                                                                                void mousePressEvent(QMouseEvent* event);
 void MainWidget::paintEvent(QPaintEvent* event) {                              void paintEvent(QPaintEvent* event);
     // Paint directly on the widget surface                                 private:
     QPainter painter(this);                                                    int lastX;
     // Draw the image to the widget                                            int lastY;
     painter.drawPixmap(0, 0, *bgImg);                                          QPixmap* bgImg;
     // Draw text on top of the image to the widget                          };
     painter.setPen(QPen(Qt::blue, 1));
     painter.drawText(5, 15, tr("Draw using left mouse button clicks"));
     painter.drawText(5, 30, tr("Set position with right mouse button"));
 }
The Graphics View
Framework
GraphicsView
Architecture
                             Scene


                    Item 1
                                              Item 6


           Item 2
                             Item 3
                                                 Item 7


                Item 4               Item 5
Graphics View Framework – Example
• Setting up a simple scene




 scene = new QGraphicsScene(0, 0, 400, 400);
 QGraphicsLineItem *wall = new QGraphicsLineItem
     (QLineF(0.0, 200.0, 100.0, 200.0));
 scene->addItem(wall);
 view = new QGraphicsView(scene);
 view->setRenderHint(QPainter::Antialiasing);
Items
•   QGraphicsItem subclasses
     – Pre-defined shapes (line, rectangle, polygon, path, etc.)
     – Text
     – Images
     – Widgets
     – Custom items
•   Supports
     – Painting
     – Transformations
     – Collision Detection
     – Interaction through event handlers
Using Widgets as Items?
• Possible through two ways:
   – QGraphicsWidget
       •   New subclass for widgets in QGraphicsScenes
       •   Resembles QWidget, only few limitations

   – QGraphicsProxyWidget
       •   Embeds a standard QWidget into QGraphicsScene
       •   Translates coordinate systems
       •   Automatically manages child widgets
       •   Not suitable for high performance scenarios
Proxy Widget – Example
    #include <QtGui>

     int main(int argc, char **argv)
     {
         QApplication app(argc, argv);

         QPushButton *testButton = new QPushButton("Hello World");

         QGraphicsScene scene;
         QGraphicsProxyWidget *proxy = scene.addWidget(testButton);
         proxy->rotate(-20.0);

         QGraphicsView view(&scene);
         view.show();

         return app.exec();
     }
Scene: QGraphicsScene
• Surface for managing items on a 2D surface
   – 3 layers: background, item layer, foreground
   – Scene can be parent of items, or items are children of other items
   – Manages items: position & transformation, visibility, collision, locate
      items
   – Propagates events to items
   – Indexes items with BSP tree by default
       •   Suitable for large scenes with relatively static items
View: QGraphicsView
• Widget that presents a scene
   – Multiple views for a single scene
      possible
   – Supports transformations
      (zooming, rotation, etc.)
   – Provides scroll bars if necessary
                                         Image Credit: Ricardo J. Reyes
                                                        Public Domain
   – By default uses 2D paint engine,
      possible to use OpenGL
Coordinate Systems
• Item Coordinates
   – Each item has its own coordinate system
   – Usually centered around its center point (0,0)
   – Relative to parent’s coordinates
• Scene Coordinates
   – Base coordinate system for all items
   – Describes position for all top-level items
• View Coordinates
   – Coordinates relative to the widget
Coordinate Mappings / Transformations
• Coordinate mappings with utility functions
   – mapToScene() / mapFromScene()
   – Available in view / scene / item classes
• Affine Transformations
   – Extra methods (rotate(), etc.)
   – QMatrix
QTransform transform;
transform.rotate(newPos.x() / 6.0, Qt::YAxis);
transform.rotate(newPos.y() / 6.0, Qt::XAxis);
baseItem->setTransform(transform);
Animation Framework
• Part of Qt Kinetic project (→ Qt 4.6)
    – Animate Qt properties of widgets and
      QObjects
    – Can be used on its own or with state
      machine
    – Supports easing curves, animation
      groups
Optimizing SVG
• Free tools
    – http://code.google.com/p/svgmin/
    – http://codedread.com/scour/

                            SVG Loading Time

 Optimized

   Original

              0   20   40    60     80   100   120   140   160   180
Pixel Images
• Most common pixel-based formats:
   – .png (Portable Network Graphics)
       •   Similar to .gif (which was patented until 2003 because of
           its LZW compression)
       •   Compression: works well for graphics, not so well for
           photos
       •   Transparency: support depends on device – 1 bit             increasing JPEG compression
           transparency or full alpha-channel.

   – .jpg (Joint Photographic Experts Group)
       •   Compression: for photos (wavelength), not for graphics
       •   Transparency: not supported                                        Image Credit: Ilmari_Karonen / Brianski
                                                                                                   Creative Commons
Save PNGs – File Size Reduction
   1.    Optimized export – Photoshop: Save for Web
   2.    Further optimization – Pngcrush: http://pmt.sourceforge.net/pngcrush/

                                                                Use as few colors as
                                                                   possible (fine
      No dithering                                              gradients compress
   (compression gets                                                  worse)
     more difficult)


   Transparenter Kanal
      You can set a
      transparency
      kann gesetzt
         channel
         werden
PNG Optimization – Example: 472 x 472 px




                  256 colours, no dither      64 colours, no dither                    8 colours, no dither
                         30,0 kB                     16,3 kB                                  6,3 kB

   Results:
   - Not much difference between 256
   and 64 colours (especially on a device
   display), but only half of the file size
   - Limits of optimization: 8 colours not
   enough
   - Dithering at 8 colours: same file size
   as visually better 64 colours image
                                                                8 colours, Diffusion dither
   → often, dithering is problematic!                                    15,9 kB
Thank You.

05 - Qt External Interaction and Graphics

  • 1.
    Qt – ExternalInteraction and Graphics Andreas Jakl Senior Technical Consultant Forum Nokia 20 September, 2010 v3.0.0
  • 2.
    Contents –Events – Low Level Painting – Graphics View Framework – Optimizing Images
  • 3.
  • 4.
    Events • UI applicationsare event-based – Wait for user to interact – Then start working on the requested task • Alternative – Polling for status changes “Is the user pressing a button?” → Events save processing time, thus battery life Picture credits: Pearson Scott Foresman Public domain
  • 5.
    Events vs. Signals? • Signals – For using widgets – e.g., push button should return clicked() signal, not low-level mouse or key events • Events – For implementing widgets • Modifying existing widgets • New widgets – e.g., implement own push button: handle mouse and key events and emit clicked() signal when necessary
  • 6.
    Events and Signals •Mouse button’s way to become a clicked() signal QCoreApplication::exec() Mouse button Operating QEventLoop::exec() released system QEvent sent through event dispatcher QPushButton::event() QAbstractButton:: QAbstractButton::event() mouseReleasedEvent() QWidget::event() → emit clicked() signal QObject::event() Signal & slots connection Custom slot that handles button click
  • 7.
    Event Loop • Threadsin Qt can have an event loop – Initial thread starts its loop through QCoreApplication::exec() – Other threads: QThread::exec() • Events – Derived from QEvent – Source: • Window system (QMouseEvent, QKeyEvent) • Generated by Qt itself (QTimerEvent) – Handled by QObject subclass (especially widgets)
  • 8.
    QEvent • Get typeof event through QEvent::type() – 100+ events defined through enum values in Qt – Own events can be defined • Event is an instance of a QEvent subclass – Adds additional information about event – e.g., QMouseEvent: buttons, position, ...
  • 9.
    Handling Events inWidgets – Events delivered to event() function of QObject – Calls appropriate virtual event handler functions qwidget.cpp bool QWidget::event(QEvent *event) { Q_D(QWidget); // ... switch (event->type()) { case QEvent::MouseMove: mouseMoveEvent((QMouseEvent*)event); break; You only need to case QEvent::Paint: paintEvent((QPaintEvent*)event); override virtual, pre- defined handler method break; case QEvent::Close: closeEvent((QCloseEvent*)event); break; from QWidget base class // ... default: return QObject::event(event); } return true; }
  • 10.
    Example: Ticker • Scrollingtext – 1 Pixel / 30 ms – Demonstrates Timer events • Handles 4 events – Paint event: manual drawing of the text – Timer event: regular call-backs – Show event: start timer when widget is shown – Hide event: end timer when widget becomes invisible
  • 11.
    Ticker – GeneralDefinition ticker.h ticker.cpp #ifndef TICKER_H #include "ticker.h" #define TICKER_H Ticker::Ticker(QWidget* parent) #include <QtGui> : QWidget(parent) { class Ticker : public QWidget m_offset = 0; { m_timerId = 0; Q_OBJECT } Q_PROPERTY(QString text READ text WRITE setText) void Ticker::setText(const QString &newText) public: { Ticker(QWidget* parent = 0); m_text = newText; void setText(const QString &newText); update(); QString text() const { return m_text; } updateGeometry(); QSize sizeHint() const; } protected: // Return recommended size of this widget void paintEvent(QPaintEvent* event); QSize Ticker::sizeHint() const void timerEvent(QTimerEvent* event); { void showEvent(QShowEvent* event); // Determine size required by the text void hideEvent(QHideEvent* event); // First argument isn't needed here -> 0 return fontMetrics().size(0, text()); private: } QString m_text; int m_offset; int m_timerId; }; #endif // TICKER_H
  • 12.
    Ticker – EventHandling ticker.cpp ticker.cpp void Ticker::paintEvent(QPaintEvent* /*event*/) void Ticker::timerEvent(QTimerEvent* event) { { QPainter painter(this); // Called by the system at intervals if (event->timerId() == m_timerId) // Get required width of the text { int textWidth = fontMetrics().width(text()); // Increase offset by 1 to simulate movement if (textWidth < 1) ++m_offset; return; if (m_offset >= fontMetrics().width(text())) m_offset = 0; // Draw the text as many times as necessary // Call to QWidget::scroll(), moves existing // to fill the entire width of the widget // pixels on-screen and only paints new area. // (taking offset into account) // Also possible: call update() to redraw int x = -m_offset; // the whole widget. while (x < width()) scroll(-1, 0); { } else { painter.drawText(x, 0, textWidth, height(), // Event not from the timer we are Qt::AlignLeft | Qt::AlignVCenter, text()); // interested in -> pass to base class x += textWidth; QWidget::timerEvent(event); } } } } void Ticker::showEvent(QShowEvent* /*event*/) void Ticker::hideEvent(QHideEvent* /*event*/) { { // Starts a timer. Returned ID number can be // Stop the timer // used to identify timer later killTimer(m_timerId); m_timerId = startTimer(30); m_timerId = 0; } }
  • 13.
    Event Filters • Lookat / intercept events delivered to other object – e.g., dialogs filter key presses for widgets to modify Return-key handling – Set up through QObject::installEventFilter() – Target object gets events before monitored object – Accepts or rejects events: allow / deny further event processing monitoredObj->installEventFilter(targetObj);
  • 14.
    Ways to InfluenceEvent Handling I 1. Incoming event first goes to virtual function QCoreApplication::notify() –  Override notify() – Get all events before any event filters can intercept – Only one subclass of QCoreApplication can be active at a time 2. Install an event filter on QCoreApplication::instance() –  implement eventFilter() – Get events after sent out by notify() – As powerful as option 1, also allows multiple application-global event filters
  • 15.
    Ways to InfluenceEvent Handling II 3. Event filter on target object –  implement eventFilter() – Gets all events (except Tab, Shift+Tab) before actual target object 4. Event handler of target object –  override QObject::event() – Gets events after event filter – Don’t forget to call event handler of base class for unhandled events! 5. Re-implement event handling functions –  implement paintEvent(), mousePressEvent() – Easiest, most common, but least powerful
  • 16.
  • 17.
    Painting • Low-level drawinghandled through QPainter • Draws on paint devices (QPaintDevice): – QWidget: most common use case – QImage: optimized for I/O and direct pixel manipulation – QPixmap: optimized for showing images on screen • QBitmap: convenience for monochrome QPixmap – e.g., QCursor, QBrush, QRegion – QPicture: records and replays QPainter commands – QPrinter: paint on a printer – ...
  • 18.
    QPainter • Can draw: – Geometric shapes with pen/brush – Fonts – Bezier curves – Images • Features: – Anti-aliasing – Alpha blending – Gradient filling – Vector paths – Linear transformations
  • 19.
    Example: Drawing – Draws line between coordinates of two mouse clicks – Uses image to store drawing – Text written directly on Widget surface
  • 20.
    Drawing mainWidget.cpp MainWidget::MainWidget() { // Use standard colors of system setBackgroundRole(QPalette::Base); lastX = -1; lastY = -1; resize( 300, 200 ); bgImg = new QPixmap(300, 200); bgImg->fill(QColor(255, 255, 255)); } void MainWidget::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton && lastX > -1 && lastY > -1) { // Create painter object for our image QPainter painter(bgImg); // Draw a line from previous pos to new position mainWidget.h painter.setPen(QPen(Qt::red, 3)); painter.drawLine(lastX, lastY, event->x(), event->y()); class MainWidget : public QWidget { update(); Q_OBJECT } public: lastX = event->x(); MainWidget(); lastY = event->y(); } protected: void mousePressEvent(QMouseEvent* event); void MainWidget::paintEvent(QPaintEvent* event) { void paintEvent(QPaintEvent* event); // Paint directly on the widget surface private: QPainter painter(this); int lastX; // Draw the image to the widget int lastY; painter.drawPixmap(0, 0, *bgImg); QPixmap* bgImg; // Draw text on top of the image to the widget }; painter.setPen(QPen(Qt::blue, 1)); painter.drawText(5, 15, tr("Draw using left mouse button clicks")); painter.drawText(5, 30, tr("Set position with right mouse button")); }
  • 21.
  • 22.
  • 23.
    Architecture Scene Item 1 Item 6 Item 2 Item 3 Item 7 Item 4 Item 5
  • 24.
    Graphics View Framework– Example • Setting up a simple scene scene = new QGraphicsScene(0, 0, 400, 400); QGraphicsLineItem *wall = new QGraphicsLineItem (QLineF(0.0, 200.0, 100.0, 200.0)); scene->addItem(wall); view = new QGraphicsView(scene); view->setRenderHint(QPainter::Antialiasing);
  • 25.
    Items • QGraphicsItem subclasses – Pre-defined shapes (line, rectangle, polygon, path, etc.) – Text – Images – Widgets – Custom items • Supports – Painting – Transformations – Collision Detection – Interaction through event handlers
  • 26.
    Using Widgets asItems? • Possible through two ways: – QGraphicsWidget • New subclass for widgets in QGraphicsScenes • Resembles QWidget, only few limitations – QGraphicsProxyWidget • Embeds a standard QWidget into QGraphicsScene • Translates coordinate systems • Automatically manages child widgets • Not suitable for high performance scenarios
  • 27.
    Proxy Widget –Example #include <QtGui> int main(int argc, char **argv) { QApplication app(argc, argv); QPushButton *testButton = new QPushButton("Hello World"); QGraphicsScene scene; QGraphicsProxyWidget *proxy = scene.addWidget(testButton); proxy->rotate(-20.0); QGraphicsView view(&scene); view.show(); return app.exec(); }
  • 28.
    Scene: QGraphicsScene • Surfacefor managing items on a 2D surface – 3 layers: background, item layer, foreground – Scene can be parent of items, or items are children of other items – Manages items: position & transformation, visibility, collision, locate items – Propagates events to items – Indexes items with BSP tree by default • Suitable for large scenes with relatively static items
  • 29.
    View: QGraphicsView • Widgetthat presents a scene – Multiple views for a single scene possible – Supports transformations (zooming, rotation, etc.) – Provides scroll bars if necessary Image Credit: Ricardo J. Reyes Public Domain – By default uses 2D paint engine, possible to use OpenGL
  • 30.
    Coordinate Systems • ItemCoordinates – Each item has its own coordinate system – Usually centered around its center point (0,0) – Relative to parent’s coordinates • Scene Coordinates – Base coordinate system for all items – Describes position for all top-level items • View Coordinates – Coordinates relative to the widget
  • 31.
    Coordinate Mappings /Transformations • Coordinate mappings with utility functions – mapToScene() / mapFromScene() – Available in view / scene / item classes • Affine Transformations – Extra methods (rotate(), etc.) – QMatrix QTransform transform; transform.rotate(newPos.x() / 6.0, Qt::YAxis); transform.rotate(newPos.y() / 6.0, Qt::XAxis); baseItem->setTransform(transform);
  • 32.
    Animation Framework • Partof Qt Kinetic project (→ Qt 4.6) – Animate Qt properties of widgets and QObjects – Can be used on its own or with state machine – Supports easing curves, animation groups
  • 33.
    Optimizing SVG • Freetools – http://code.google.com/p/svgmin/ – http://codedread.com/scour/ SVG Loading Time Optimized Original 0 20 40 60 80 100 120 140 160 180
  • 34.
    Pixel Images • Mostcommon pixel-based formats: – .png (Portable Network Graphics) • Similar to .gif (which was patented until 2003 because of its LZW compression) • Compression: works well for graphics, not so well for photos • Transparency: support depends on device – 1 bit increasing JPEG compression transparency or full alpha-channel. – .jpg (Joint Photographic Experts Group) • Compression: for photos (wavelength), not for graphics • Transparency: not supported Image Credit: Ilmari_Karonen / Brianski Creative Commons
  • 35.
    Save PNGs –File Size Reduction 1. Optimized export – Photoshop: Save for Web 2. Further optimization – Pngcrush: http://pmt.sourceforge.net/pngcrush/ Use as few colors as possible (fine No dithering gradients compress (compression gets worse) more difficult) Transparenter Kanal You can set a transparency kann gesetzt channel werden
  • 36.
    PNG Optimization –Example: 472 x 472 px 256 colours, no dither 64 colours, no dither 8 colours, no dither 30,0 kB 16,3 kB 6,3 kB Results: - Not much difference between 256 and 64 colours (especially on a device display), but only half of the file size - Limits of optimization: 8 colours not enough - Dithering at 8 colours: same file size as visually better 64 colours image 8 colours, Diffusion dither → often, dithering is problematic! 15,9 kB
  • 37.