Emi*_*ore 19 linux user-interface qt multithreading
我在Qt工作,当我按下按钮GO时,我需要不断地将包发送到网络并使用我收到的信息修改界面.
问题是我有一个while(1)按钮,所以按钮永远不会完成,所以界面永远不会更新.我想在按钮中创建一个线程并将while(){}代码放在那里.
我的问题是如何从线程修改接口?(例如,如何从线程中修改textBox?
NIA*_*NIA 37
关于Qt的重要一点是,您必须仅从GUI线程(即主线程)使用Qt GUI.
这就是为什么正确的方法是从工作者通知主线程,主线程中的代码实际上将更新文本框,进度条或其他东西.
我认为,最好的方法是使用QThread而不是posix线程,并使用Qt 信号在线程之间进行通信.这将是你的工人,一个替代品thread_func:
class WorkerThread : public QThread {
void run() {
while(1) {
// ... hard work
// Now want to notify main thread:
emit progressChanged("Some info");
}
}
// Define signal:
signals:
void progressChanged(QString info);
};
Run Code Online (Sandbox Code Playgroud)
在您的小部件中,使用与.h中的信号相同的原型定义一个插槽:
class MyWidget : public QWidget {
// Your gui code
// Define slot:
public slots:
void onProgressChanged(QString info);
};
Run Code Online (Sandbox Code Playgroud)
在.cpp中实现此功能:
void MyWidget::onProgressChanged(QString info) {
// Processing code
textBox->setText("Latest info: " + info);
}
Run Code Online (Sandbox Code Playgroud)
现在在你想要产生一个线程的地方(点击按钮):
void MyWidget::startWorkInAThread() {
// Create an instance of your woker
WorkerThread *workerThread = new WorkerThread;
// Connect our signal and slot
connect(workerThread, SIGNAL(progressChanged(QString)),
SLOT(onProgressChanged(QString)));
// Setup callback for cleanup when it finishes
connect(workerThread, SIGNAL(finished()),
workerThread, SLOT(deleteLater()));
// Run, Forest, run!
workerThread->start(); // This invokes WorkerThread::run in a new thread
}
Run Code Online (Sandbox Code Playgroud)
连接信号和插槽后,emit progressChanged(...)在工作线程中发出插槽将向主线程发送消息,主线程将调用连接到该信号的插槽,onProgressChanged此处.
Ps我还没有测试过代码,所以如果我错了,可以随意建议编辑