gpt4 book ai didi

c++ - 向 QML 应用程序发送键盘事件

转载 作者:行者123 更新时间:2023-11-30 05:05:18 25 4
gpt4 key购买 nike


我想从一个线程向我的应用程序发送一个 Qt::Key_Left 信号。
我尝试使用以下代码发送我的事件,但没有任何反应:
QKeyEvent *event = new QKeyEvent (QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier);
QCoreApplication::sendEvent (app, pressEvent);


实际上,这些函数是从监听端口的线程调用的。问题是否可能是由于这些函数不是从主线程调用引起的?

我只是让你知道我的应用程序是在 QML 中(不知道它是否改变了什么)。我还尝试使用静态函数 QCoreApplication::postEvent

提前致谢。对不起我的英语水平。

最佳答案

No, I didn't and I don't see how to do it. The main thread is busy with QGuiApplication::exec

主线程并没有真正锁定,在每个事件循环周期之间有一个时间段,它会监听来自其他线程的事件。

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

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

编辑:

好的,我知道出了什么问题,出于某种原因,将事件发布到核心应用程序实例不会将其转发到 qml 引擎和后续的 qml 对象。但是如果接收器设置为根 qml 对象 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++ Controller 再到另一个线程中的对象,然后返回到 Controller 然后发布事件。它确实按预期工作 - 来自辅助线程的数据已正确发布到事件循环,但发布的事件未按预期工作。

关于c++ - 向 QML 应用程序发送键盘事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48459492/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com