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. Property Binding not updating after signal emitted
Forum Updated to NodeBB v4.3 + New Features

Property Binding not updating after signal emitted

Scheduled Pinned Locked Moved Solved QML and Qt Quick
12 Posts 2 Posters 2.3k Views
  • 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.
  • B beckseba

    Hello,

    I use a property binding to update a text box in my application. The value shall be updated after a change of the variable QString m_textBox1 in the c++ backend. Here, is a code snippet example:

    messaging.h
    
    Q_OBJECT
    Q_PROPERTY(QString textBox1 READ textBox1 WRITE setTextBox1 NOTIFY textBox1Changed)
    
    public: 
        QString textBox1();
        void setTextBox1(QString value);
        void setMessageText(QString message);
    
    signals:
        void textBox1Changed(); 
    
    private:
        QString m_textBox1 = "";
    
    
    messaging.cpp
    
    void Messaging::setMessageText(QString message)
    {
        setTextBox1(message);
        qDebug() << textBox1();
    }
    
    QString Messaging::textBox1()
    {
        return m_textBox1;
    }
    
    void Messaging::setTextBox1(QString value)
    {
         m_textBox1 = value;
         emit textBox1Changed();
    }
    
    test.qml
    
    import hmi.messaging 1.0
    
    textBox1 {
           text: messages.textBox1
    }
    

    I have also tested

    property string textMessage: ""
    Messaging {
         id: messages
         onTextBox1Changed:
         {
              console.log("Test")
              screen.textMessage = textBox1;
        }
    }
    
    textBox1 {
           text: screen.textMessage
    }
    

    But the signal seems not to be emitted. The qDebug()shows, that the global variable m_textBox1has been changed but the console.log()is not executed. I worked a lot with Qt and I had never this problem. Does someone has an idea?

    Thank you.

    J.HilkJ Offline
    J.HilkJ Offline
    J.Hilk
    Moderators
    wrote on last edited by
    #2

    @beckseba you don't have a guard in the setTextBox1 function, that prevents the emit, when the same text is set again.

    If the signal is emitted too often during one event loop cycle, the binding is broken.
    Do you get a console output about binding loops or something like that?


    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


    Q: What's that?
    A: It's blue light.
    Q: What does it do?
    A: It turns blue.

    1 Reply Last reply
    0
    • B Offline
      B Offline
      beckseba
      wrote on last edited by
      #3

      @J-Hilk I have added a guard in the setTextBox1()function but it is still not working. I am wondering that the initialization value of m_textBox1is shown properly when starting the application but updating when clicking a button is not working.

      Yet, I did not debug the binding loop.

      J.HilkJ 1 Reply Last reply
      0
      • B beckseba

        @J-Hilk I have added a guard in the setTextBox1()function but it is still not working. I am wondering that the initialization value of m_textBox1is shown properly when starting the application but updating when clicking a button is not working.

        Yet, I did not debug the binding loop.

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #4

        @beckseba can you make a minimal example for us to check out?

        the only thing missing from your opening post seems to be the main.cpp


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        1 Reply Last reply
        0
        • B Offline
          B Offline
          beckseba
          wrote on last edited by
          #5

          @J-Hilk I have only registered the Messaging class qmlRegisterType<Messaging>("hmi.messaging",1,0,"Messaging");in the main.cpp file.

          In my application I have several classes which are able to update the property bindings very well. The only difference is that I call void Messaging::setMessageText(QString message)from annother class to trigger the update of the property.

          J.HilkJ 1 Reply Last reply
          0
          • B beckseba

            @J-Hilk I have only registered the Messaging class qmlRegisterType<Messaging>("hmi.messaging",1,0,"Messaging");in the main.cpp file.

            In my application I have several classes which are able to update the property bindings very well. The only difference is that I call void Messaging::setMessageText(QString message)from annother class to trigger the update of the property.

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #6

            @beckseba sounds like you're updating a different instance of the class then the qml side has access to


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            0
            • B Offline
              B Offline
              beckseba
              wrote on last edited by
              #7

              @J-Hilk That would be a valid reason why it is not working. Have you an idea for triggering the update from annother class?

              J.HilkJ 1 Reply Last reply
              0
              • B beckseba

                @J-Hilk That would be a valid reason why it is not working. Have you an idea for triggering the update from annother class?

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #8

                @beckseba from c++ side ?

                afaik, there's only setting a c++ class instance as contextProperty (setContextProperty) or qmlRegisterSingletonType and accessing the class instance via the getters respectively

                https://doc.qt.io/qt-5/qqmlcontext.html#setContextProperty
                https://doc.qt.io/qt-5/qqmlengine.html#qmlRegisterSingletonType


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  beckseba
                  wrote on last edited by
                  #9

                  @J-Hilk Thank you for the hint. However, I do not understand how to update a property if the update does not take place in the main function, because I have no access to the QQuickView viewobject.

                  J.HilkJ 1 Reply Last reply
                  0
                  • B Offline
                    B Offline
                    beckseba
                    wrote on last edited by
                    #10

                    Are there any additional ideas how to access from annother instance property bindings, or in general how to access qml properties (from c++ side) from annother class. More precisely (considering the example in the first comment), how can I update m_textBox1from a second class e.g. handler.cpp so that the textBox1in test.qml is also updated properly?

                    handler.cpp
                    
                    Messaging messagingObject;
                    messagingObject.setMessageText("This is a new message");
                    
                    

                    Thank you for the support.

                    1 Reply Last reply
                    0
                    • B beckseba

                      @J-Hilk Thank you for the hint. However, I do not understand how to update a property if the update does not take place in the main function, because I have no access to the QQuickView viewobject.

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #11

                      @beckseba said in Property Binding not updating after signal emitted:

                      @J-Hilk Thank you for the hint. However, I do not understand how to update a property if the update does not take place in the main function, because I have no access to the QQuickView viewobject.

                      Well, if you don't want to connect this inside main, and don't want to path a reference/pointer around either, then I would go with the singleton.

                      btw, this is the only case where I would ever suggest a singleton :P


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      1 Reply Last reply
                      1
                      • B Offline
                        B Offline
                        beckseba
                        wrote on last edited by
                        #12

                        @J-Hilk Thank you, the singleton approach works very well.

                        I have created two functions *Messagging::instance()and *Messaging::qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine) and registered the second one as Singleton in my main file:

                        Messaging *Messaging::instance()
                        {
                             if (m_pThis == nullptr)
                             {
                                   m_pThis = new Messaging;
                             }
                             return m_pThis;
                        }
                        
                        QObject *Messaging::qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine)
                        {
                             Q_UNUSED(engine);
                             Q_UNUSED(scriptEngine);
                        
                             return Messaging::instance();
                        }
                        

                        Now, the same instance can be used in all other classes to edit variables and update GUI elements accordingly with e.g.

                        Messagging *messageService = Messagging::instance();
                        messageService->setMessageText("xyz");
                        
                        1 Reply Last reply
                        1

                        • Login

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