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. Passing values from C++ to QML...
Forum Updated to NodeBB v4.3 + New Features

Passing values from C++ to QML...

Scheduled Pinned Locked Moved QML and Qt Quick
12 Posts 3 Posters 8.6k 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.
  • P Offline
    P Offline
    Peppy
    wrote on last edited by
    #1

    I have a problem, when I call from C++ code:
    @
    object->setProperty("width", viewer.width());
    @
    or:
    @
    object->setWidth(viewer.width());
    @
    I am not able to access this values from QML (at least I have tried it in "constructor" (Component.onCompleted)) - but if I call this property on destroying, it works... I don't understand that...

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mbrasser
      wrote on last edited by
      #2

      Hi,

      Can you provide a larger snippet showing e.g. where/how object is created? Perhaps Component.onCompleted is being fired before the width is changed.

      Regards,
      Michael

      1 Reply Last reply
      0
      • P Offline
        P Offline
        Peppy
        wrote on last edited by
        #3

        Yes, sure...
        @
        MainWindow
        {
        id: mainWindow

        width: 100
        height: 100
        
        Component.onCompleted:
        {
            console.log("Fired!" + mainWindow.screenWidth); // does not work.
        }
        
        Component.onDestruction:
        {
            console.log("Fired!" + mainWindow.screenWidth); // works.
        }
        
        
        Rectangle
        {
            x: 10; y: 10; width: 50; height: 50; color: "red";
        
            Component.onCompleted:
            {
                console.log(mainWindow.screenHeight)
            }
        }
        

        }
        @
        Where MainWindow is just basic QDeclarativeItem class:
        @
        #include <QObject>
        #include <QDeclarativeItem>

        class MainWindow : public QDeclarativeItem
        {
        Q_OBJECT
        Q_PROPERTY(int screenWidth READ getScreenWidth WRITE setScreenWidth NOTIFY screenWidthChanged)
        Q_PROPERTY(int screenHeight READ getScreenHeight WRITE setScreenHeight NOTIFY screenHeightChanged)

        public:
        explicit MainWindow(QDeclarativeItem *parent = 0);

        Q_INVOKABLE int getScreenWidth(void) { return window.x(); }
        void setScreenWidth(int w) { window.setX(w); }

        Q_INVOKABLE int getScreenHeight(void) { return window.y(); }
        void setScreenHeight(int h) { return window.setY(h); }

        signals:
        void screenWidthChanged(int width);
        void screenHeightChanged(int height);

        public slots:

        protected:

        private:
        QPoint window;
        };
        @
        And passing to it, in main function:
        @
        MainWindow* mainWindow = qobject_cast<MainWindow*> (viewer.rootObject());

        mainWindow->setProperty("screenWidth", viewer.width());
        mainWindow->setProperty("screenHeight", viewer.height());
        

        @
        where viewer is QDeclarativeView...

        1 Reply Last reply
        0
        • D Offline
          D Offline
          DigitalPioneer
          wrote on last edited by
          #4

          It's setting the properties, but realize that the Component.onCompleted is going to be called long before you can do things like viewer.rootObject() -- the QML components are completed at the line where you load a QML file into the viewer. The C++ cannot interact with a QML element that has not been created yet. If you want assurance that things are being set correctly as soon as the application starts (which they should be) then monitor the properties with something like this:
          @MainWindow {
          //...
          onScreenWidthChanged: {
          console.log ("screenWidth is now " + screenWidth);
          }
          }@

          Component.onCompleted will run before the C++ can interact with your object.

          1 Reply Last reply
          0
          • P Offline
            P Offline
            Peppy
            wrote on last edited by
            #5

            So, how to set variables from C++ in QML?

            I am doing something wrong, because I want to run it as fullscreen, I just need a resolution of display in QML...

            1 Reply Last reply
            0
            • D Offline
              D Offline
              DigitalPioneer
              wrote on last edited by
              #6

              You are setting the QML properties from C++. But seriously, I think you're overcomplicating this. If you want to show your QML fullscreen, then when you show the viewer, use viewer.showFullscreen() instead of whatever it is you're currently using. The root object will automatically size to the viewer size.

              1 Reply Last reply
              0
              • P Offline
                P Offline
                Peppy
                wrote on last edited by
                #7

                Well, that's not true. Only graphics scene resizes, not the root object.

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  DigitalPioneer
                  wrote on last edited by
                  #8

                  Well, it does in my experience (maybe I used anchors.fill: parent on root?), but I think you'd benefit from reading this: http://doc.qt.nokia.com/4.7-snapshot/qdeclarativeview.html#resizeMode-prop

                  1 Reply Last reply
                  0
                  • P Offline
                    P Offline
                    Peppy
                    wrote on last edited by
                    #9

                    Well, the truth is that, I have to write much more QML code (used for UI, not for the business logic) - I want to have in QML everything clean, and readble - I just want to pass the viewer's size inside into QML...

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      DigitalPioneer
                      wrote on last edited by
                      #10

                      Well you'll have to forgive me because I'm a bit slow. You can set one flag from C++ in the very readable line

                      @viewer.setResizeMode(QDeclarativeView::SizeRootObjectToView);@

                      or you can subclass QDeclarativeItem, make new properties, pass values for these properties to QML from C++, debug everything.... and you expect this to be cleaner and more readable? Please understand that I don't mean to be condescending, but we seem to have very different ideas of what constitutes cleanliness and readability. :P

                      1 Reply Last reply
                      0
                      • P Offline
                        P Offline
                        Peppy
                        wrote on last edited by
                        #11

                        Well, okay, in QML you have to write:
                        @
                        Rectangle
                        {
                        id: root
                        height: 10
                        width: 100

                        property int screenWidth: 0
                        property int screenHeight: 0
                        
                        onWidthChanged:
                        {
                            screenWidth = width
                            console.log(screenWidth)
                        }
                        
                        onHeightChanged:
                        {
                            screenHeight = height
                            console.log(screenHeight)
                        }
                        
                        Rectangle
                        {
                            Component.onCompleted:
                            {
                                console.log("root's screen height: " + root.screenHeight) // writes: 0.
                            }
                        
                        }
                        

                        }
                        @

                        Okay, it's fine - screenHeight, screenWidth are as my resolution, but the child item - rectangle depends on screenHeight/screenWidth which are the root's properties... could you change my thinking? Because I am thinking, I think, conversely.

                        1 Reply Last reply
                        0
                        • D Offline
                          D Offline
                          DigitalPioneer
                          wrote on last edited by
                          #12

                          I think these properties screenHeight and screenWidth need to go away. They make no sense; they seem to be copies of width and height.

                          Looking at your code there, this is the only code I see that actually seems useful:

                          @
                          Rectangle {
                          id: root

                          Rectangle {
                              //Whatever actually goes in this thing
                          }
                          

                          }
                          @

                          From the C++, you can just set the root object to resize to the view like I showed earlier, do a viewer.showFullScreen() and be happy. :)

                          Oh, and stop using Component.onCompleted() to tell you what the sizes of things are. QML doesn't work that way -- components are completed, but after that changes continue propagating through until everything is set up the way it's supposed to be. Rendering a QML GUI is a multistep process that happens behind the scenes, don't expect onCompleted to have the final values of things. It will have the initial placeholders (most likely 0) that are used until everything is created and real values can be calculated.

                          Of course, my response is naive because I don't know what you're actually trying to put on the screen. If I had some idea of what you want your window to look like, I could give much more useful responses.

                          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