Keyboard key emulation from C++ to QML
-
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 scopeSo how to correctly send QkeyEvent to QML?
-
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?
-
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.
-
@sierdzio Thanks for the reply.
But as i am new to Qt and all. I am asking this question.
If i create newQQmlApplicationEngine *m_engine;
pointer ? how can i refer it to my original
QQmlApplicationEngine engine;
And i need to pass keyevent to engine .
-
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.
-
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 ... :)