[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