Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Italian
  4. QML e UDP Socket
QtWS25 Last Chance

QML e UDP Socket

Scheduled Pinned Locked Moved Unsolved Italian
5 Posts 2 Posters 2.0k 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 Offline
    B Offline
    bilbo69
    wrote on last edited by
    #1

    Buongiorno a tutti,
    qualcuno ha mai avuto l'esigenza di ricevere (o inviare) pacchetti UDP all'interno di un'applicazione QML/JavaScript in Android?

    Da una prima ricerca fatta (https://forum.qt.io/topic/87143/udp-and-tcp-sockets-with-qml) sembrerebbero esserci due strade: integrazione QML/C++ o Libreria esterna.
    Ho provato a scaricare la libreria ma non sono riuscito a utilizzarla (non ci sono istruzioni). Nei commenti nella pagina GitHub sembrerebbe però che la libreria non funziona su Android (sarà vero...?)

    Per la seconda strada, il link presente nel post (http://doc.qt.io/qt-5/qtqml-cppintegration-topic.html) c'è un esempio di integrazione QML/C++ ma si tratta di un'interazione semplice. In questo caso ci dovrebbe essere, dal lato C++, qualcosa in ascolto continuo sulla porta UDP e, in caso di dato ricevuto, dovrebbe trasferirlo dal lato QML.
    Qualcuno ha mai avuto un'esigenza simile?
    Grazie

    1 Reply Last reply
    0
    • mrdebugM Offline
      mrdebugM Offline
      mrdebug
      wrote on last edited by
      #2

      QML/C++, non usare librerie esterne per una cosa così semplice.
      Io ad esempio ho un'app che in fase di avvio cerca i dispositivi mandando in broadcast un pacchetto udp e poi mostra a video ciò che trova.
      Non pensare sia difficile.

      Ciao ciao.

      Need programmers to hire?
      www.labcsp.com
      www.denisgottardello.it
      GMT+1
      Skype: mrdebug

      B 1 Reply Last reply
      2
      • mrdebugM mrdebug

        QML/C++, non usare librerie esterne per una cosa così semplice.
        Io ad esempio ho un'app che in fase di avvio cerca i dispositivi mandando in broadcast un pacchetto udp e poi mostra a video ciò che trova.
        Non pensare sia difficile.

        Ciao ciao.

        B Offline
        B Offline
        bilbo69
        wrote on last edited by
        #3

        grazie @mrdebug !

        Ho trovato un esempio che allego. In effetti dal lato c++ si apre una porta UDP in ascolto. Alla ricezione di un dato però invia al "lato QML" un evento di tasto premuto (almeno così mi sembra) che viene riconosciuto dall'evento Keys.OnPressed.
        Se invece volessi passare al QML semplicemente i dati ricevuti come dovrebbe essere modificato il codice? oppure chiedo se qualche utente ha un esempio semplice adatto allo scopo.

        (main.cpp)

        #include <QGuiApplication>
        #include <QQmlApplicationEngine>
        #include <QQmlApplicationEngine>
        #include <QKeyEvent>
        #include <QUdpSocket>
        #include <QTimer>
        #include <QDebug>
        #include <QWindow>
        #include <QObject>
        #include <QUrl>
        #include <QString>
        #include <QVariant>
        
        #include <QQmlContext>
        #include <QByteArray>
        #include <QHostAddress>
        QQmlApplicationEngine * engine;
        
        
        class Listener : public QUdpSocket
        {
            Q_OBJECT
            public:
            Listener(QObject *parent = 0): QUdpSocket(parent)
            {
                bind(1129);
                qDebug() << "Started Listener";
                connect(this, SIGNAL(readyRead()), this, SLOT(readDatagram()));
            }
        
            private slots:
            void readDatagram()
            {
                QByteArray datagram;
                datagram.resize(QUdpSocket::pendingDatagramSize());
                QUdpSocket::readDatagram(datagram.data(), datagram.size());
        
                //processTheDatagram(datagram);
                int key = QString::fromUtf8(datagram.data()).toInt();
                qDebug() << "Key: " << QString::number(key);
        
                QKeyEvent* keyP = new QKeyEvent(QEvent::KeyPress,key,Qt::NoModifier);
                QKeyEvent* keyR = new QKeyEvent(QEvent::KeyRelease,key,Qt::NoModifier);
                QCoreApplication::sendEvent(engine->rootObjects().first(), keyP);
                QCoreApplication::sendEvent(engine->rootObjects().first(), keyR);
            }
        };
        
        int main(int argc, char *argv[])
        {
            QGuiApplication app(argc, argv);
            engine = new QQmlApplicationEngine;
        
            engine->load(QUrl(QStringLiteral("qrc:///main.qml")));
            Listener l;
            return app.exec();
        }
        
        #include "main.moc"
        
        

        (main.qml)

        import QtQuick 2.9
        import QtQuick.Window 2.2
        import QtQuick.Controls 1.1
        import QtQuick.Layouts 1.1
        
        ApplicationWindow
        {
            visible: true
            width: 1024
            height: 768
        
            Rectangle
            {
                id:zzMain
                visible: true
                width: 1024
                height: 768
                color: "#56555b"
        
                property string source1: ""
                property string source2
                property color bgColor: "#002244"
                property real volume: 0.25
                property string backto: "mainmenu.qml"
        
                RowLayout
                {
        
                    id: layout
                    anchors.fill: parent
                    spacing: 6
        
                    Item
                    {
                        id: header1
                        width: parent.width
                        height: 135
                        anchors.top: parent.top
        
                        Loader
                        {
                            id: headerLoader
                            anchors.fill: parent
                            source: "header.qml"
                        }
                    }
        
        
                    Item
                    {
                        anchors.leftMargin: 10
                        anchors.rightMargin: 10
                        anchors.topMargin: 10
                        anchors.left: parent.left
                        anchors.top: header1.bottom
                        width: parent.width
                        height: parent.height - 10 - header1.height
        
                        Loader
                        {
                            id: sceneLoader
                            focus:true
                            anchors.fill: parent
                            source: "mainmenu.qml"
                        }
                    }
        
                    Keys.onPressed:
                    {
                        console.log('Key A was pressed');
                        event.accepted = true
                    }
                    Keys.onReleased:
                    {
                        console.log('Key A was released: ' + event.key);
                        event.accepted = true
                    }
        
                    function closeScene()
                    {
                        console.log("[qmlvideo] main.closeScene")
                        console.log("[qmlvideo] main.closeScene->Going to:" + zzMain.backto)
                        sceneLoader.source = zzMain.backto
                    }
                }
            }
        }
        
        
        1 Reply Last reply
        0
        • mrdebugM Offline
          mrdebugM Offline
          mrdebug
          wrote on last edited by
          #4

          Per comunicare cpp verso qml, in cpp devi emettere un evento, ad esempio

          void sendLog(QString Log);
          

          lato qml impllementi la connection, ad esempio

              Connections {
                  target: QCMainClass
                  onSendLog: sendLog(Log)
              }
          
              ...
          
              function sendLog(Log) {
                  console.log(Log)
              }
          

          Need programmers to hire?
          www.labcsp.com
          www.denisgottardello.it
          GMT+1
          Skype: mrdebug

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

            Grazie mrdebug,
            sono arrivato ad un risultato.
            Posto il codice a beneficio di tutti gli utenti, anche se c'è un'ultima cosa che non torna.

            1. MAIN.CPP
            #include <QGuiApplication>
            #include <QQmlApplicationEngine>
            
            #include "myudp.h"
            
            int main(int argc, char *argv[])
            {
            
                QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
            
                QGuiApplication app(argc, argv);
            
                qmlRegisterType<MyUDP>("MyUDP", 1, 0, "MyUDP");
            
                QQmlApplicationEngine engine;
            
                engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
            
                if (engine.rootObjects().isEmpty())
                    return -1;
            
                return app.exec();
            
            }
            
            

            MYUDP.H

            #ifndef MYUDP_H
            #define MYUDP_H
            
            #include <QObject>
            #include <QUdpSocket>
            
            class MyUDP : public QObject
            {
                Q_OBJECT
                Q_PROPERTY(QByteArray type READ type WRITE setType NOTIFY typeChanged)
            
            public:
                explicit MyUDP(QObject *parent = 0);
                void SayHello();
            
                QByteArray type();
                void setType(const QByteArray &t);
            
            signals:
                void typeChanged();
            
            public slots:
                void readyRead();
            
            private:
                QUdpSocket *socket;
                QByteArray _type;
            };
            
            #endif // MYUDP_H
            

            MYUDP.C

            #include "myudp.h"
            
            MyUDP::MyUDP(QObject *parent) : QObject(parent)
            {
                socket = new QUdpSocket(this);
                socket->bind(1129, QUdpSocket::ShareAddress);
                connect(socket,SIGNAL(readyRead()),this, SLOT(readyRead()));
            }
            
            // send message in client mode
            void MyUDP::SayHello()
            {
                QByteArray Data;
                Data.append("test message");
                socket->writeDatagram(Data,QHostAddress::LocalHost,5824);
            }
            
            void MyUDP::readyRead()
            {
                QByteArray Buffer;
                Buffer.resize(socket->pendingDatagramSize());;
            
                QHostAddress sender;
                quint16 senderPort;
            
                socket->readDatagram(Buffer.data(),Buffer.size(), &sender, &senderPort);
                qDebug()<< "Message size:" << Buffer.size();
                setType(Buffer);
            }
            
            QByteArray MyUDP::type()
            {
                return _type;
            }
            
            void MyUDP::setType(const QByteArray &t)
            {
                _type = t;
                emit typeChanged();
            }
            
            

            MAIN.QML

            import QtQuick 2.0
            import QtQuick.Controls 2.2
            
            import "main.js" as SpkScript
            import MyUDP 1.0
            
            ApplicationWindow
            {
                id: window
                visible: true
            
                title: qsTr("AESA.Monitor")
                MyUDP
                {
                    id:myUdp
                    onTypeChanged:
                    {
                        console.log("[QML]Msg:" + type)
                    }
                }
            }
            
            

            L'esempio funziona in ricezione. Il pacchetto ricevuto è contenuto in "type" (lato QML).
            Se si fa una console.log(typeof type) il risultato è "object".

            Se si ricevono caratteri stampabili va tutto bene. Ho provato il codice seguente che trasforma type in stringa permettendo l'uso di tutte le funzioni relative:

                var m=type.toString();
                if(m.slice(0,4)==="col=")
                {
                        ecc.ecc...
            

            il problema (nel mio caso) è che ricevo dati binari, per cui la conversione a stringa non funziona più bene (al primo carattere non stampabile la stringa si interrompe).

            Ho provato a ricavare i singoli byte dalla variabile type ma senza successo:
            type[0] ritorna "not defined"
            type.charCodeAt(0) non funziona (non è una stringa)
            ci vorrebbe una conversione ad array ma non so come fare.

            grazie per tutti i suggerimenti
            ciao

            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