C++ 显示QDialog box时出现QT线程问题

C++ 显示QDialog box时出现QT线程问题,c++,multithreading,qt,qthread,C++,Multithreading,Qt,Qthread,我用Qt/C++开发了一个应用程序,它是一个类似文件浏览器的应用程序。目前,当删除一些文件或复制一些文件时,我有一个线程来管理整个应用程序和复制,另一个线程刚刚创建,用于显示带有“取消”按钮的进度条。这是非常基本的,但当我浏览Android设备文件系统时,任何删除复制的访问都会冻结UI,访问由应用程序线程完成。这不是问题,因为我不希望用户在复制或删除时玩UI 我的问题主要是线程的实时问题。当我使用Qt-creator作为IDE并进行调试时,我没有任何问题,删除工作正常,进度条也会显示出来,没有任

我用Qt/C++开发了一个应用程序,它是一个类似文件浏览器的应用程序。目前,当删除一些文件或复制一些文件时,我有一个线程来管理整个应用程序和复制,另一个线程刚刚创建,用于显示带有“取消”按钮的进度条。这是非常基本的,但当我浏览Android设备文件系统时,任何删除复制的访问都会冻结UI,访问由应用程序线程完成。这不是问题,因为我不希望用户在复制或删除时玩UI

我的问题主要是线程的实时问题。当我使用Qt-creator作为IDE并进行调试时,我没有任何问题,删除工作正常,进度条也会显示出来,没有任何问题。当我在Qt Creator之外使用应用程序时,在尝试显示对话框时,应用程序经常崩溃

我很确定这是线程的链接。当使用调试器和Qt creator时,整个应用程序会减慢跟踪速度,调试

以下是请求删除时my TreeView.cpp的代码,例如:

DialogProgressIndicator *DeleteProgress = new DialogProgressIndicator;
        DeleteProgress->moveToThread(&ProgressThread);
        connect(&ProgressThread, &QThread::finished, DeleteProgress, &QObject::deleteLater);
        connect(this, &PulsTreeWidget::DisplayProgress, DeleteProgress, &DialogProgressIndicator::ShowDlg);
        connect(this, &PulsTreeWidget::UpdateProgress, DeleteProgress, &DialogProgressIndicator::UpdateIndicator);
        connect(this, &PulsTreeWidget::CloseProgress, DeleteProgress, &DialogProgressIndicator::CloseDlg);
        connect(DeleteProgress,&DialogProgressIndicator::CancelAction, this, &PulsTreeWidget::CatchActionCancel);
        ProgressThread.start();
        DisplayProgress();
删除完成后,我将按照以下方法关闭所有内容:

CloseProgress();
            ProgressThread.quit();
            disconnect(&ProgressThread, &QThread::finished, FileTransferProgress, &QObject::deleteLater);
            disconnect(this, &PulsTreeWidget::DisplayProgress, FileTransferProgress, &DialogProgressIndicator::ShowDlg);
            disconnect(this, &PulsTreeWidget::UpdateProgress, FileTransferProgress, &DialogProgressIndicator::UpdateIndicator);
            disconnect(this, &PulsTreeWidget::CloseProgress, FileTransferProgress, &DialogProgressIndicator::CloseDlg);
            disconnect(FileTransferProgress,&DialogProgressIndicator::CancelAction, this, &PulsTreeWidget::CatchActionCancel);
脉冲宽度等级定义如下:

class PulsTreeWidget : public QTreeWidget
{
    Q_OBJECT
    QThread ProgressThread;

public:
    PulsTreeWidget(PulsDeviceMngr& device, PulsMainUI& parent);
    ~PulsTreeWidget();

signals:
    void DisplayProgress();
    void CloseProgress();
    void UpdateProgress(int);
进度条由类管理

DialogProgressIndicator.cpp

#include <QApplication>

#include "dialogprogressindicator.h"
#include "ui_dialogprogressindicator.h"

DialogProgressIndicator::DialogProgressIndicator(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogProgressIndicator)
{
    ui->setupUi(this);
    ui->progressBar->setRange(0,100);
    ui->progressBar->setValue(1);

    connect(ui->Cancel, SIGNAL(clicked()), this, SLOT(onClickCancel()));
}

void DialogProgressIndicator::ShowDlg() {
    ui->progressBar->show();
}

void DialogProgressIndicator::CloseDlg() {
    ui->progressBar->close();
}

DialogProgressIndicator::~DialogProgressIndicator()
{
    delete ui;
}

void DialogProgressIndicator::UpdateIndicator(int value) {
    ui->progressBar->setValue(value);
    QApplication::processEvents();
}

void DialogProgressIndicator::onClickCancel() {
    emit CancelAction();
    disconnect(ui->Cancel, SIGNAL(clicked()), this, SLOT(onClickCancel()));
}
我正在添加崩溃日志:

Application Specific Information:
abort() called

Thread 0:: Dispatch queue: com.apple.main-thread
0   com.apple.AppKit                0x00007fff89e6561f -[NSView(NSInternal) _allocAuxiliary:] + 833
1   com.apple.AppKit                0x00007fff89e67a59 -[NSView _commonAwake] + 36
2   com.apple.AppKit                0x00007fff89e6c841 -[NSView initWithFrame:] + 457
3   libqcocoa.dylib                 0x0000000103c2078f 0x103c0c000 + 83855
4   libqcocoa.dylib                 0x0000000103c20a1d 0x103c0c000 + 84509
5   libqcocoa.dylib                 0x0000000103c18f36 0x103c0c000 + 53046
6   libqcocoa.dylib                 0x0000000103c14b72 0x103c0c000 + 35698
7   QtGui                           0x0000000100f77603 QWindow::create() + 51
8   QtWidgets                       0x0000000101509e13 QWidgetPrivate::create_sys(unsigned long long, bool, bool) + 1107
9   QtWidgets                       0x00000001014df86c QWidget::create(unsigned long long, bool, bool) + 444
10  QtWidgets                       0x00000001014eeebd QWidget::setVisible(bool) + 237
11  QtWidgets                       0x000000010169679d QDialog::setVisible(bool) + 205
12  com.yourcompany.puls_connect    0x0000000100022305 DialogProgressIndicator::ShowDlg() + 21
13  com.yourcompany.puls_connect    0x000000010001a51e void QtPrivate::FunctionPointer<void (DialogProgressIndicator::*)()>::call<void, void>(void (DialogProgressIndicator::*)(), DialogProgressIndicator*, void**) + 142
14  com.yourcompany.puls_connect    0x000000010001a3fa QtPrivate::QSlotObject<void (DialogProgressIndicator::*)(), void, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) + 202
15  QtCore                          0x0000000100bfdda2 QMetaObject::activate(QObject*, int, int, void**) + 1874
16  com.yourcompany.puls_connect    0x00000001000242db PulsTreeWidget::DisplayProgress() + 43
特定于应用程序的信息:
调用了abort()
线程0::调度队列:com.apple.main-Thread
0 com.apple.AppKit 0x00007fff89e6561f-[NSView(NSInternal)\u allocAuxiliary:+833
1 com.apple.AppKit 0x00007fff89e67a59-[NSView\u commonAwake]+36
2 com.apple.AppKit 0x00007fff89e6c841-[NSView initWithFrame:+457
3 libqcocoa.dylib 0x0000000103c2078f 0x103C000+83855
4 libqcocoa.dylib 0x0000000103c20a1d 0x103C000+84509
5 libqcocoa.dylib 0x0000000103c18f36 0x103C000+53046
6 libqcocoa.dylib 0x0000000103c14b72 0x103C000+35698
7 QtGui 0x0000000100f77603 QWindow::create()+51
8 QtWidgets 0x0000000101509e13 QWidgetPrivate::创建系统(无符号长、布尔、布尔)+1107
9 QtWidgets 0x00000001014df86c QWidget::create(无符号长、布尔、布尔)+444
10个QtWidgets 0x00000001014eeebd QWidget::setVisible(bool)+237
11 QtWidgets 0x000000010169679d QDialog::setVisible(bool)+205
12 com.yourcompany.puls_connect 0x00000001000222305 DialogProgressIndicator::ShowDlg()+21
13 com.yourcompany.puls_connect 0x000000010001a51e void QtPrivate::FunctionPointer::call(void(DialogProgressIndicator::*)(),DialogProgressIndicator*,void**)+142
14 com.yourcompany.puls_connect 0x000000010001a3fa QtPrivate::QSlotObject::impl(int,QtPrivate::QSlotObjectBase*,QObject*,void**,bool*)+202
15 QtCore 0x0000000100bfdda2 QMetaObject::激活(QObject*,int,int,void**)+1874
16 com.yourcompany.puls_connect 0x000000010002DB PulsTreeWidget::DisplayProgress()+43

请记住,您只能在主线程中使用GUI类。用于并行任务使用 QFutureWatcher:

WaitDialog waitDlg(this);
connect(this, SIGNAL(progress(int)), &waitDlg, SLOT(setProgress(int)));
QFutureWatcher<void> watcher;
connect(&watcher, SIGNAL(finished()), &waitDlg, SLOT(close()));
connect(&watcher, SIGNAL(canceled()), &waitDlg, SLOT(close()));
QFuture<void> future = QtConcurrent::run([] () {/*do parallel task here*/});
watcher.setFuture(future);
waitDlg.exec();
WaitDialog waitDlg(这个);
连接(this,信号(progress(int)),&waitDlg,插槽(setProgress(int));
未来观察者;
连接(&watcher,信号(finished()),&waitDlg,插槽(close());
连接(&watcher,信号(取消()),&waitDlg,插槽(关闭());
QFuture future=QtConcurrent::run([](){/*此处执行并行任务*/});
watcher.setFuture(未来);
waitDlg.exec();

请记住,您只能在主线程中使用GUI类。用于并行任务使用 QFutureWatcher:

WaitDialog waitDlg(this);
connect(this, SIGNAL(progress(int)), &waitDlg, SLOT(setProgress(int)));
QFutureWatcher<void> watcher;
connect(&watcher, SIGNAL(finished()), &waitDlg, SLOT(close()));
connect(&watcher, SIGNAL(canceled()), &waitDlg, SLOT(close()));
QFuture<void> future = QtConcurrent::run([] () {/*do parallel task here*/});
watcher.setFuture(future);
waitDlg.exec();
WaitDialog waitDlg(这个);
连接(this,信号(progress(int)),&waitDlg,插槽(setProgress(int));
未来观察者;
连接(&watcher,信号(finished()),&waitDlg,插槽(close());
连接(&watcher,信号(取消()),&waitDlg,插槽(关闭());
QFuture future=QtConcurrent::run([](){/*此处执行并行任务*/});
watcher.setFuture(未来);
waitDlg.exec();

请记住,您只能在主线程中使用GUI类。用于并行任务使用 QFutureWatcher:

WaitDialog waitDlg(this);
connect(this, SIGNAL(progress(int)), &waitDlg, SLOT(setProgress(int)));
QFutureWatcher<void> watcher;
connect(&watcher, SIGNAL(finished()), &waitDlg, SLOT(close()));
connect(&watcher, SIGNAL(canceled()), &waitDlg, SLOT(close()));
QFuture<void> future = QtConcurrent::run([] () {/*do parallel task here*/});
watcher.setFuture(future);
waitDlg.exec();
WaitDialog waitDlg(这个);
连接(this,信号(progress(int)),&waitDlg,插槽(setProgress(int));
未来观察者;
连接(&watcher,信号(finished()),&waitDlg,插槽(close());
连接(&watcher,信号(取消()),&waitDlg,插槽(关闭());
QFuture future=QtConcurrent::run([](){/*此处执行并行任务*/});
watcher.setFuture(未来);
waitDlg.exec();

请记住,您只能在主线程中使用GUI类。用于并行任务使用 QFutureWatcher:

WaitDialog waitDlg(this);
connect(this, SIGNAL(progress(int)), &waitDlg, SLOT(setProgress(int)));
QFutureWatcher<void> watcher;
connect(&watcher, SIGNAL(finished()), &waitDlg, SLOT(close()));
connect(&watcher, SIGNAL(canceled()), &waitDlg, SLOT(close()));
QFuture<void> future = QtConcurrent::run([] () {/*do parallel task here*/});
watcher.setFuture(future);
waitDlg.exec();
WaitDialog waitDlg(这个);
连接(this,信号(progress(int)),&waitDlg,插槽(setProgress(int));
未来观察者;
连接(&watcher,信号(finished()),&waitDlg,插槽(close());
连接(&watcher,信号(取消()),&waitDlg,插槽(关闭());
QFuture future=QtConcurrent::run([](){/*此处执行并行任务*/});
watcher.setFuture(未来);
waitDlg.exec();

我不确定在run()中要运行什么?是Showdlg吗?不是。run()您可以执行任何非gui任务。例如,删除文件。当您尝试在非主线程中使用gui时,您会得到未定义的bihavourI,但在我的情况下,在执行DisplayProgress时,它会崩溃,DisplayProgress是发送到对话框(在线程中)并运行show()的信号。我尚未管理和更改或删除。只需设置线程、设置对话框并显示对话框。当应用程序在Qt creator环境中运行时不会发生这种情况,但只有当您通过双击应用程序来运行应用程序时才会发生这种情况。但是您有
DeleteProgress->moveToThread(&ProgressThread)代码行。qt是否向应用程序输出窗口写入内容?我不确定在run()中要运行什么?是Showdlg吗?不是。run()您可以执行任何非gui任务。例如,删除文件。当您尝试在非主线程中使用gui时,您会得到未定义的bihavourI,但在我的cas中