将只有插槽的 QGLWidget 移动到不同的线程

Posted

技术标签:

【中文标题】将只有插槽的 QGLWidget 移动到不同的线程【英文标题】:Move QGLWidget with only slots to different thread 【发布时间】:2013-07-18 11:11:35 【问题描述】:

我有一个 QT 程序,它从 Kinect 接收 QBytearray,然后将它们处理为 QGLWidget 中屏幕上的可见图像。这个 QGLWidget 在 GUI 线程中运行,就像 GUI 的其余部分一样。触发 Kinect 图像的类在不同的线程中运行。所有粉碎都是通过信号和槽完成的。

有时 GUI 线程会锁定,然后 OpenGLWidget 也会锁定,我想修复它。为此,我需要一个 QT Slot 在与 GUI 的其余部分不同的线程中运行。我知道这是可能的,但我看到的所有示例都使用 run 方法,它在不同的线程中启动,然后自行运行。

但是我使用一个插槽来接收图像,这意味着它不会一直运行,但只有当有图像可用于渲染时才会运行。我可以创建一个线程并将这个槽放在线程中吗?

【问题讨论】:

【参考方案1】:

在最近的一个项目中,我通过shaving some yaks“解决”了这个问题,错误,写了一些路由包装器。

class FooClass : public QThread

Q_OBJECT

  /* ... */

public slots:
/* to thread loopback signals */
void setBufferCount(
    unsigned int buffercount ) 
        QMetaObject::invokeMethod(this, "_priv_loslot_setBufferCount",
            Qt::QueuedConnection,
            Q_ARG(unsigned int, buffercount) ); 
    

private slots:
/*
 * private loopback slots
 * ^^^^    ^^       ^^^^
 *
 * These slots are connected to the coresponding frontend
 * signals. Calling a frontend signal will send a invocation
 * between the threads, calling the loopback slots within
 * the worker thread.
 */
void _priv_loslot_setBufferCount(unsigned int buffercount);

  /* ... */

通过调用或连接到公共插槽,通过在 Qt::QueuedConnection 上调用 invokeMethod 进行内部包装就可以了。

【讨论】:

【参考方案2】:

您可以创建辅助类并将您的逻辑移到那里。所以你的 Widget 类将在主线程中,它应该发出信号,这些信号将在不同线程的帮助类中处理。

【讨论】:

以上是关于将只有插槽的 QGLWidget 移动到不同的线程的主要内容,如果未能解决你的问题,请参考以下文章

如何将信号连接到不同线程中的插槽

QGLWidget 最大尺寸

两个不同类别的信号和插槽

Qt 插槽同时断开连接并从不同线程调用

插槽在哪个线程中执行,我可以将其重定向到另一个线程吗?

QGLWidget::renderText() 创建一些向下移动的字母