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

Move QGLWidget with only slots to different thread

本文关键字:线程 移动 QGLWidget 插槽      更新时间:2023-10-16

我有一个QT程序,它从Kinect接收QBytearray,然后在QGLWidget中将它们处理为屏幕上的可见图像。这个QGLWidget在GUI线程中运行,就像GUI的其他部分一样。激发Kinect图像的类在另一个线程中运行。所有的混合都是通过信号和时隙来完成的。

有时GUI线程会锁定,然后OpenGLWidget也会锁定,我想解决这个问题。要做到这一点,我需要一个QT插槽在不同的线程中运行,然后运行GUI的其余部分。我知道这是可能的,但我看到的所有例子都使用run方法,它在不同的线程中开始,然后自己运行。

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

在最近的一个项目中,我通过剃掉一些牦牛来"解决"这个问题,呃,写一些路由包装器。

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的内部包装实现了这一点。

您可以创建助手类并将逻辑移动到那里。所以Widget类将在主线程中,它应该发出信号,这些信号将在另一个线程中的helper类中处理。