c++ - (QT) QThread 不执行第二次

标签 c++ multithreading qt qthread

我是线程和练习题的新手,我正在编写一个程序,该程序在目录中创建文件列表并将其显示在QTableWidget中。它使用单独的线程来查找文件。由于 this,我没有从 QThread 进行子类化问题。当我运行程序并搜索目录时,它第一次工作正常,并按预期在 TableView 中显示文件的名称。但是当我再次尝试执行此操作时,QTableView 不会更新。

在调试时,我注意到我的 fileFinder 类中的断点在第二次尝试时没有被触发。似乎该线程第二次不再像第一次一样运行,我不明白为什么。我很确定这是一个我错过的简单错误。任何帮助将不胜感激。代码:

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "filefinder.h"
#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void addToTable(QString name);
    void on_btnBrowse_clicked();

private:
    Ui::MainWindow *ui;
    QThread workerThread;
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QFileDialog>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //set up tableWidget code here omitted

}

void MainWindow::on_btnBrowse_clicked()
{
    //clear tableWidget contents
    ui->tableFiles->setRowCount(0);

    fileFinder *finder = new fileFinder;
    finder->moveToThread(&workerThread);

    connect(&workerThread, SIGNAL(started()), finder, SLOT(run())); //execute run() function when worker thread has started
    connect(finder, SIGNAL(name(QString)), this, SLOT(addToTable(QString)));    //pass names from thread to handler slot
    connect(&workerThread, SIGNAL(finished()), finder, SLOT(deleteLater()));    //delete thread when done

    //get directory
    QString dir = QFileDialog::getExistingDirectory(this, "Select Directory", "/home", QFileDialog::ShowDirsOnly);
    ui->dirEdit->setText(dir);

    //set directory in thread object
    finder->setDir(dir);

    //start worker thread
    workerThread.start();
}

//add each name to tableWidget one at a time
void MainWindow::addToTable(QString name)
{
    QTableWidgetItem *fileName = new QTableWidgetItem(name);
    int row = ui->tableFiles->rowCount();
    ui->tableFiles->insertRow(row);
    ui->tableFiles->setItem(row, 0, fileName);
}

MainWindow::~MainWindow()
{
    workerThread.quit();
    workerThread.wait();
    delete ui;
}

文件查找器.h

#ifndef FILEFINDER_H
#define FILEFINDER_H

#include <QStringList>
#include <QThread>

class fileFinder : public QObject
{
    Q_OBJECT

public:
    fileFinder();
    void searchDir();
    void setDir(QString path);

public slots:
    void run();

signals:
    void name(QString n);

private:
    QStringList files;
    QString m_dir;
};

#endif // FILEFINDER_H

文件查找器.cpp

#include "filefinder.h"
#include <unistd.h>
#include <QDir>

fileFinder::fileFinder()
{

}

//return list of all files in the directory
void fileFinder::searchDir()
{
    QDir dir;
    dir.setPath(m_dir);
    //get list of file names sorted by name
    files = dir.entryList(QDir::Files, QDir::Name);
}

//set the selected directory
void fileFinder::setDir(QString path)
{
    m_dir = path;
}

//executed when thread is started
void fileFinder::run()
{
    searchDir();

    //iterate through list of files and emit names one by one
    foreach(QString f, files){
        emit(name(f));
        usleep(100);    //pause inbetween emits
    }
}

最佳答案

此行将在完成后销毁您的线程对象

connect(&workerThread, SIGNAL(finished()), finder, SLOT(deleteLater()));

您需要将线程保留为指针并在开始之前重新创建它。

在mainwindow.h中

QThread* workerThread;

然后

workerThread = new QThread;
finder->moveToThread(workerThread);

connect(workerThread, SIGNAL(started()), finder, SLOT(run()));
connect(finder, SIGNAL(name(QString)), this, SLOT(addToTable(QString)));
connect(workerThread, SIGNAL(finished()), finder, SLOT(deleteLater()));

关于c++ - (QT) QThread 不执行第二次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55244980/

相关文章:

c++ - C++ STL (ExecutionPolicy) 算法如何确定使用多少并行线程?

c++ - 模板参数中的相同长度相同符号整数类型

c++ - QGraphicsScene、QTextEdit 和失去焦点

c++ - 如何在 C++ 中进行多线程文件处理?

Ruby 2 : Forks/Threads, 如何计算特定机器的效率?

java - Thread.interrupted()清除线程中断状态的原因是什么?

c++ - 在 Qt Creator 中使用 Locator 查找成员变量

c++ - 我们应该在 C++ 单元测试中测试 src 代码断言(不是异常)吗?

c++ - 如何在不释放鼠标按钮的情况下更改选定的文本

qt - QMessageBox::critical不显示标题文本