将QGLWidget仅使用插槽移动到不同的线程

时间:2013-07-18 11:11:36

标签: c++ multithreading qt opengl

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

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

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

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

在最近的一个项目中,我通过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 来实现内部包装。