将键盘事件发送给QML应用程序(Send keyboard event to QML application)

编程入门 行业动态 更新时间:2024-10-20 04:02:32
将键盘事件发送给QML应用程序(Send keyboard event to QML application)

我想从一个线程发送一个Qt :: Key_Left信号给我的应用程序。 我试图用以下代码发送我的事件,但没有任何反应: QKeyEvent *event = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier); QCoreApplication::sendEvent (app, pressEvent); 实际上,这些函数是从正在端口上侦听的线程中调用的。 这是否可能是由于这些函数没有从主线程调用而引起的?

我只是让你知道我的应用程序是在QML中(不知道它是否改变了某些东西)。 我也尝试过使用静态函数QCoreApplication::postEvent

先谢谢你。 对不起,我的英文水平。

I would like to send a Qt::Key_Left signal to my app from a thread. I tried to send my event with the following code but nothing happens : QKeyEvent *event = new QKeyEvent ( QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier); QCoreApplication::sendEvent (app, pressEvent); Actually, these functions are called from a thread that was listening on a port. Is that possible the problem is caused by the fact that these functions are not called from the main thread ?

I just let you know that my app is in QML (don't know if it changes something). I also tried with the static function QCoreApplication::postEvent

Thank you in advance. Sorry for my english level.

最满意答案

不,我没有,我也没有看到如何去做。 主线程忙于使用QGuiApplication :: exec

主线程没有真正锁定,每个事件循环周期之间有一段时间用于侦听来自其他线程的事件。

你可以使用QMetaObject::invokeMethod()或通过信号触发一个槽,在这两种情况下都使用Qt::QueuedConnection ,它将使用该监听窗口来调度在相关线程的下一个事件循环周期中执行的调用。

QCoreApplication::postEvent()应该可以工作,我使用它从QML中实现的自定义屏幕控制器发送事件,并且它工作正常,但QML确实存在于主线程中,因此推测您的问题是您从一个不同的线程。 所以我假设如果您安排事件通过主线程发送,它将按预期工作。

编辑:

好的,我想出了什么问题,出于某种原因,将事件发布到核心应用程序实例并不会将其转发给qml引擎和后续的qml对象。 但是,如果接收器设置为root engine->rootObjects().at(0)对象engine->rootObjects().at(0)它可以工作...有点...

通过Keys.onPressed和类似的方式接收焦点物品的事件,所以如果这就是你需要的一切,那么你已经设置好了。 奇怪的是,如果我使用类似于TextEdit东西,这种方法无法将文本写入字段,尽管使用箭头键来移动光标等效果确实有效。 我甚至可以按下shift修饰符并选择文字。 但不写文字...

所以也许它不像预期的那么简单。 希望有人能够阐明这个问题。 对我来说,这对于Qt来说太过典型了,通常很简单,显然逻辑上的事情最终不能按预期工作,或者完全不工作,因为一些奇怪的实现细节。

这是我使用的代码:

class Worker : public QObject { Q_OBJECT public slots: void forwardKeyEvent(int k) { sendKeyEvent(k); } signals: void sendKeyEvent(int k); }; class Controller : public QObject { Q_OBJECT public: Controller(QQmlApplicationEngine * e) : engine(e) { w = new Worker; t = new QThread; w->moveToThread(t); connect(this, SIGNAL(sendKeyEvent(int)), w, SLOT(forwardKeyEvent(int))); connect(w, SIGNAL(sendKeyEvent(int)), this, SLOT(receiveEvent(int))); t->start(); } public slots: void receiveEvent(int k) { QCoreApplication::postEvent(engine->rootObjects().at(0), new QKeyEvent(QEvent::KeyPress, (Qt::Key)k, Qt::NoModifier)); QCoreApplication::postEvent(engine->rootObjects().at(0), new QKeyEvent(QEvent::KeyRelease, (Qt::Key)k, Qt::NoModifier)); } private: Worker * w; QThread * t; QQmlApplicationEngine * engine; signals: void sendKeyEvent(int k); }; // QML side Column { TextEdit { width: 400 height: 200 Keys.onPressed: console.log("pressed ", event.key) Keys.onReleased: console.log("released ", event.key) } Row { Repeater { model: [Qt.Key_Left, Qt.Key_S, Qt.Key_Right] delegate: Rectangle { width: 50 height: 50 color: "red" Text { anchors.centerIn: parent text: modelData } MouseArea { anchors.fill: parent onClicked: Work.sendKeyEvent(modelData) // this is actually the worker controller } } } } }

它为了测试从QML到C ++控制器到另一个线程中的对象,然后回到发布事件的控制器,测试了线程间事件发布做了一些疯狂的事情。 它确实按预期工作 - 来自辅助线程的数据正确地发布到事件循环,但发布的事件无法按预期工作。

Actually the problem came from the system and the user, it is necessary to focus the windows on the system to make it work.

更多推荐

本文发布于:2023-07-31 01:52:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1340501.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:应用程序   发送给   键盘   事件   event

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!