2015-04-16 3 views
0

У меня есть приложение в Qt/C++, это браузер файлов. В настоящее время при удалении некоторых файлов или копировании некоторых файлов у меня есть поток, который управляет общим приложением и копией, а другой только что созданный для отображения индикатора выполнения с кнопкой «Отмена». Это очень просто, но когда я просматриваю файловую систему Android-устройств, любой доступ к удалению копии блокирует пользовательский интерфейс, и доступ осуществляется потоком приложения. Это не проблема, так как я не хочу, чтобы пользователь играл с пользовательским интерфейсом при копировании или удалении.QT Проблема с резьбой при отображении QDialog box

Моя проблема в основном проблема с потоком. Когда я использую создатель Qt в качестве IDE и отладки, у меня нет проблем с удалением, и индикатор выполнения также отображается без каких-либо проблем. Когда я просто использую приложение из Qt Creator, приложение часто сбивается при попытке отобразить диалоговое окно.

Я уверен, что это ссылка на резьбу. при использовании отладчика и Qt Creator общее приложение замедляя прослеживать, отлаживать ...

Вот код моего 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); 

класс PulsTreeWidget определяется, как показано ниже:

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())); 
} 

я следовал руководство Qt, но она по-прежнему сбой при выполнении «DisplayProgress»

Любая идея? Это действительно сбой, когда в другом потоке я делаю

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

Я добавляю журнал аварии:

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 

ответ

3

Помните, что вы можете использовать классы 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(); 
+0

Я не уверен, чтобы увидеть, что я должен работать в бегах()? это шоу? – Seb

+0

№ run() вы можете выполнять любые задачи, не связанные с gui. Например, удалите файлы. – gomons

+0

Когда вы пытаетесь использовать gui в non-main thread, вы получаете undefined bihavour – gomons

 Смежные вопросы

  • Нет связанных вопросов^_^