Andreas
Uncategorized
Qt
KDE
Graphics View
Graphics
Kinetic
Posted by Andreas
 in Uncategorized, Qt, KDE, Graphics View, Graphics, Kinetic
 on Thursday, April 23, 2009 @ 17:00

As part of Qt 4.5, we added QGraphicsItem::opacity. Which is great! But it doesn’t work as well as it could. We’re receiving a few comments about how this implementation could work better. Trouble is, in Qt 4.5 we only have two ways of rendering: direct, and indirect (”cached”, e.g., ItemCoordinateCache). And in order to apply opacity, you really need full composition support… :-/

Here’s a rundown of the trouble with today’s opacity support:

  • The current behavior modifies the input opacity of the painter
    • …so you can override this opacity on a per-item basis (intentionally or not!)
    • …and each primitive (line, rect, pixmap) you draw with QPainter will be composed one at a time inside the item (which is bad!)
  • The behavior is slightly different depending on whether you cache an item or not.
    • …if you use caching, the offscreen pixmap is rendered with an opacity, whereas the item itself doesn’t have any opacity set on its painter.
  • Each item applies opacity locally, and even though opacity propagates to children, each item is still rendered by itself, cause each item to be transparent (as opposed to rendering one subtree as a whole with an opacity)

All these problems could have been solved if we treated opacity as an effect that you can apply to one layer as a whole, instead of on each item. I think this is how opacity should work in the first place… but that’s how it goes sometimes. But fear not, we can fix this in a later release! :-)

To illustrate the current behavior, here’s what you get if you construct a scene with four items, each a child of the previous item, in colors red, then green, then blue, then yellow. Logical structure in hypothetical markup:


Rect {
    color: red;
    rect: QRectF(0, 0, 100, 100);

    child : Rect {
        color : green;
        pos: QPointF(25, 25);
        rect: QRectF(0, 0, 100, 100);
        opacity: 0.5;

        child : Rect {
            color : blue;
            pos: QPointF(25, 25);
            rect: QRectF(0, 0, 100, 100);
            rotation: 45;

            child : Rect {
                color : yellow;
                pos: QPointF(25, 25);
                rect: QRectF(0, 0, 100, 100);
                scale: 2×2;
            };
        };
        };
};

This will in Qt 4.5 render the following output:

Opacity, in Qt 4.5

What’s important to notice here is how all elements are transparent; so you can see the blue through the yellow item, the green through the blue item, and the red item through the green item. But the yellow item doesn’t actually have any opacity assigned. It inherits opacity from the green item (opacity: 0.5).

By rendering the “green sub-tree” into a separate layer, we can combine all items and apply one uniform opacity as part of composing these items together. In my last blog I wrote about off-screen rendering. This work has progressed and is in quite a usable state (although the code is really ugly). It works! The rendering output for the same application as the above looks like this:

Opacity, in Qt 4.6

The essential difference is how the “green sub-tree” is treated as if it had one _combined_ opacity. The yellow item, for example, isn’t transparent by itself at all. You can’t see the blue through the yellow. By “collapsing” the subtree into a single layer we can both avoid unnecessary rerendering of items (i.e., if you move the green item around, the children are not repainted, not even from cache). Which is pretty cool!

(We get this at the cost of allocating and spending an extra pixmap, and the first time we render there’s an extra level of indirection.)

But there’s even more applications to this technique… :-) With code for handling explicit composition of layers, we can now use pixmap filters and shaders to compose one layer onto another. And this is very useful for any future effects API we might add to Qt in general. Imagine applying a gaussian blur effect to the layer represented by the green item. The result is below:

Opacity w/blur, in Qt 4.6

The result is very neat; the whole layer is blurred before it’s rendered. You don’t get funny artifacts that might have occurred in overlapping regions if each of the items was blurred individually.

Now none of this gives any mind-blowing screenshots (at least not yet), but it’s an important step that provides faster rendering of subtrees (as sliding and transforming a complex graph of items ends up just being matrix operations on a single pixmap/texture, and in software this prevents overdrawing), a more accurate processing of the opacity property of QGraphicsItem, and it makes it very easy to apply fancy composition effects to groups of items.

Questions: Should layers be explicitly defined, or implicitly handled by logics inside Graphics View? In the example above, I’ve used the opacity property to detect whether an item’s subtree should be rendered into a separate layer or not. This is easy to do and very clear/unsurprising. But what if you want to collapse a subtree for performance reasons? An alternative, or possibly an additional approach would be to add an explicit setting: QGraphicsItem::setLayer(true) or setCacheMode(QGraphicsItem::DeepItemCoordinateCache). I’m torn. Experimentation and feedback will show (yes I know I need to push this code out, once our SCM goes public this will be much easier!).

There’s also the problem with these darn flags QGraphicsItem::ItemIgnoresParentOpacity and QGraphicsItem::ItemDoesntPropagateOpacityToChildren. There’s no way to make these flags work with a layered rendering approach. But are these flags very important, or could we just (*cough* *cough*) disable/deprecate them? ;-)

Finally I still haven’t found out how to handle ItemIgnoresTransformations. The most probable solution is that these items are automatically rendered into a separate layer.

Happy hacking! :-)

Jan-Arve
Graphics
Kinetic
Posted by Jan-Arve
 in Graphics, Kinetic
 on Thursday, April 23, 2009 @ 13:58

Since I don’t want to take focus away from the 4.5.1 release, I’ll keep this short. We have now released an updated version of the Animation Framework solution. There are not so many visible changes to the animation classes - besides bug fixes we renamed QAbstractAnimation::iterationCount back to QAbstractAnimation::loopCount. (You don’t want to know how many times we have discussed the naming of that property). And let’s not forget that sub-attaq now has animated explosions! (sorry, no video)
But there are more interesting changes to the state machine classes. Hopefully, this will be the last solution before it gets merged into 4.6 so this might be one of your last chances of influencing it.

Please tell us what you think!

denis
Uncategorized
Qt
Posted by denis
 in Uncategorized, Qt
 on Thursday, April 23, 2009 @ 12:35

After Brad has blogged about multi-touch support in Qt, it became perfectly clear that there is a need for better description of a high-level API that should be built on top of user input (mouse- and touch-based and possibly others) providing complex input events support known as “gestures”.

I think what the gesture api should provide to the widget developers an ability to drop-in gesture support without modifying the widget source code much. However some modification is required - at least the widget should announce that it supports gesture input and implement gesture event handler. Good news are that for standard Qt widgets this can be handled by cuteQt developers.

Thinking about gesture event - I’d say that they should be as context-free as possible - i.e. instead of a QZoomGesture it should be called QPinchGesture with a distance delta, QGoToNextImageGesture should be called QSlideGesture with a direction argument that specifies slide direction. It should be up to the application developer to decide which action should be executed as a result of a gesture. Of course for the most commonly used gestures there could be a recommended action documented somewhere - for example Pinch is usually used for zooming and rotating an item, and TwoFingerTap (as well as Tap-And-Hold) usually triggers a context menu.

Native and Non-native Gestures

The gesture api is intended to be extendable so that application developers can implement custom gestures support (for example Linja Zax gesture). The idea is that all you need to add a new gesture is subclass the QGestureRecognizer class, implement a state machine that recognizes a gesture out of a list of QMouseEvent/QTouchEvents and “register” it in a gesture framework.

Some OSes also have support for native gestures - for example - Windows 7 with its new WM_GESTURE window message that supports most common gestures like Panning (with either one or two fingers), Pinching (zoom and rotate), etc. Of course we would also want Qt to benefit from having native gestures support and automatically translate them to QGestureEvents - this is done automatically by Qt itself and the application developer won’t event bother what was the source of the gesture.

However implementing native gesture support adds some limitations to our gesture api - for example there are some tricks on Windows7 - if it decides that the gesture started or is about to start, we will not get raw mouse/touch events that resulted in the gesture, but get WM_GESTURE events only. Moreover a single window cannot receive both WM_TOUCH and WM_GESTURE events. That means that there could be no direct mapping between mouse/touch events and gesture events, hence the application developer that uses Qt gesture api cannot rely on receiving QTouchEvent before a QGestureEvent. But I suppose in most gesture usecases this should be acceptable.

While looking into gesture handling on Windows 7, I’ve noticed that it delays WM_LBUTTONDOWN message delivery when you touch the screen until either a finger was released or a finger was moved far enough to figure out if this is a beginning of a gesture or not. The current implementation of Qt Gesture API follows the same concept and delays the QMouseEvent delivery to gesture-enabled widgets and replays these events back to the widget if either a mouse release event received or gesture recognizers didn’t come to a solid conclusion in a fixed amount of time. That allows to have gesture support in complex widget like QWebView without modifying the widget source code to work around issues when a gesture starts over a link or an image (to tell apart a gesture, a drag-n-drop sequence and a click on a link). That might not be something that suits  all applications, and that’s why the delay is configurable and can be turned off completely, allowing a widget to receive both mouse/touch events and gesture events.

Custom gestures

To add a custom gesture support the developer need to subclass a QGestureRecognizer class and add it to the Gesture framework. For widgets that subscribe to gestures provided by that recognizer, the recognizer object will become an input event filter which decides if the input event should be forwarded to the widget or a QGestureEvent should be sent instead.

gestures.png

The source code for the QGestureRecognizer should be self explanatory:

/*!
    class QGestureRecognizer

    brief The QGestureRecognizer class is the base class for
    implementing custom gestures.

    This is a base class, to create a custom gesture type, you should
    subclass it and implement its pure virtual functions.

    Usually gesture recognizer implements state machine, storing its
    state internally in the recognizer object. The recognizer receives
    input events through the l{QGestureRecognizer::}{filterEvent()}
    virtual function and decides whether the parsed event should
    change the state of the recognizer - i.e. if the event starts or
    ends a gesture or if it isn’t related to gesture at all.
*/
class Q_GUI_EXPORT QGestureRecognizer : public QObject
{
public:
    /*!
        This enum type defines the state of the gesture recognizer.

        value NotGesture              Not a gesture.

        value GestureStarted The continuous gesture has started. When the
        recognizer is in this state, a l{QGestureEvent}{gesture event}
        containing QGesture objects returned by the
        l{QGestureRecognizer::}{getGesture()} will be sent to a widget.

        value GestureFinished The gesture has ended. A
        l{QGestureEvent}{gesture event} will be sent to a widget.

        value MaybeGesture Gesture recognizer hasn’t decided yet if a
        gesture has started, but it might start soon after the following
        events are received by the recognizer. This means that gesture
        manager shouldn’t reset() the internal state of the gesture
        recognizer.
    */
    enum Result
    {
        NotGesture,
        GestureStarted,
        GestureFinished,
        MaybeGesture
    };

    explicit QGestureRecognizer(const QString &type, QObject *parent = 0);

    /*!
        Returns the name of the gesture that is handled by the recognizer.
    */
    QString gestureType() const;

    /*!
       The main method that processes input events and changes the
       internal state accordingly.
       Return the current state of the gesture recognizer.
    */
    virtual QGestureRecognizer::Result filterEvent(const QEvent* event) = 0;

    /*!
        Returns a gesture object that will be send to the widget. This
        function is called when the gesture recognizer changed its state
        to QGestureRecognizer::GestureStarted or
        QGestureRecognizer::GestureFinished.
    */
    virtual QGesture* getGesture() = 0;

    /*!
        Resets the internal state of the gesture recognizer.
    */
    virtual void reset() = 0;

signals:
    /*!
        The gesture recognizer might emit the stateChanged() signal when
        the gesture state changes asynchronously, i.e. without any event
        being filtered through filterEvent().
    */
    void stateChanged(QGestureRecognizer::Result result);
};
Jason McDonald
Qt
Posted by Jason McDonald
 in Qt
 on Thursday, April 23, 2009 @ 09:36

After much hard work from Qt Software developers in Oslo, Berlin and Brisbane, Qt 4.5.1 is now available.

Qt 4.5.1 is a patch level release providing a large number of bug fixes and minor improvements over the 4.5.0 release that went out in early March. You can get Qt 4.5.1 here and you can see what’s changed in the changes log.

Many thanks are due to those users who provided feedback on the 4.5.0 release. Your feedback has been very valuable in helping us to improve Qt, and we hope that you will continue to send us your constructive criticism, wishlists, likes and dislikes for the 4.5.1 release and beyond.

Eike Ziller
QtCreator
Posted by Eike Ziller
 in QtCreator
 on Thursday, April 23, 2009 @ 09:18

Indeed, time does fly. Today we released Qt Creator 1.1.0 together with Qt 4.5.1, VS Add-in 1.0, and an updated Qt SDK 2009.02 that contains the new Qt and Qt Creator. Get it from the downloads page!

I wrote a lot about the upcoming QtCreator 1.1 already in this blog post on the release candidate, but since you might not be inclined to actually read that as well, I’ll just take the chance to repeat myself ;). These are some of the highlights:

  • Completely reworked editor split mechanism
  • Improved function argument hint (since a lot of you reported problems with that one!)
  • Improved open documents view (sorted, single-click, close buttons)
  • Added experimental support for generic Makefile based projects
  • Added signal/slot editor to the form editor

A lot of things are not mentioned above, please have a look at the more complete list of interesting changes.

Thank you all for the last minute feedback. If we didn’t manage to put your favorite feature in, don’t despair (and please don’t get your flame-thrower out), the next release will not be far away. For example we are working full-steam on the cdb (VS debugger) integration. If you want to check out what is going on, have a look at the snapshots (we are in the process of getting them up again. edit: available now), or at the source repository.

Kavindra Palaraja
Qt
 in Qt
 on Thursday, April 23, 2009 @ 08:52

When you write documentation on a daily basis, with very little link to the outside world* beyond the tasks created by our esteemed Support department, you can get lost in your own little world, thinking your documentation is perfect ;)

So if the documentation is perfect, then Qt is perfect, no?

Read the rest of this entry »

Alessandro
Qt
S60
Posted by Alessandro
 in Qt, S60
 on Wednesday, April 22, 2009 @ 10:26

Nothing fancy, just an update of the Qt for S60 development :)

At the MWC this year, S60 developers were pleased when we showed them our nice Qt for S60 demos on the touch based XpressMusic 5800 devices. However, many of them where asking about the support for keypad devices. Therefore, here is a video showing the current development state (not included in the “Garden” release) of Qts Keypad Navigation on S60.

Note: It is work in progress and not yet complete. Also, it still needs to be polished by designers in order to look sweet :)


Download as .ogv (~3MB)

Edit: Here is a screenshot of selected (or ‘ticked’ as it is called in S60) items in a list view. They can be toggled with the select key. In this example, the SelectionMode is set to “QAbstractItemView::MultiSelection”.

No
Qt
SCXML
Posted by No'am Rosenthal
 in Qt, SCXML
 on Wednesday, April 22, 2009 @ 09:52

After some excellent feedback on Kent and Eskil’s state machine framework, and on the old-time Qt-SCXML project, we now present the updated version, with the latest and greatest of both. Qt State Machine Framework Solution 1.1 now includes not only carefully designed API adjustments and bug fixes to the main state/transition classes, but it now also includes the Qt-SCXML functionality, loaded into the Qt State Machine Framework with the QtScriptedStateMachine class.

What does the SCXML part add?

With both SCXML and the State Machine C++ API, you can choose whether your design calls for Qt/C++ style initialization of the state machine, or for loading external SCXML files that access Qt through scripting. The SCXML part also contains a few additions that are not implemented in the C++ API, such as anchors, and the ability to use scripted conditions to guard transitions (even without loading a whole SCXML file, with the QtScriptedTransition class).

Even with the aforementioned features, the SCXML support is a pretty thin layer on top of the C++ State Machine API, as it is basically some standard QXmlStreamReader code for parsing the SCXML file, QtScript for ecmascript transitions and actions, and a couple of additional goodies like menu/message-box and anchors.

Note that there might be a few minor discrepancies between the SCXML spec and what’s supported in the implementation. That’s due to the fact that the SCXML specification itself is still evolving. We’re also participating in the group that makes that happen.

A feature that didn’t make it to the release

During the development of this solution, we made an attempt at creating a compiler similar to uic (the QtDesigner form compiler), that would generate C++ Qt State Machine code from the SCXML files, and thus reduce the load time of the state machine. We solicit feedback as to whether such feature is needed.

Note to users of the original Qt-SCXML project

Some of the original features of Qt-SCXML have been enhanced, removed or modified in this spec. For example, instead of using the custom <Qt:property /> tag, we enable an invoke tag <invoke type=”q-bindings” /> that does virtually the same thing. See the ported examples and you’ll get the picture :)

Also, Qt-SCXML now supports only QtScript, and not the “native” sort-of-expression-syntax it supported before as an alternative. If you’re interested in using Qt state-machines without using QtScript at all, We hope that the C++ API is an adequate answer.

If a removed feature from the old Qt-SCXML is extremely close to your heart, please speak your mind!

Feedback Please

Any bug, question, suggestion or interesting use you have: qt-solutions@trolltech.com or here.

Link to the solution: http://www.qtsoftware.com/products/appdev/add-on-products/catalog/4/Utilities/qt-state-machine-framework/

Enjoy :)

Bradley T. Hughes
Qt
 in Qt
 on Monday, April 20, 2009 @ 11:30

A few weeks ago, Denis blogged about some thoughts he had on how gesture recognition could work in Qt. One of the things he mentioned, and that was also brought up in the comments, was support for multi-touch gestures. As a MacBook Pro owner, I already use multi-touch gestures every single day. Needless to say, he got my attention. I would certainly like to see multi-touch events and gestures in Qt so that I can start using them myself. The only question is… how do we do it?

Read the rest of this entry »

Morten Johan Sørvig
Qt
 in Qt
 on Friday, April 17, 2009 @ 12:24

cocoawidgets.png

Qt on Mac OS X has traditionally used Appearance Manager/HITheme to draw its widgets. This has been a great experience so far, but lately more and more UI elements have appeared as Cocoa views only with no corresponding HITheme API.

So, for Qt 4.5 we went ahead and built an escape hatch: QMacCocoaViewContainer. This class allows you to embed any Cocoa view in a Qt widget hierarchy. Its only drawback is that programmers have to learn the Cocoa API conventions and that odd [function call] syntax.

To try to remedy this I’ve experimented a bit with using the Cocoa views (or Cocoa cells to be specific) directly to replace the drawing code for certain widgets. So far I’ve done three classes: QtCocoaPushButton, QtCocoaComboBox and QtCocoaSegmentedButton. The first two are subclasses of the similar Qt classes, while the last provides a visual appearance for QButtonGroup.

I’m currently supporting my dev machine setup: Qt 4.5/Cocoa on Mac OS X.5.
Qt 4.4, Qt/Carbon or 10.4 support can probably be added if there is interest.

The code is available on the git server (Run “git clone git://labs.trolltech.com/msorvigs-cocoawidgets cocoawidgets”)



© 2008 Nokia Corporation and/or its subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation in Finland and/or other countries worldwide.
All other trademarks are property of their respective owners.