Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. From widgets to quick2

From widgets to quick2

Scheduled Pinned Locked Moved QML and Qt Quick
15 Posts 3 Posters 5.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Offline
    Z Offline
    zing0000
    wrote on last edited by
    #1

    I have converted my old widget-based code to a new shiny QML UI running on touch-enabled windows desktop and android tablets in Qt5.2. I have done this with mixed results so here is an overview of the journey - I would love to hear from others who are doing this, i.e. not bugs and features, more a 'product' viewpoint.

    My App has two main UI components,

    • a viewport for images with pinch/zoom/pan.
    • a dashboard with several animated controls.

    The starting point was a version using C++ widgets. The graphicview provided all the functionality for multi-touch and keyboard and I was quite pleased with the performance of the image zoom and pan. I also used a declarative view for an animated busy spinner written in QML. The UI appearance was predictably boring (except for the spinner!). I used Qt5.2 and the App runs well on Windows8 laptop and Android Nexus 7.

    The next step was to replace the Declarative views with a QuickView. I also wanted to add some additional QML sophistication to the controls. This went well until I tried to deploy to android. Using widgets and Quick together meant that I had to use createWindowsContainer() which works fine on Windows desktop but does not (and I believe cannot) work on Android.

    Not discouraged, I stretched for the 'true path', i.e. a fully implemented QML UI with Quick2. This went smoothly until I tried to port the pinch/zoom functionality. I thought it would be easy to connect the touch events from a QML MouseArea to my old GraphicsView code which was easily updated to a QuickItem. Everything builds and runs but I could not get the mousePressEvents to work.

    Clearly this is not quite the 'pure' Quick2 implementation but to my surprise I found no comments from anyone else trying to do this. Is the best way to put all the pinch/zoom code into the QML? I would rather use my existing C++ code than start a jungle of javascript. There are not many Qt5.2 examples that I could find of touch / gesture UIs.

    So what shall I do?
    vote A: revert to widgets and declarative code.
    vote B: tackle head-on a new QML touch front-end.
    vote C: split responsibility for pinch/zoom between QML and C++ code.

    Happy New Year!

    1 Reply Last reply
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      Hi,

      Sounds like you want a PinchArea, not a MouseArea: http://qt-project.org/doc/qt-5/qml-qtquick-pincharea.html

      [quote]This went smoothly until I tried to port the pinch/zoom functionality. I thought it would be easy to connect the touch events from a QML MouseArea to my old GraphicsView code which was easily updated to a QuickItem. Everything builds and runs but I could not get the mousePressEvents to work.[/quote]If you still have difficulties, please provide some code.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      0
      • Z Offline
        Z Offline
        zing0000
        wrote on last edited by
        #3

        That would be a good future step. But right now I am blocked because I cannot get simple mouse events to propagate to my handling class (below).

        Keyboard events work fine from a QML TextInput (but I would like to be able to propagate individual characters rather than a terminated string)

        I am missing something!

        @
        #pragma once
        #include <QKeyEvent>
        #include <QtQuick>

        class ViewportWidget : public QQuickPaintedItem
        {
        Q_OBJECT

        public:
        ViewportWidget(QQuickItem *parent = 0);
        virtual ~ViewportWidget(void);

        public slots:
        void zoomIn();
        void zoomOut();
        void displayUpdate();

        protected:
        void keyPressEvent(QKeyEvent* event);
        void mousePressEvent(QMouseEvent* event);
        void timerEvent(QTimerEvent* event);
        #ifndef QT_NO_WHEELEVENT
        void wheelEvent(QWheelEvent* event);
        #endif
        void paint(QPainter *painter);
        void scaleView(qreal scaleFactor);

        private:
        QGraphicsScene* _scene;
        };
        @

        1 Reply Last reply
        0
        • JKSHJ Offline
          JKSHJ Offline
          JKSH
          Moderators
          wrote on last edited by
          #4

          I don't have experience in combining Qt Quick with the old Graphics View technology or in implementing a custom QQuickPaintedItem, sorry.

          What does your view port need to do? If it's only to show images with pinch/zoom/pan, it might be far simpler to reimplement everything in Qt Quick, instead of trying to glue old graphics view code to a new Qt Quick UI.

          See the "Photo Surface example":http://qt-project.org/doc/qt-5/qtquick-demos-photosurface-example.html, which does pinch/zoom/drag+drop/rotate. (you can build and run it by opening Qt Creator and searching for "Photo Surface" in Welcome -> Examples

          But anyway, if you'd still like to try your current approach but don't get any more replies here, try subscribing to the "Interest mailing list":http://lists.qt-project.org/mailman/listinfo/interest and asking there.

          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

          1 Reply Last reply
          0
          • Z Offline
            Z Offline
            zing0000
            wrote on last edited by
            #5

            Thanks for the example, and indeed this is a great demo of the power of QML for the UI-side of the problem.

            But I need to feed mouse and touch events to my C++ image analysis code, for example to interact and provide location cues to the analysis.

            For example, suppose I wish to send a mousePressed event. ViewportWidget is a registered type and I would expect mouse events to be automatically connected to the mousePressEvent(...) override method in the C++ class of the same name.

            I have tried explicit connections too, but nothing works. The events in QML are type MouseEvent, but in C++ they are QMouseEvent. It does not seem to be designed to be used this way. As I said, I must be missing something!

            @
            ViewportWidget {
            id: viewportwidget
            width: 600; height: 600

            MouseArea {
                anchors.fill: parent
                acceptedButtons: Qt.AllButtons
                onPressed: {
                    console.debug("hello")
            

            // viewportwidget.mousePressEvent(mouse)
            }
            }
            }
            @

            If I uncomment line 10, I get the runtime error
            TypeError: Object [object Object] has no method 'mousePressEvent'

            1 Reply Last reply
            0
            • JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by
              #6

              mousePressEvent() is not an "invokable method":http://qt-project.org/doc/qt-5/qobject.html#Q_INVOKABLE, so it is not accessible from QML.

              The MouseArea is a separate object from the ViewportWidget, so it's not connected to ViewportWidget::mousePressEvent().

              @
              MouseArea { anchors.fill: parent }
              @
              The code above says: "Create a new (invisible) MouseArea object, and stretch it to cover the parent object". Mouse events are received by the MouseArea object, NOT the parent object.

              I'm purely guessing here, but try this:

              Remove the MouseArea completely

              Use qDebug() to print a message in your C++ implementation of ViewportWidget::mousePressEvent()

              Build your application, and click on the QML-rendered ViewportWidget

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              1 Reply Last reply
              0
              • Z Offline
                Z Offline
                zing0000
                wrote on last edited by
                #7

                I think I follow your line of thought but it didn't work. I also tried declaring,
                @
                protected:
                void keyPressEvent(QKeyEvent* event);
                Q_INVOKABLE void mousePressEvent(QMouseEvent* event);
                @

                What puzzles me is that if I add at the same level as the MouseArea,
                @
                TextInput {
                id: kbdinput
                anchors.fill: parent
                focus: true
                }
                @

                a text string entered anywhere in the viewport does get passed to keyPressEvent(...)

                1 Reply Last reply
                0
                • T Offline
                  T Offline
                  Torgeir
                  wrote on last edited by
                  #8

                  Does your ViewportWidget call setAcceptedMouseButtons()? It is needed for mousePressEvent to be called.

                  For keypressEvent your item needs to have active focus, or a child item must have active focus (and not accept the event).

                  See also "keyboard focus in QtQuick":http://qt-project.org/doc/qt-5/qtquick-input-focus.html

                  1 Reply Last reply
                  0
                  • Z Offline
                    Z Offline
                    zing0000
                    wrote on last edited by
                    #9

                    Hi Torgier

                    In the QML MouseArea I have
                    @
                    acceptedButtons: Qt.AllButtons
                    @

                    And the problem remains,
                    keyPressEvents work; mousePressEvents do not.

                    1 Reply Last reply
                    0
                    • T Offline
                      T Offline
                      Torgeir
                      wrote on last edited by
                      #10

                      [quote author="zing0000" date="1388768258"]
                      In the QML MouseArea I have
                      @
                      acceptedButtons: Qt.AllButtons
                      @
                      [/quote]

                      Please try adding that to the ViewportWidget instead of the MouseArea.

                      1 Reply Last reply
                      0
                      • Z Offline
                        Z Offline
                        zing0000
                        wrote on last edited by
                        #11

                        Just tried it, but same result.

                        Do you have any thoughts about the experimental code line,
                        @viewportwidget.mousePressEvent(mouse)
                        @

                        My understanding is that this should call the method directly, and it seems to try, but with the error message,
                        @
                        hello
                        qrc:/qml/MainPanelLandscape.qml:45: Error: Unknown method parameter type: QMouseEvent*
                        @
                        But the QML property "mouse" is of type MouseEvent, and this does not match the method argument QMouseEvent*.

                        1 Reply Last reply
                        0
                        • T Offline
                          T Offline
                          Torgeir
                          wrote on last edited by
                          #12

                          Sorry for the confusion. My response was to this problem:
                          [quote author="zing0000" date="1388688947"]That would be a good future step. But right now I am blocked because I cannot get simple mouse events to propagate to my handling class (below).
                          [/quote]

                          If you call setAcceptedMouseButtons() in the constructor of ViewportWidget the signal handler in ViewportWidget should be called. That worked for me.

                          Then you don't need any MouseArea nor do you need to declare Q_INVOKABLE for the mousePressEvent().

                          All you need then in QML is:

                          @ViewportWidget {
                          id: viewportwidget
                          width: 600; height: 600
                          @

                          On the other hand if you want to handle it with a MouseArea and forward the events, that is possible too. However you can't forward the 'mouse' parameter as it is of type QQuickMouseEvent* and your mousePressEvent() handler needs QMouseEvent*.

                          You could forward mouse.x and mouse.y to a Q_INVOKABLE that takes two int parameters for example.

                          1 Reply Last reply
                          0
                          • Z Offline
                            Z Offline
                            zing0000
                            wrote on last edited by
                            #13

                            Thank you!
                            The problem was that I misunderstood Qt::AllButtons in the MouseArea - which was correctly consuming all mouse events instead of my intention of passing them on.
                            With Qt::NoButtons it now works.

                            But in any case, you are right, the MouseArea is not needed.

                            However, I am also trying to pass keystroke events, and I am still looking for a way of passing events for individual characters.

                            Thanks again for nudging me in the right direction.

                            1 Reply Last reply
                            0
                            • T Offline
                              T Offline
                              Torgeir
                              wrote on last edited by
                              #14

                              [quote author="zing0000" date="1388885058"]
                              However, I am also trying to pass keystroke events, and I am still looking for a way of passing events for individual characters.
                              [/quote]

                              To receive key press and release events your ViewportWidget item needs to have active focus. It may be enough to set

                              @focus: true@

                              on it, or you may have to call forceActiveFocus() on it.

                              When the item has active focus, the event handlers keyPressEvent(QKeyEvent *) and keyReleaseEvent(QKeyEvent *) will be called for individual key presses.

                              1 Reply Last reply
                              0
                              • Z Offline
                                Z Offline
                                zing0000
                                wrote on last edited by
                                #15

                                Yes, it needed both.

                                my ViewportWidget is part of a ScrollView, so I had to set focus on that.

                                and it did need forceActiveFocus() in the ViewportWidget constructor.

                                Clearly I need to read up a bit more about all this....

                                1 Reply Last reply
                                0

                                • Login

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • Users
                                • Groups
                                • Search
                                • Get Qt Extensions
                                • Unsolved