2015-12-29 3 views
1

У меня есть следующий код, который работает как ожидалось. Он обновляет значение индикатора выполнения в каждом цикле. Единственная проблема, с которой я столкнулась, - это когда я закончил, и вызывается emit ProcessUserRowsFinished() в методе OnProcessUserRowsStarted, программа вылетает из строя.Обновление QProgressBar в результате сбоев QThread

class UsersProcess: public QObject 
{ 
    Q_OBJECT 

public: 
    UsersProcess(CTCore::DBConnect* db_context, UserSettingsMap user_settings_map); 
    void SetProgressBar(QProgressBar *progress_bar); 

private: 

    QProgressBar *progressBar; 
    QSharedPointer<QList<CTCoreZen::User>> listUsers; 
    QScopedPointer<QThread> threadRowWorker; 

signals: 
    void ProcessUserRowsFinished(); 
    void ProgressBarSetValue(int value); 

} 

void UsersProcess::SetProgressBar(QProgressBar *progress_bar) 
{ 
    this->progressBar = progress_bar; 
} 

void UsersProcess::OnUserListSuccess(QList<CTCoreZen::User> *users) 
{ 
    this->listUsers.reset(users); 

    this->progressBar->setVisible(true); 
    this->progressBar->setTextVisible(true); 
    this->progressBar->setMinimum(0); 
    this->progressBar->setMaximum(this->listUsers->size()); 
    this->progressBar->setValue(0); 



    this->threadRowWorker.reset(new QThread()); 
    this->moveToThread(this->threadRowWorker.data()); 

    connect(this->threadRowWorker.data(), &QThread::started, this, &UsersProcess::OnProcessUserRowsStarted); 

    connect(this, &UsersProcess::ProgressBarSetValue, this->progressBar, &QProgressBar::setValue); 

    connect(this, &UsersProcess::ProcessUserRowsFinished, this->threadRowWorker.data(), &QThread::quit); 
    connect(this, &UsersProcess::ProcessUserRowsFinished, this, &UsersProcess::deleteLater); 
    connect(this->threadRowWorker.data(), &QThread::finished, this->threadRowWorker.data(), &QThread::deleteLater); 

    this->threadRowWorker->start(); 
} 

void UsersProcess::OnProcessUserRowsStarted() 
{ 
    int row = 0; 

    UsersData userData(this->dbContext); 

    int maxRows = this->listUsers->size(); 
    for(auto iter = this->listUsers->begin(); iter != this->listUsers->end(); ++iter) 
    { 
     row++; 
     emit this->ProgressBarSetValue(row); 
    } 

    emit ProcessUserRowsFinished(); 
} 

ответ

1

Это из-за вашей темы было удалено. Этот вызов удаляет экземпляр класса UsersProcess, а QScopedPointer удаляет поток.

connect(this, &UsersProcess::ProcessUserRowsFinished, this, &UsersProcess::deleteLater); 

Но вы также имеете эти соединения

connect(this, &UsersProcess::ProcessUserRowsFinished, this->threadRowWorker.data(), &QThread::quit); 
connect(this->threadRowWorker.data(), &QThread::finished, this->threadRowWorker.data(), &QThread::deleteLater); 

Когда один из этих событий запускает поток уже удален.

+0

Я следую примеру по этой ссылке: https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ Так это сделано неправильно? Каков наилучший способ сделать это? Или это потому, что я использую QSharedPointer? – adviner

+0

Да, вы можете просто удалить указатель с областью или удалить эти два соединения. – Evgeny

+0

Я, наконец, испытал, и он сработал спасибо за информацию – adviner