[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