Updating data model for QML while already displaying view



  • Hi,

    I have a project designed to display information coming in about vehicle status. I use a carData object to store the information about the car. Right now, it is implemented like this:
    @
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    MainWindow w;
    carData *data = new carData();
    w.rootContext()->setContextProperty("data", data);
    w.show();
    return a.exec();
    }
    @

    However, information on car status is obviously constantly changing, so I want to update the carData object every second or so to reflect the most current data on the car. I can write an update method that will reset the contents of the carData object, but I am wondering how I will be able to do this once w.show() or a.exec() has been called. How can I continuosuly update the object being displayed while the display is already running?



  • Don't do that!
    Please refer to property binding in QML.
    "http://doc-snapshot.qt-project.org/4.8/propertybinding.html":http://doc-snapshot.qt-project.org/4.8/propertybinding.html

    You just need a property with notification.



  • if your model is derived from "QAbstractItemModel":http://doc-snapshot.qt-project.org/4.8/qabstractitemmodel.html it should work too



  • [quote author="diro" date="1342070833"]Don't do that!
    Please refer to property binding in QML.
    "http://doc-snapshot.qt-project.org/4.8/propertybinding.html":http://doc-snapshot.qt-project.org/4.8/propertybinding.html

    You just need a property with notification.[/quote]

    He already knew that, because that was "discussed":/forums/viewthread/18649/ earlier, right?



  • I understand that what is being displayed on the screen is going to be updated when the carData object changes, and that this can be accomplished using properties. Thanks to Andre and Chriadam for clarifying that for me. What I was interested in, was how I would be able to continuously update the carData object, since information must be updated when it is received from the car every second or so. I don't think I can use something like an update method because a.exec() has already been called to start the program running, and I assume that a.exec is running until you close the application window, making any c++ calls in main irrelevant while the program is running. So, I think that I will look into QAbstractItemModel, and maybe changing the get functions for properties to return data from the ip address of the car instead of a private variable.



  • I really don't get the question. While your application is running, any call after the app.exec() call in the main() is indeed not executed yet. exec() is blocking after all. However, in the code above, you have plenty of oppurtunity to setup some form of polling system, or otherwise connect to some service that provides the actual values. However, you don't us where you are supposed to get the values from, so we cannot comment on that part of your design.

    One simple way would be to use a polling system driver by a simple timer. You can start such a system before you reach your QApplication::exec() call. It would however be preferable if you can do without polling.



  • I am going to be getting the values by communicating with a system over ethernet, so essentially by interacting with an IP. I will look into polling systems and a way to connect to the service. Thank you for your suggestions.



  • Ok, if you're communicating over ethernet (I assume UDP or TCP), then you don't even need polling. You simply use a [[doc:QTcpSocket]] in case of a TCP connection. You don't need polling, as the socket will use signals to notify you of new incoming data.



  • Hey, so the QTcpSocket works great to get all the data I need, and continue to get data while the display is up and running, but I am having a bit of trouble displaying the data once I have read it in and stored it in a map. When I try to display the data in the QML, it simply displays zero, despite the fact that I can see it updating in the application output.
    In my data class I have:
    @
    Q_PROPERTY(int headingSensor READ getHeadingSensor NOTIFY headingSensorChanged)
    int headingSensor;
    @
    In the c++ implementation I originally had:
    @
    int data::getHeadingSensor(){
    return data.value(heading)[headingSensorReading];
    }
    @
    Where it returns the value in the map which is being updated with the incoming information. This I realized, probably doesn't work, because the property is dependent upon the headingSensor variable, which is itself not being updated despite the correct value being returned. So, I thought if I changed it to update the headingSensor value and return that it might work. So in my data aquisition logic I wrote a method to update the variables as well.
    @
    data.insert(key, value);
    updateVariables();
    }
    }
    }
    void data::updateVariables(){
    headingSensor = data.value(heading)[headingSensorReading];
    }
    int data::getHeadingSensor(){
    return headingSensor;
    }
    @
    While this led to the headingSensor variable being updated in addition to the value in the map, the correct value is still not displayed in the QML display. It simply displays 0 (its default value when it is initially displayed since it has not gotten a value from incoming data yet).

    EDIT:
    Nevermind, I am a fool! I was so used to writing elements that had getters and setters (which emitted the Changed signal), that when I was writing this where the socket updates the information, I did not think to put in the emit signal.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.