Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Transmitting Values via UDP to change QML-UI doesn't work.



  • Hello Everybody!

    I'm currently trying to build up my first UDP-Server/Client, to send some Values which should change the Speedvalue of my SpeedOMeter-UI which I've created via 3D Studio. But it doesn't arrive at the UI.
    My Server asks in a loop for a QString value which he can transmit to my Client.

    Regarding to the Debugger, every value I transmit, arrives on Clientside.

    At Clientside, I'm converting the QString to an Integer and return it to my main.cpp, where it translates the variable to QML with viewer.rootContext()…

    There, the value (convertint) is connected with the speedvalue in my main.qml, which normally should change the Speed-Display to the transmitted speed. But it doesn't change anything.
    I've put in a Debug-Message in the Qml-Trigger to look, if the convertvalue is the value it should be. But it never changes.

    But as soon as I'm creating a normal Integer (like testvalue) as return-Value for readyRead() - it changes the value of the SpeedOMeter.

    Can you help me?

    ----- udp_client.h : -----

    #ifndef MYUDP_H
    #define MYUDP_H
    
    #include <QObject>
    #include <QUdpSocket>
    #include <QNetworkDatagram>
    
    
    class Client : public QObject
    {
        Q_OBJECT
    public:
    
        explicit Client(QObject *parent = nullptr);
    
        int convertint;
        QNetworkDatagram data;
    
        int testvalue;
    
    signals:
    
    public slots:
        int readyRead();
    
    
    private:
        QUdpSocket *socket;
    
    };
    
    #endif // MYUDP_H
    
    

    ----- udp_client.cpp -----

    #include "udp_client.h"
    #include <iostream>
    
    using namespace std;
    
    Client::Client(QObject *parent) : QObject(parent)
    {
        // create a QUDP socket
        socket = new QUdpSocket(this);
    
        socket->bind(QHostAddress::LocalHost, 1234);
    
        connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
    
        convertint = 0;
        data;
        testvalue = 50;
    
    }
    
    int Client::readyRead()
    {
        // when data comes in
        QByteArray buffer;
        buffer.resize(socket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;
    
        socket->readDatagram(buffer.data(), buffer.size(),
                             &sender, &senderPort);
    
        data = buffer;
        convertint = data.data().toInt();
    
        qDebug() << "Message from: " << sender.toString();
        qDebug() << "Message port: " << senderPort;
        qDebug() << "Message: " << buffer;
        qDebug() << "Message: " << convertint;
    
        return convertint;
    }
    
    

    ------- main.cpp --------

    #include <QtWidgets/QApplication>
    #include <QQuickView>
    #include <QSurfaceFormat>
    #include <Qt3DStudioRuntime2/q3dsruntimeglobal.h>
    #include <QVector3D>
    #include <QQmlContext>
    #include <QString>
    #include "udp_client.h"
    
    
    
    int main(int argc, char *argv[])
    {
        qputenv("QSG_INFO", "1");
    
        QApplication app(argc, argv);
    
        QSurfaceFormat::setDefaultFormat(Q3DS::surfaceFormat());
    
        int convertint;
    
        Client client;
    
        convertint = client.readyRead();
    
        QQuickView viewer;
        viewer.setSource(QUrl("qrc:/main.qml"));
        viewer.rootContext()->setContextProperty("konvertierungsint", convertint);
        viewer.setTitle(QStringLiteral("Integration of Qt3D Studio"));
        viewer.setResizeMode(QQuickView::SizeRootObjectToView);
        viewer.resize(1600, 800);
        viewer.show();
    
        return app.exec();
    
    }
    
    
    

  • Lifetime Qt Champion

    Hi,

    Your Client object should be the context property.

    It should provide provide that converted int as a Q_PROPERTY so you have all the signal and slots mechanism in place. Then in you QML code, you can bind that property to whatever GUI representation you want to have.



  • Thank you so much! It worked pretty well.
    Had to change a few things in the code, but now it finally works.

    Information for future Qt-Newbys like me:

    1. Use Q_Property in the Header. You don't need every part of the Q_Property Example. In my case, READ was enough.

    2. Don't call your SLOT function "readyRead()". Qt will get you in serious trouble because of the already existing SIGNAL function "readyRead()" of your socket.

    3. Like SGaist said, create your class in main.cpp (Client client in my case) and use it as context property in rootContext.
      Just like:

      viewer.rootContext()->setContextProperty("theclient", &client);
    

    theclient will be the Object, you can work with in QML.

    Important:

    Do NOT create a new Client Object in your QML. For example:

    Client{
    id: theclient
    }
    
    

    in combination with "Import client 1.0", this will get you in serious trouble, because Qml and C++ will create TWO DIFFERENT OBJECTS with DIFFERENT values.

    just use your (in rootContext() defined) Object in Qml ( in my case it would be "theclient") and you will get the same values like you're getting in C++.

    1. I had to use
    qmlRegisterType<Client>("client", 1, 0, "Client");
    

    in the main.cpp as well.
    To be honest, I'm still not quite sure why. But I works, sooo.. hell yeah.
    But make sure, that you write it BEFORE you create your viewer Object. Otherwise it probably won't work.



  • hi !

    @J_Weihele said in Transmitting Values via UDP to change QML-UI doesn't work.:

    UDP-Newbys

    it is not specific to UDP but Qt itself, it is the QML and C++ Integration , see an Overview of possibilities



  • @LeLev You're right. Also realized it when I read it the second time. Already changed it :).



  • @J_Weihele said in Transmitting Values via UDP to change QML-UI doesn't work.:

    It worked pretty well.

    if your issue is solved, please don't forget to mark your post as such! Thanks


Log in to reply