[Qt-interest] QML Images displayed incorrectly on Linux/X11 with OpenGL viewport + Crash on Windows

Pierre Fillard pierre.fillard at gmail.com
Mon Aug 15 10:02:05 CEST 2011


Just a quick feedback.

For problem #1, setting the graphics system to "raster" seems to solve it,
i.e., by putting:

QApplication::setGraphicsSystem("raster");

in the main before the QApplication is created the problem vanishes.

Pierre.


On Sat, Aug 13, 2011 at 6:22 PM, Pierre Fillard <pierre.fillard at gmail.com>wrote:

> Hello folks,
>
>
> Sorry about the title, the two problems are IMO not connected at all. But I
> am running into those on the same code snippet and they are puzzling me.
> First, my setup:
>
>
> Qt Desktop SDK 4.7.3
> Linux Ubuntu 11.04 x86_64
> Windows 7 / Visual Studio 2010 express
>
>
> *Now the description:*
>
> (I moved all the code samples at the end of the post - anyone should be
> able to reproduce what I am describing now with this minimal example. The
> code snippet can also be downloaded from here:
> https://transfert.inria.fr/fichiers/f0ab563059f84fb4b3ca77e7ddfdf2b1/qml_bug.rar- it is available for 5 months).
>
>
> I want to display a *toolbar* on top of a *QGraphicsView* and *animate it*when the mouse enters the top of the view. The toolbar is designed using QML
> and called from a C++ app.
>
>
> I wrote a QML element, namely a ToolBar (see ToolBar.qml), composed of
> ToolButtons (see ToolButton.qml). Those ToolButtons are made of a MouseArea
> and an Image showing the ToolButton icon. Nothing exceptional. Note that
> icons are taken from a Qt resource file that I embedd in my binary.
>
>
> Now, those QML elements are created from my C++ app using customized
> QGraphicsScene / QGraphicsView (see myGraphicsView / myGraphicsScene) and
> QDeclarativeComponent. *My QGraphicsView sets its viewPort to an openGL
> Widget* because I need it for displaying other stuff. My QGraphicsScene is
> responsible for creating the QML element and adding it to itself. I also use
> some logic using a QStateMachine to make the toolbar appear / disappear
> smoothly (using an animation) when the mouse is over the top the view.
>
>
> In my main app (see main.cpp), *I finally create two of these* (two pairs
> of (view , scene) embedded in an horizontal layout).
>
>
> *Now the problems:*
>
>
>    1. on Linux, *toolbar icons are totally mixed up or just shown
>    incorrectly* (random pixels). I also get tons of X errors about invalid
>    pixmap parameters. If I use a regular QWidget as a viewPort for my
>    QGraphicsView, everything works fine (but this is not an option). I tried to
>    use item providers, clearing the QPixmapCache, nothing worked. This problem
>    occurs only on Linux, meanging that the behaviour is correct on Windows and
>    Mac.
>
>    2. *on Windows, if compiled in Release mode, the program crashes when
>    emitting the signal enterToolbarArea()*. This signal is emitted when
>    the mouse passes over a certain region of the view. It is emitted from the
>    mouseMoveEvent() of the QGraphicsView. This event is then interpreted by the
>    state machine to trigger the display of the toolbar.
>    Note that *if I remove any signal declaration in the root Item of the
>    ToolBar* (see ToolBar.qml - I added a custom dummy signal which is
>    actually never called), *the program runs fine*. If *I remove the
>    animation, the program runs fine as well*.
>    The bug *only appears when compiling in Release mode with Visual Studio
>    * (compiling in Debug or on any other system, it works). I tried with
>    other version of visual studio, same effect.
>
>
> If anyone has an idea about one or the other problem, you'll be my
> champion.
>
>
> Cheers,
> Pierre.
>
>
> *Now the code:*
>
> ToolButton.qml:
>
> import Qt 4.7
>>
>> Rectangle {
>>      id: container
>>
>>      property string text: "Button"
>>
>>      property string icon
>>
>>      signal clicked (bool value);
>>      signal pressed
>>      signal released
>>
>>      SystemPalette { id: activePalette }
>>
>>      width:  45
>>      height: 45
>>      smooth: true
>>
>>      color: {
>>          if (mouseArea.pressed) {
>>             return activePalette.highlight;
>>          }
>>          else {
>>             return "gray";
>>          }
>>      }
>>
>>      MouseArea {
>>          id: mouseArea
>>          anchors.fill: parent
>>          onClicked: {container.clicked(true);}
>>
>>          onPressed: container.pressed();
>>
>>          onReleased: {container.released();}
>>      }
>>
>>      Image {
>>          id: myImage
>>          smooth: true
>>          anchors.centerIn: container
>>          source: container.icon
>>          sourceSize.width: container.width
>>          sourceSize.height: container.height
>>      }
>>  }
>>
>
>
> ToolBar.qml:
>
> import Qt 4.7
>>
>>  Item {
>>      width: 640
>>      height: 45
>>
>>      signal dummySignal // makes app crash on Windows when compiled in
>> Release mode
>>
>>      Rectangle {
>>          id:myToolBar
>>          objectName:"toolBar"
>>
>>          anchors.fill: parent
>>
>>         color: "transparent"
>>
>>         property int spacing: 5
>>
>>
>>          ToolButton {
>>              id: tb1
>>              icon: "/icons/designer.png"
>>
>>              anchors.right: parent.right
>>              anchors.verticalCenter: parent.verticalCenter
>>          }
>>
>>          ToolButton {
>>              id: tb2
>>              icon:  "/icons/go-next.png"
>>
>>              anchors.right: tb1.left
>>              anchors.rightMargin: parent.spacing
>>              anchors.verticalCenter: parent.verticalCenter
>>         }
>>
>>          ToolButton {
>>              id: tb3
>>              icon:  "/icons/qwebview.png"
>>
>>              anchors.right: tb2.left
>>              anchors.rightMargin: parent.spacing
>>              anchors.verticalCenter: parent.verticalCenter
>>          }
>>
>>          ToolButton {
>>              id: tb4
>>              icon:  "/icons/videoplayer.png"
>>
>>              anchors.right: tb3.left
>>              anchors.rightMargin: parent.spacing
>>              anchors.verticalCenter: parent.verticalCenter
>>          }
>>
>>          Rectangle {
>>              id: spacer
>>              anchors {right: tb4.left; rightMargin: 5; verticalCenter:
>> parent.verticalCenter}
>>              width: parent.width - 4*(tb1.width + 5)
>>              height: parent.height
>>              color: "white"
>>          }
>>      }
>>  }
>>
>
>
> myGraphicsView.h:
>
> #ifndef MYGRAPHICSVIEW_H
>> #define MYGRAPHICSVIEW_H
>>
>> #include <QtGui>
>>
>> class myGraphicsScene;
>> class myGraphicsViewPrivate;
>>
>> class myGraphicsView : public QGraphicsView
>> {
>>     Q_OBJECT
>>
>> public:
>>              myGraphicsView (myGraphicsScene * scene, QWidget * parent =
>> 0);
>>     virtual ~myGraphicsView (void);
>>
>> signals:
>>     void enterToolbarArea (void);
>>     void leaveToolbarArea (void);
>>
>> protected:
>>     void resizeEvent (QResizeEvent * event);
>>     void mouseMoveEvent (QMouseEvent *event);
>>
>> private:
>>     myGraphicsViewPrivate *d;
>> };
>>
>> #endif // MYGRAPHICSVIEW_H
>>
>
>
> myGraphicsView.cpp:
>
> #include "myGraphicsView.h"
>>
>> #include "myGraphicsScene.h"
>>
>> #include <QGLWidget>
>>
>> #include <QDeclarativeItem>
>>
>> class myGraphicsViewPrivate
>> {
>> public:
>>     bool top;
>>
>>     myGraphicsScene *scene;
>>
>>     QStateMachine *stateMachine;
>>
>>     QState *toolbarState;
>>     QState *defaultState;
>>
>>     QPropertyAnimation *toolbarAnimation;
>> };
>>
>> myGraphicsView::myGraphicsView (myGraphicsScene * scene, QWidget * parent)
>>     : QGraphicsView (scene, parent), d (new myGraphicsViewPrivate)
>> {
>>     this->setViewport(new QGLWidget(this) );
>>     this->setViewportUpdateMode(
>>
>>     QGraphicsView::FullViewportUpdate);
>>     this->setCacheMode(CacheNone);
>>     this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
>>     this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
>>     this->setMouseTracking(true);
>>
>>     Q_ASSERT (scene!=NULL);
>>
>>     d->scene = scene;
>>
>>     d->top = false;
>>
>>     d->toolbarAnimation = new QPropertyAnimation (d->scene->toolbar(),
>> "y", this);
>>     d->toolbarAnimation->setDuration(250);
>>     d->toolbarAnimation->setEasingCurve(QEasingCurve::InOutQuad);
>>
>>     // Build the state machine
>>     d->stateMachine = new QStateMachine (this);
>>
>>     d->toolbarState = new QState (d->stateMachine);
>>     d->defaultState = new QState (d->stateMachine);
>>
>>     d->stateMachine->setInitialState (d->defaultState);
>>
>>     d->defaultState->addTransition (this, SIGNAL (enterToolbarArea()),
>> d->toolbarState)
>>         ->addAnimation (d->toolbarAnimation);
>>     d->toolbarState->addTransition  (this, SIGNAL (leaveToolbarArea()),
>> d->defaultState)
>>         ->addAnimation (d->toolbarAnimation);
>>
>>     QRectF rect = d->scene->toolbar()->boundingRect();
>>
>>     d->toolbarState->assignProperty  (d->scene->toolbar(), "y", 0);
>>     d->defaultState->assignProperty  (d->scene->toolbar(), "y",
>> -rect.height());
>>
>>     d->stateMachine->start();
>> }
>>
>> myGraphicsView::~myGraphicsView (void)
>> {
>>     delete d;
>> }
>>
>> void myGraphicsView::resizeEvent (QResizeEvent * event)
>> {
>>     QGraphicsView::resizeEvent (event);
>>
>>     if (d->scene) {
>>         QPointF shownPos  = this->mapToScene (0, 0);
>>         QPointF hiddenPos = this->mapToScene (0, -45);
>>
>>         if (d->stateMachine->configuration().contains (d->toolbarState))
>>             d->scene->toolbar()->setPos ( shownPos );
>>         else
>>             d->scene->toolbar()->setPos ( hiddenPos );
>>
>>         d->scene->toolbar()->setWidth ( event->size().width() );
>>
>>         d->toolbarState->assignProperty  (d->scene->toolbar(), "y",
>> shownPos.y());
>>         d->defaultState->assignProperty  (d->scene->toolbar(), "y",
>> hiddenPos.y());
>>
>>         this->update();
>>     }
>> }
>>
>>
>> void myGraphicsView::mouseMoveEvent( QMouseEvent * e )
>> {
>>     if ( e->buttons() == Qt::NoButton ) {
>>         if (d->scene->toolbar()->boundingRect().contains ( e->pos() ) ) {
>>             if (!d->top) {
>>                 d->top = true;
>>                 emit enterToolbarArea();
>>             }
>>         }
>>         else {
>>             if (d->top) {
>>                 d->top = false;
>>                 emit leaveToolbarArea();
>>             }
>>         }
>>     }
>>     else
>>         QGraphicsView::mouseMoveEvent (e);
>> }
>>
>
>
> myGraphicsScene.h:
>
> #ifndef MYGRAPHICSSCENE_H
>> #define MYGRAPHICSSCENE_H
>>
>> #include <QtGui>
>>
>> class QDeclarativeItem;
>> class myGraphicsScenePrivate;
>>
>> class myGraphicsScene : public QGraphicsScene
>> {
>>     Q_OBJECT
>>
>> public:
>>              myGraphicsScene (QObject * parent = 0);
>>     virtual ~myGraphicsScene (void);
>>
>>     QDeclarativeItem *toolbar (void) const;
>>
>> private:
>>     myGraphicsScenePrivate *d;
>>
>> };
>>
>> #endif // myGraphicsScene_H
>>
>
>
> myGraphicsScene.cpp:
>
> #include "myGraphicsScene.h"
>>
>> #include <QDeclarativeEngine>
>> #include <QDeclarativeComponent>
>> #include <QDeclarativeItem>
>>
>> #include <QDebug>
>>
>> class myGraphicsScenePrivate
>> {
>> public:
>>     QDeclarativeEngine  *engine;
>>     QDeclarativeItem    *toolbar;
>> };
>>
>> myGraphicsScene::myGraphicsScene(QObject *parent)
>>     : QGraphicsScene (parent), d (new myGraphicsScenePrivate)
>> {
>>     d->engine  = new QDeclarativeEngine (this);
>>
>>     QDeclarativeComponent component (d->engine,
>> QUrl("qrc:/qml/ToolBar.qml"));
>>     d->toolbar = qobject_cast<QDeclarativeItem *>(component.create());
>>     if (!d->toolbar) {
>>         qDebug() << "cannot create toolbar";
>>         qDebug() << component.errorString();
>>     }
>>     Q_ASSERT (d->toolbar!=NULL);
>>
>>     d->toolbar->setPos (0, 0);
>>     d->toolbar->setHeight (45);
>>     d->toolbar->setY(-45);
>>
>>     this->addItem (d->toolbar);
>> }
>>
>> myGraphicsScene::~myGraphicsScene (void)
>> {
>>     delete d;
>> }
>>
>> QDeclarativeItem *myGraphicsScene::toolbar (void) const
>> {
>>     return d->toolbar;
>> }
>>
>
>
> main.cpp:
>
> #include <QApplication>
>>
>> #include <QtGui>
>>
>> #include "myGraphicsScene.h"
>> #include "myGraphicsView.h"
>>
>> int main (int argc, char *argv[])
>> {
>>     QApplication application (argc, argv);
>>
>>     QMainWindow mainWindow;
>>
>>     QWidget *mainWidget = new QWidget (&mainWindow);
>>
>>     // create 2 scenes
>>     myGraphicsScene *scene1 = new myGraphicsScene (mainWidget);
>>     myGraphicsScene *scene2 = new myGraphicsScene (mainWidget);
>>
>>     // create 2 myGraphicsView instances
>>     myGraphicsView *view1 = new myGraphicsView (scene1, mainWidget);
>>     myGraphicsView *view2 = new myGraphicsView (scene2, mainWidget);
>>
>>     // create a default layout
>>     QHBoxLayout * layout = new QHBoxLayout (mainWidget);
>>     layout->addWidget (view1);
>>     layout->addWidget (view2);
>>
>>     mainWindow.setCentralWidget (mainWidget);
>>     mainWindow.resize (640, 480);
>>
>>     mainWindow.show();
>>
>>     return application.exec();
>> }
>>
>
>
> --
> Pierre Fillard, Ph.D.,
> Research Scientist
> INRIA Parietal - Neurospin
> Bât 145, Point Courrier 156
> 91191 Gif/Yvette, France
> tel: +33 1 69 08 79 92
>
> INRIA Saclay-Île-de-France,
> Parc Orsay Université
> 4, rue Jacques Monod
> 91893 Orsay cedex
> tel: +33 1 72 92 59 62
>
>


-- 
Pierre Fillard, Ph.D.,
Research Scientist
INRIA Parietal - Neurospin
Bât 145, Point Courrier 156
91191 Gif/Yvette, France
tel: +33 1 69 08 79 92

INRIA Saclay-Île-de-France,
Parc Orsay Université
4, rue Jacques Monod
91893 Orsay cedex
tel: +33 1 72 92 59 62
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20110815/07412807/attachment.html 


More information about the Qt-interest-old mailing list