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. C++ Integration with QML, getting SendEvents working after a socket.readready() signal, and processing the data.
Forum Updated to NodeBB v4.3 + New Features

C++ Integration with QML, getting SendEvents working after a socket.readready() signal, and processing the data.

Scheduled Pinned Locked Moved QML and Qt Quick
12 Posts 2 Posters 3.8k Views 1 Watching
  • 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
    jonlmailstrain.com
    wrote on last edited by
    #1

    I am trying to send events from c++ once I have received a UDP Datagram, I have a viewer showing my qml (viewer) that I need to send key press events to after these datagrams are processed.

    The problem is that I can not get the send events to send to the viewer. If I send events from the main program it works great, but not from after the ready read signal and reading of datagrams.

    I could use a bit of help here, maybe there is a simple fix for this, but it seems silly that you can't send events into the viewer like this.
    I have tried: These all are implemented after the signal(ReadyRead()) and processed
    QCoreApplication::sendEvent(viewer,KeyPress);
    viewer->sendEvent(viewer->rootObject(),KeyPress);
    --and many others nothing seems to work.

    Please Help!

    1 Reply Last reply
    0
    • jeremy_kJ Offline
      jeremy_kJ Offline
      jeremy_k
      wrote on last edited by
      #2

      Does something in the viewer that should respond have active focus?

      Asking a question about code? http://eel.is/iso-c++/testcase/

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jonlmailstrain.com
        wrote on last edited by
        #3

        Yes it has focus, because prior to sendEvent after the datagram, I send several after the viewer is started using a timer object, these work just fine.

        1 Reply Last reply
        0
        • jeremy_kJ Offline
          jeremy_kJ Offline
          jeremy_k
          wrote on last edited by
          #4

          This works for me, as long as the window has focus from the window manager.

          main.cpp
          @
          #include <QGuiApplication>
          #include <QQmlApplicationEngine>
          #include <QKeyEvent>
          #include <QUdpSocket>
          #include <QTimer>
          #include <QDebug>
          #include <QWindow>

          QQmlApplicationEngine * engine;

          class Listener : public QUdpSocket
          {
          Q_OBJECT
          public:
          Listener(QObject *parent = 0): QUdpSocket(parent)
          {
          bind(22222);
          connect(this, SIGNAL(readyRead()), this, SLOT(readDatagram()));
          }
          private slots:
          void readDatagram()
          {
          QUdpSocket::readDatagram(0, 0);
          QKeyEvent kp(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "0");
          QCoreApplication::sendEvent(engine->rootObjects().first(), &kp);
          }
          };

          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&#40;&#41;;
          

          }

          #include "main.moc"
          @

          main.qml
          @
          import QtQuick 2.2
          import QtQuick.Window 2.1

          Window {
          visible: true
          width: 360
          height: 360

          TextInput {
              text: qsTr("Hello World")
              anchors.centerIn: parent
              focus: true
          }
          

          }
          @

          Asking a question about code? http://eel.is/iso-c++/testcase/

          1 Reply Last reply
          0
          • J Offline
            J Offline
            jonlmailstrain.com
            wrote on last edited by
            #5

            I Tried This and I get: Synbol(s) not Found when trying to build

            @#include <QApplication>
            #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(7755);
            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[])
            {
            QApplication app(argc, argv);
            engine = new QQmlApplicationEngine;

            engine->load(QUrl(QStringLiteral("qrc:///main.qml")));
            Listener l;
            return app.exec&#40;&#41;;
            

            }
            @
            main.qml
            @
            import QtQuick 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'&#41;;
                                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
            • jeremy_kJ Offline
              jeremy_kJ Offline
              jeremy_k
              wrote on last edited by
              #6

              Please be more specific about which symbols are missing.

              It's useful to eliminate anything not related to the problem at hand. For example, the type zzScreen is referenced but not defined. This might mean that it isn't relevant. Leaving it in the example adds noise, without providing the ability to try the code. The content of main.qml likely is relevant, but is missing and as such unusable. Feel free to reference code earlier in the thread instead of retyping if that is the intention.

              Asking a question about code? http://eel.is/iso-c++/testcase/

              1 Reply Last reply
              0
              • J Offline
                J Offline
                jonlmailstrain.com
                wrote on last edited by
                #7

                I update the code to inlude everything, and removed the screens element as it was not necessary. You can always substitute another QML for the main menu.qml as it is only a grid item.

                1 Reply Last reply
                0
                • jeremy_kJ Offline
                  jeremy_kJ Offline
                  jeremy_k
                  wrote on last edited by
                  #8

                  By any chance are the missing symbols related to Listener?
                  undefined reference to `vtable for Listener

                  At the end of my main.cpp example, there's a #include "main.moc". The code highlighting for #include statements makes it easy to overlook in my opinion. This #include causes qmake to generate a moc rule which will catch the Listener class, despite the lack of a definition of the class in a header file.

                  I don't see this include statement in the main.cpp you provided. If so, add it and re-run qmake (or cmake, qbs, ...).

                  Adding that, your code works for me with x86_64 Linux using xcb if the window has focus. I didn't need to implement mainmenu.qml and header.qml.

                  Asking a question about code? http://eel.is/iso-c++/testcase/

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    jonlmailstrain.com
                    wrote on last edited by
                    #9

                    That was it for the building of the project, it builds not, but the qml does not see the keyevents..

                    1 Reply Last reply
                    0
                    • jeremy_kJ Offline
                      jeremy_kJ Offline
                      jeremy_k
                      wrote on last edited by
                      #10

                      I should add that I've tried it with 5.3.0 and 5.2.1. What platform are you using? I only have access to Linux with xcb, but maybe someone else knows how to get this to work for your platform.

                      Are you by any chance switching away to another window to send the UDP packet that triggers the events? If so, that won't work.

                      It's also worth considering whether key events are the best tool for what you're trying to accomplish. Is a signal, property change, or a direct function call more appropriate? With key events, the application has to deal with changing focus and potential conflicts from a user pressing buttons on a physical keyboard.

                      Asking a question about code? http://eel.is/iso-c++/testcase/

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        jonlmailstrain.com
                        wrote on last edited by
                        #11

                        You were right, and I was being stupid :) I was trying to use the same machine with the remote. i know better than that, but sometimes you just can't see it. Thank you so much!

                        1 Reply Last reply
                        0
                        • jeremy_kJ Offline
                          jeremy_kJ Offline
                          jeremy_k
                          wrote on last edited by
                          #12

                          Input handling can be pretty confusing, for developers and users.

                          Asking a question about code? http://eel.is/iso-c++/testcase/

                          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