从不同的线程更新GUI

时间:2014-05-25 16:52:40

标签: c++ multithreading qt

我需要在不同的线程中运行计算密集型功能,以便GUI在运行时不会冻结或变灰。

我按照这个例子:https://stackoverflow.com/a/16501374/2904614

但是GUI仍然会冻结并变灰。

MainWindow.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->textBrowser->setFont(QFont("Monospace",11));
    ui->textBrowser->setLineWrapMode(QTextEdit::NoWrap);

    updater->moveToThread(thread);
    connect(updater,SIGNAL(req()), this, SLOT(getCheckSum()));
    connect(thread, SIGNAL(destroyed()), updater, SLOT(deleteLater()));
    thread->start();
}

当用户点击指定按钮时。由于一个目录中可能有很多文件,因此当QDirIterator遍历所有文件时,GUI将冻结。我希望添加一个进度条,向用户显示该程序仍在运行。

void MainWindow::on_pushButton_clicked()
{
    updater->getHash();
    //getCheckSum();
}

修改 我希望函数MainWindow::getCheckSum()在与GUI不同的线程中运行。我该如何实现?

Github:https://github.com/Jyang772/PenguSniff

3 个答案:

答案 0 :(得分:1)

鉴于你只需要运行一个函数我会推荐QtConcurrent。从文档中提取:

在单独的线程中运行函数

要在另一个线程中运行函数,请使用QtConcurrent :: run():

extern void aFunction();
QFuture<void> future = QtConcurrent::run(aFunction);

这将在从默认QThreadPool获得的单独线程中运行aFunction。您可以使用QFuture和QFutureWatcher类来监视函数的状态。

答案 1 :(得分:0)

问题是你直接在另一个线程中调用类的函数:

updater->getHash();

它会在您的应用程序中导致未定义的行为并使其崩溃。正确的方法是从MainWindow发出一个信号,该信号连接到更新程序中的getHash()插槽:

connect(this,SIGNAL(getHash()), updater, SLOT(getHash()));


void MainWindow::on_pushButton_clicked()
{
    emit getHash();
}

这将导致排队连接,并在更新程序线程中运行插槽。

答案 2 :(得分:0)

在GUI线程中调用getHash()计算函数(根据您的注释计算)。将它绑定到单击的信号,然后它将在对象的线程中调用。

connect(button, SIGNAL(clicked()), this, SLOT(getHash()));