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

Jesus Fernandez jsfdez at gmail.com
Wed Aug 31 09:17:39 CEST 2011


I have the same problem than #1. But in an embedded platform and using
"raster" graphic system does not solve the problem.

Best regards :)

On Mon, Aug 15, 2011 at 10:02, Pierre Fillard <pierre.fillard at gmail.com>wrote:

> 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
>
>
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at qt.nokia.com
> http://lists.qt.nokia.com/mailman/listinfo/qt-interest
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20110831/3ea8feaf/attachment.html 


More information about the Qt-interest-old mailing list