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. Keyboard key emulation from C++ to QML

Keyboard key emulation from C++ to QML

Scheduled Pinned Locked Moved Solved General and Desktop
qmlqkeyevent
6 Posts 2 Posters 4.1k 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.
  • RiteshPanchalR Offline
    RiteshPanchalR Offline
    RiteshPanchal
    wrote on last edited by RiteshPanchal
    #1

    I want to emulate keyboard key press event from C++ and that would affect in qml.

    In my application i need to operate GUI from keyboard and also from UART.
    I am using qml from GUI. and its working great with keyboard. But i want same gui functionalities from UART bytes reception (ex. UP/DOWN uart frame). My UART code works fine. But i am unable to find way to emulate QKeyEvent from C++ file.

    main.cpp

    int main(int argc, char **argv)
    {
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
    
        UART *uart = new UART(&engine);
        uart->UARTInit();
    
        engine.load(QUrl(QStringLiteral("qrc:///HomePage.qml")));
        engine.rootContext()->setContextProperty(QLatin1String("uart"), uart);
    
        return app.exec();
    }
    

    UART.cpp

    void UART::readRequest()
    {
            QKeyEvent key_press(QKeyEvent::KeyPress, Qt::Key_P, Qt::NoModifier);
            QCoreApplication::sendEvent(engine.rootObjects().first(), &key_press);
    }
    

    HomePage.qml

    ApplicationWindow {
        id: rootWindow
        width: Screen.width
        height: Screen.height
        visible: true
        visibility: Window.FullScreen
    
        Item {
            id: it
            focus: true
    
           .
           .
    
            Keys.onPressed: {
                switch(event.key) {
                case Qt.Key_P:
                    gstpipe.play()
                    videoview.visible = true
                    event.accepted = true;
                    break;
               }
          }
       }
    }
    

    so i am getting error in "QCoreApplication::sendEvent(engine.rootObjects().first(), &key_press);"
    error: 'engine' was not declared in this scope

    So how to correctly send QkeyEvent to QML?

    1 Reply Last reply
    0
    • RiteshPanchalR Offline
      RiteshPanchalR Offline
      RiteshPanchal
      wrote on last edited by RiteshPanchal
      #2

      I have found one solution for the error: 'engine' was not declared in this scope

      UART.h

      class UART : public QObject
      {
          Q_OBJECT
          QQmlApplicationEngine m_engine;
      public:
          explicit UART(QQmlApplicationEngine *engine, QObject *parent = 0);
      }
      

      UART.cpp

      UART::UART(QQmlApplicationEngine *engine, QObject *parent) :
          QObject(parent), m_engine(engine)
      {
      
      }
      void UART::readRequest()
      {
              QKeyEvent key_press(QKeyEvent::KeyPress, Qt::Key_P, Qt::NoModifier);
              QCoreApplication::sendEvent(m_engine.rootObjects().first(), &key_press);
      }
      

      Now i am not getting any error while building.
      But when UART request is received and QCoreApplication::sendEvent(m_engine.rootObjects().first(), &key_press); is executed i am getting following error.

      ASSERT: "!isEmpty()" in file /usr/include/qt5/QtCore/qlist.h, line 287
      The program has unexpectedly finished.
      

      So whats' the missing here?

      1 Reply Last reply
      0
      • sierdzioS Offline
        sierdzioS Offline
        sierdzio
        Moderators
        wrote on last edited by
        #3

        QQmlApplicationEngine is a QObject, so you are not allowed to copy it!

        So, it should help if you declared m_engine as pointer in your UART class:

        QQmlApplicationEngine *m_engine;
        

        And then called that pointer from your request:

        void UART::readRequest()
        {
                QKeyEvent key_press(QKeyEvent::KeyPress, Qt::Key_P, Qt::NoModifier);
                QCoreApplication::sendEvent(m_engine->rootObjects().first(), &key_press);
        }
        

        For more information about why QObjects can't be copied, see Qt docs.

        (Z(:^

        RiteshPanchalR 1 Reply Last reply
        1
        • sierdzioS sierdzio

          QQmlApplicationEngine is a QObject, so you are not allowed to copy it!

          So, it should help if you declared m_engine as pointer in your UART class:

          QQmlApplicationEngine *m_engine;
          

          And then called that pointer from your request:

          void UART::readRequest()
          {
                  QKeyEvent key_press(QKeyEvent::KeyPress, Qt::Key_P, Qt::NoModifier);
                  QCoreApplication::sendEvent(m_engine->rootObjects().first(), &key_press);
          }
          

          For more information about why QObjects can't be copied, see Qt docs.

          RiteshPanchalR Offline
          RiteshPanchalR Offline
          RiteshPanchal
          wrote on last edited by
          #4

          @sierdzio Thanks for the reply.
          But as i am new to Qt and all. I am asking this question.
          If i create new

          QQmlApplicationEngine *m_engine;
          

          pointer ? how can i refer it to my original

          QQmlApplicationEngine engine;
          

          And i need to pass keyevent to engine .

          1 Reply Last reply
          0
          • sierdzioS Offline
            sierdzioS Offline
            sierdzio
            Moderators
            wrote on last edited by
            #5

            No, no, you do not need to change anything in your main.cpp, the engine can still be created on stack there.

            QQmlApplicationEngine engine;
            /// ...
            UART *uart = new UART(&engine); // here you pass a reference (pointer) to your UART class - everything is fine
            

            Just changing the UART class as I indicated in my previous post should be enough.

            (Z(:^

            1 Reply Last reply
            0
            • RiteshPanchalR Offline
              RiteshPanchalR Offline
              RiteshPanchal
              wrote on last edited by
              #6

              Thanks for the Reply.
              I get everything working from below changes.

              UART.cpp

              UART::UART(QObject *parent) :
                  QObject(parent)
              {
                  m_engine = (QQmlApplicationEngine *)parent;
              }
              
              void UART::readRequest()
              {
                      QKeyEvent key_press(QKeyEvent::KeyPress, Qt::Key_P, Qt::NoModifier);
                      QCoreApplication::sendEvent(m_engine->rootObjects().first(), &key_press);
              }
              

              UART.h

              class UART : public QObject
              {
                  Q_OBJECT
              
              public:
                  explicit UART(QObject *parent = 0);
              
              signals:
              
              protected:
              
              public slots:
                  void UARTInit();
              
              private:
                  QQmlApplicationEngine *m_engine;
              
              private slots:
                  void readRequest();
              
              };
              

              And main.cpp without any change as per your previous reply.

              Thanks ... :)

              1 Reply Last reply
              1

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved