如何在Qt GUI中使用线程
How to use threads in Qt GUI
我有一个应用程序,它可以连续从相机读取图像并将其显示给用户。用户可以调整不同的滑块,如曝光和阈值,以实时修改图像。之后,我还对这个图像进行了一系列计算,这有时会使GUI没有响应,所以我决定使用线程来分配工作负载。
然而,我无法使其正常工作,有时当滑块值更改或尝试保存图像(GUI中的保存按钮)时,我会出现分段错误和一堆"assertion`GLib GObject CRITICAL**:g_object_unref:assertion'g_IS_object(object)'failed"警告,GUI有时会停止更新图像或冻结,因此您无法移动滑块或按下任何按钮。
我尝试使用C++中的标准std::线程,并通过插槽将其连接到启动按钮。
QObject::connect(btnStart, SIGNAL(clicked()), this, SLOT(RunStartThread()));
void MainMenu::RunStartThread(){
std::thread t1;
t1= std::thread(&MainMenu::Start,this);
t1.detach();
}
void MainMenu::Start() {
run = true;
window->mngr->ReadCalibration();
window->mngr->InitializeCameras();
while (run) {
window->mngr->CaptureImage();
window->mngr->ProcessImages();
UpdateLabels();
}
window->mngr->Stop();
}
当用户更改滑块值时,他们会更改我的管理器(上面的mngr)中captureImage和ProcessImages使用的变量。当要访问变量时,我尝试使用std::互斥锁/解锁,但它没有改变任何内容。我试着在网上找到如何做到这一点的例子,但还没有找到有连续while循环的东西。
当谈到线程时,我是个新手,所以只要告诉我我是否以错误的方式处理它。
首先,对于线程间通信,使用信号和插槽。默认情况下,Qt连接在线程之间进行良好的线程跳跃,从而避免复杂的同步。
其次,您有三种使用线程的方法:QThread、QRunnable、QtConcurrent::Run(我最喜欢,因为需要最少的代码量)。
如果是QThread
,请不要将其子类化!这是常见的设计错误。
示例:
SomeClass::~SomeClass()
{
SignalStop();
future.result();
}
void SomeClass::RunStartThread(){
future = QtConcurrent::run(this, &SomeClass::DoOnThread);
}
void SomeClass::DoOnThread()
{
while (ShouldContinueToRun()) {
QImage im1 = CaptureImage();
emit ImageCaptured(im1);
QImage im2 = ProcessImages(im1);
emit ImageProcessed(im2);
}
emit JobCompleted();
}
请注意,QObject::connect有最后一个参数,它定义了在涉及不同线程的情况下如何执行插槽调用。请参阅用于此参数的枚举文档
因此,默认情况下,Qt会检测是否需要跳线程。仔细阅读QObject::moveToThread也应该有助于理解这个问题(注意,如果对象有父线程,就不能将其移动到不同的线程)。
- QtConcurrent - 在发布到 UI 线程的数千个结果中保持 GUI 响应
- 线程和 GUI 处理
- 多线程Windows GUI应用程序中的死锁
- 带GUI的Qt多线程
- 与非主线程的 GUI 线程通信
- Qt 如何将数据从一个 GUI 传递到另一个线程
- Qt:工作线程和 GUI 事件之间的关系
- 解决方法:QPixmap:在GUI线程之外使用pixmap是不安全的
- 处理中断时,如何回到主gui线程
- 从其他std ::线程更新QT GUI
- QNetworkAccessManager即使在另一个线程中也能冻结GUI
- 如何在非 gui 线程上正确创建 QUdpSocket?未发出现读
- Qt的GUI线程在从外部对象调用方法时是否会在引擎盖下生成线程?
- ROS-Qt GUI - 如何分发线程
- 由于线程问题,Qt-Gui没有更新
- 当主GUI线程被阻塞时,如何从工作线程创建无模式对话框
- Qt 停止来自 GUI 线程的工作线程循环
- 使用第二个线程快速更新 GUI 窗口会通过调整窗口大小或移动窗口而崩溃
- 如何降低 QT Gui 线程优先级
- 使用 Qt 的简单线程 gui 应用程序的结构是什么?