【发布时间】:2015-07-31 03:30:27
【问题描述】:
我的应用正在等待线程完成。当线程完成它的事情时,我想更新 GUI。 GUI 线程在 xcb_wait_for_event() 中被阻塞。
XCB 可以做到这一点吗? Qt、GTK、FLTK 等如何在 XCB API 方面实现这个基本的 GUI 问题?
【问题讨论】:
我的应用正在等待线程完成。当线程完成它的事情时,我想更新 GUI。 GUI 线程在 xcb_wait_for_event() 中被阻塞。
XCB 可以做到这一点吗? Qt、GTK、FLTK 等如何在 XCB API 方面实现这个基本的 GUI 问题?
【问题讨论】:
在 Qt 中,您应该将线程发出的(排队的)信号连接到 GUI 线程对象上的插槽。插槽调用然后由事件循环处理,就像来自例如的自发事件一样。用户输入。
来自Maya Posch's excellent article on using QThread:
class Worker : public QObject {
Q_OBJECT
public:
Worker();
~Worker();
public slots:
void process();
signals:
void finished();
void error(QString err);
private:
// add your variables here
};
void Worker::process() {
// allocate resources using new here
qDebug("Hello World!");
emit finished();
}
在 GUI 线程中:
QThread* thread = new QThread;
Worker* worker = new Worker();
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
你感兴趣的线路是
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
现在去阅读How To Really, Truly Use QThreads; The Full Explanation。
【讨论】:
它在 Qt 中的工作方式似乎是 xcb_wait_for_event() 在它自己的线程中重复运行。每次它接收到一个事件,它都会在QApplication 的共享消息队列上发布一条消息。用户线程还可以通过排队信号将消息添加到QApplication 的共享消息队列中(请参阅我的其他答案)。
用户应用程序现在可以从共享消息队列中读取事件(例如,使用qApp->exec())并接收自发的 UI 事件和来自其他线程的内部信号的混合。
如需更多阅读,我建议使用 Qt5 资源,以 src/plugins/platforms/xcb/qxcbconnection.cpp 开头 - 查看 QXcbEventReader::run。
【讨论】:
stackoverflow.com/questions/8794089/how-to-send-key-event-to-application-using-xcb
注意潜在安全性的警告,以及使用 xtest 避免它的方法。我想知道你是否愿意等待一个信号?它们并不像外行人认为的那样可怕和神秘。 Michael Kerrisk 有一本很棒的书:The Linux Programming Interface A Linux and UNIX System Programming Handbook 对此进行了解释。
【讨论】: