如何使用QThread从后台工作线程中的Qt GUI调用方法

时间:2014-04-22 10:06:35

标签: c++ qt qthread

我正在尝试在我的GUI中添加来自vrpn服务器的Qt代码接收数据。当我收到一些信息时,我需要不断地从这个服务器向应用程序发送数据并在界面中调用动作(方法)。

但我对无尽的循环while (running)有疑问。我发现解决方案是使用QThread从服务器接收数据,但是当我从服务器收到一些数据时,我无法弄清楚如何在工作人员中使用QT类的方法。

我尝试以这种方式创建工作者,但我不确定,当我从服务器接收一些数据时(或者如果它完全可能/或存在更好的方式),如何从另一个类调用方法:

#include "Worker.h"

#include <iostream>
#include "vrpn_Analog.h"


void VRPN_CALLBACK vrpn_analog_callback(void* user_data, vrpn_ANALOGCB analog)
{
    for (int i = 0; i < analog.num_channel; i++)
    {
        if (analog.channel[i] > 0)
        {                   
            THERE I WANT CALL METHOD nextImage(), which I have in QT class mainwindow
        }

    }
}

// --- CONSTRUCTOR ---
Worker::Worker() {

}

// --- DECONSTRUCTOR ---
Worker::~Worker() {

}

// --- PROCESS ---
// Start processing data.
void Worker::process() {

    /* flag used to stop the program execution */
    bool running = true;

    /* VRPN Analog object */
    vrpn_Analog_Remote* VRPNAnalog;

    /* Binding of the VRPN Analog to a callback */
    VRPNAnalog = new vrpn_Analog_Remote("openvibe_vrpn_analog@localhost");
    VRPNAnalog->register_change_handler(NULL, vrpn_analog_callback);

    /* The main loop of the program, each VRPN object must be called in order to process data */
    while (running)
    {
        VRPNAnalog->mainloop();
    }
}

我是使用QT的新手,所以我会感激任何帮助。

2 个答案:

答案 0 :(得分:1)

向Worker添加信号callback并将指针传递给寄存器函数(将作为user_data传递)。

void VRPN_CALLBACK vrpn_analog_callback(void* user_data, vrpn_ANALOGCB analog)
{
    for (int i = 0; i < analog.num_channel; i++)
    {
        if (analog.channel[i] > 0)
        {                   
            Worker* worker = std::reinterpret_cast<Worker>(user_data);
            worker ->callback(i, analog.channel[i]);
        }

    }
}

void Worker::process() {

    /* flag used to stop the program execution */
    bool running = true;

    /* VRPN Analog object */
    vrpn_Analog_Remote* VRPNAnalog;

    /* Binding of the VRPN Analog to a callback */
    VRPNAnalog = new vrpn_Analog_Remote("openvibe_vrpn_analog@localhost");
    VRPNAnalog->register_change_handler(this, vrpn_analog_callback);//add the pointer here

    /* The main loop of the program, each VRPN object must be called in order to process data */
    while (running)
    {
        VRPNAnalog->mainloop();
    }
}

然后,您可以将Worker的回调信号连接到您想要独立于主窗口的任何内容。

connect(worker, &Worker::callback, this, &MainWindow::nextImage);

说完所有我建议使用QTimer设置为超时0来调用VRPNAnalog->mainloop();所以worker的事件循环可以偶尔运行一次。

答案 1 :(得分:0)

  

我想要调用方法nextImage(),我在QT类mainwindow中有

您可以使用QMetaObject::invokeMethod

QMetaObject::invokeMethod(mainwindow, "nextImage");