2

我创建了一个具有主窗口的应用程序,并从该窗口创建了一个 QDialog。这个 QDialog 应该创建一个 RenderThread,它从相机发出接收到的图像,或者在示例中发出文本。当我调试它时,似乎永远不会建立连接,因为在插槽中添加断点CameraWindow::debugSomething不会被捕获。怎么了 ?我遵循了这个例子: http: //qt-project.org/doc/qt-4.8/threads-mandelbrot.html但似乎我做错了什么。

qtDEVC::qtDEVC(QWidget *parent, Qt::WFlags flags)
    : QMainWindow(parent, flags)
{
    ui.setupUi(this);
    connect (ui.pushButton_startCam, SIGNAL( clicked() ),this,SLOT( startCam() ) );

    /**Threading*/
    CameraWindow camWindow = new CameraWindow(this);
}


int qtDEVC::startCam()
{
    camWindow.show();
    camWindow.startCaptureThread();
}

相机窗口类:

 CameraWindow::CameraWindow(QWidget *parent)
        : QDialog(parent)
    {
    ui.setupUi(this);

    connect(&thread, SIGNAL(sendText(std::string)),
        this, SLOT(debugSomething(std::string)));
}

void CameraWindow::debugSomething(std::string something){
    QString somethings(something.c_str());
qDebug()<<somethings;
}

int CameraWindow::startCaptureThread(){

    RenderThread *thread = new RenderThread(this, guid, CLEYE_COLOR_RAW, CLEYE_VGA, 50); 

    thread->StartCapture(); //starts thread in low priority and sets _running to true
}

CameraWindow 标头

 class CameraWindow : public QDialog
 {
    Q_OBJECT

    public:
    CameraWindow(QWidget *parent = 0);
    ~CameraWindow();
    Ui::CameraWindow ui;

public slots:
    int startCaptureThread();
    void debugSomething(QString);

private:
    RenderThread thread;
};

渲染线程类

 void RenderThread::run()
 {

    // image capturing loop
    while(_running)
    {
    qDebug()<<("render while()"); //is printed with qdebug correctly
    if (restart)
        break;
           if (abort)
               return;

    qDebug("it");  //is also printed with qdebug correctly

    emit sendText(text);
}

渲染线程头

class RenderThread : public QThread
{
    Q_OBJECT

public:
    RenderThread(QObject *parent, GUID cameraGUID, CLEyeCameraColorMode mode, CLEyeCameraResolution resolution, float fps);
    RenderThread();
    ~RenderThread();

    bool StartCapture();

signals:

    void sendText(QString &text);

protected: 
    void run();

private:
    QMutex mutex;
    QWaitCondition condition;
    //some more private variables for construction

};

我认为这个创作似乎有些错误:RenderThread *thread = new RenderThread(this);

4

3 回答 3

1

这个问题首先担心的是“RenderThread”这个词。请注意,Qt 只允许在主线程上渲染。您可以创建单独的线程来计算图像数据,但无论何时使用画家和绘制对象,都必须在主线程上进行。但是,如果您只是要捕获图像并将其通过信号和插槽传递给主线程,那应该没问题。

其次,虽然您没有显示所有代码,但我从名为 RenderThread::run() 的函数和 Qt 示例中假设您可能从此处的 QThread 继承。如果是这种情况,请注意这不是如何使用 QThread。相反,您应该让您的类继承自 QObject 并将其移至 QThread。您可以在此处阅读有关如何正确使用 QThread 的信息

我知道这是您遵循的 Qt 示例,但即使是 Qt 的人也认为这是一个坏主意。这是一篇关于如何真正使用 QThreads 的文章。

考虑到这一点,以下是我将如何使用 QThread 的概述: -

class CameraWindow : public QDialog
{
    private:
      CameraObject* m_pCamObject;
};

class CameraObject : public QObject
{
    Q_OBJECT
    public:

    private slots:
         startCaptureThread();

    private:
};

int CameraWindow::startCaptureThread()
{
     m_pCamObject = new CameraObject;

     QThread* pThread = new QThread;

     this->moveToThread(pThread); // CameraObject will run on the new thread

     connect(pThread, SIGNAL(started()), m_pCamObject, SLOT(startCaptureThread()));
     connect(pThread, SIGNAL(finished()), pThread, SLOT(deleteLater()); // clear up when 

完成的

     pThread->start();
}

注意这里是一个CameraObject,与CameraWindow 分开。QThread 只是线程的控制器,并与 CameraObject 保持清晰的分离。

以这种方式处理线程的另一个原因是您可以将多个 QObject 实例移动到新线程,而不是总是为每个对象创建一个新线程。如果您的线程数多于 CPU 内核数,那么您不太可能通过创建另一个线程来获得收益。

于 2013-09-03T14:47:45.810 回答
0

在 CameraWindow 类的构造函数中,您连接的是 RenderThread 的信号,但它与 startCaptureThread 中启动的对象不同。像这样更改您的 startCaptureThread:

int CameraWindow::startCaptureThread()
{
    thread.StartCapture(); //starts thread in low priority and sets _running to true
}

在这个方法中,CameraWindow 的线程成员被启动。

PS:也发布标题,我们无法从该代码中看到成员。

于 2013-09-03T14:38:46.987 回答
-1

在上面提到的示例中,CameraWindowclass 包含一个RenderThread thread变量,而不是 a RenderThread *thread

您正在连接调用中连接指针地址:

connect(&thread, SIGNAL(sendText(std::string)),
    this, SLOT(debugSomething(std::string)));

尝试使用一个好的地址:

connect(thread, SIGNAL(sendText(std::string)),
    this, SLOT(debugSomething(std::string)));

这不是经过测试的答案。

于 2013-09-03T14:24:43.720 回答