考虑将QT窗口作为阻塞线程,加入到主线程,其余线程detach掉
class InteractiveX : public Interactive {
public:
InteractiveX() : dt_handler(nullptr), p_gui(nullptr), state(eIdle) {}
virtual ~InteractiveX() { std::cout << "InteractiveX quit" << std::endl; }
...
public:
void Run(DataHandler* data_handler) override {
dt_handler = data_handler;
state = eInput;
std::thread output(&InteractiveX::Output, this);
output.detach();
std::thread input(&InteractiveX::Input, this);
input.detach();
std::thread gui(&InteractiveX::gui_start, this);
gui.join();
}
public:
void Input() {
...
}
void Output() {
...
}
private:
void gui_start() {
p_gui = new GuiIntf;
p_gui->thread_start();
delete p_gui;
p_gui = nullptr;
}
void gui_stop() {
// 使用invokeMethod模拟connect信号到槽的连接
QMetaObject::invokeMethod(p_gui, "stop", Qt::DirectConnection);
}
private:
DataHandler* dt_handler;
GuiIntf* p_gui;
int state;
};
Interactive::~Interactive() {}
InteractiveX interactive_instance;
Interactive* Interactive::GetInstance() { return &interactive_instance; }
在 gui线程,创建窗口:
class GuiIntf : public QObject {
Q_OBJECT
public:
GuiIntf() : p_app(nullptr), p_win(nullptr) {}
public:
virtual ~GuiIntf() {
delete p_win;
delete p_app;
}
void thread_start() {
int argc = 0;
char* argv = "";
p_app = new QApplication(argc, &argv);
p_win = new MainWindow;
p_win->show();
p_app->exec();
}
void thread_stop() {
if (nullptr != p_win) {
p_win->close();
}
if (nullptr != p_app) {
p_app->quit();
}
}
public slots:
void stop() { thread_stop(); }
private:
QApplication* p_app;
MainWindow* p_win;
};
通过 QMetaObject::invokeMethod 来进行QT线程通信
void gui_stop() {
// 使用invokeMethod模拟connect信号到槽的连接
QMetaObject::invokeMethod(p_gui, "stop", Qt::DirectConnection);
}