Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Transmitting Values via UDP to change QML-UI doesn't work.

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

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 4 Posters 370 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.
  • J Offline
    J Offline
    J_Weihele
    wrote on last edited by J_Weihele
    #1

    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();
    
    }
    
    
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      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.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      2
      • J Offline
        J Offline
        J_Weihele
        wrote on last edited by J_Weihele
        #3

        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.

        ODБOïO Pablo J. RoginaP 2 Replies Last reply
        1
        • J J_Weihele

          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.

          ODБOïO Offline
          ODБOïO Offline
          ODБOï
          wrote on last edited by
          #4

          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

          1 Reply Last reply
          2
          • J Offline
            J Offline
            J_Weihele
            wrote on last edited by
            #5

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

            1 Reply Last reply
            0
            • J J_Weihele

              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.

              Pablo J. RoginaP Offline
              Pablo J. RoginaP Offline
              Pablo J. Rogina
              wrote on last edited by
              #6

              @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

              Upvote the answer(s) that helped you solve the issue
              Use "Topic Tools" button to mark your post as Solved
              Add screenshots via postimage.org
              Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

              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