c++ - 在单独的线程上填充、填充 QTreeView 树

标签 c++ qt

我试图在单独的线程上填充 QTreeView 对象。我要写入的信息是网络驱动器上的文件夹+文件列表。遍历子目录需要很多时间,所以我不想在此操作期间阻塞 Gui 线程。

这是我的代码:

class Worker : public QObject
{
    Q_OBJECT

public slots:

    void doWork(QString &parameter){

        QString data;

        QDirIterator it(parameter, QStringList() << "*.xml", QDir::Files, QDirIterator::Subdirectories);
        while (it.hasNext()) {
            QString currentFile = it.next();
            emit resultReady(currentFile);
        }
    }

    signals:
        void resultReady(QString &result);
    };

class iUSMDatabaseComposerWindow:public QMainWindow{
        Q_OBJECT
        ...

        QThread workerThread;
        QEventLoop loop;
    public:
        iUSMDatabaseComposerWindow(){
        Worker *worker = new Worker;
        worker->moveToThread(&workerThread);

        bool success = connect(&workerThread, SIGNAL(finished()), worker, SLOT(deleteLater())); assert(success);
        success = connect(this, SIGNAL(getFilesInFolder(QString &)), worker, SLOT(doWork(QString &))); assert(success);
        success = connect(worker, SIGNAL(resultReady(QString &)), this, SLOT(appendToTree(QString &))); assert(success);

        //For Qt5 : connect( &workerThread, &QThread::started, &loop, &QEventLoop::quit );
        success = connect( &workerThread, SIGNAL( started() ), &loop, SLOT( quit() ), Qt::DirectConnection ); assert(success);
        workerThread.start();
        loop.exec(); // wait for thread initialization

        QString targetFolder (TARGETFOLDER);
        emit getFilesInFolder(targetFolder);
    }
    signals:
        void getFilesInFolder(QString &folderToProcess);
    private slots:
        void appendToTree(QString &file);

我遇到的是 connect() 成功,但 Worker 的插槽 (doWork) 从未被 emit getFilesInFolder(targetFolder) 调用。我注意到如果我在连接到 doWork() 插槽时添加 Qt::DirectConnection,它会调用它。

这可能是什么问题?

最佳答案

尝试在线程初始化完成后发出信号:

QThread t;
// connect here
QEventLoop loop;
connect( &t, &QThread::started, &loop, &QEventLoop::quit );
// for Qt4: connect( &t, SIGNAL( started() ), &loop, SLOT( quit() ) );
t.start();
loop.exec(); // wait for thread initialization

emit YourSignal();

您的问题:您在线程初始化完成之前发出信号。 QThread 在创建线程后启动一个事件循环。但是在您的情况下,事件循环无法及时进行初始化,因此您的 emit 什么都不做。

关于c++ - 在单独的线程上填充、填充 QTreeView 树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32242885/

相关文章:

c++ - 如果模板是整数类型,则仅对某些模板规范启用功能

c++ - 如何在字符串中搜索 C++

Python Pyqt5 QDateEdit 获取日期字符串

c++ - OpenCV - 将相机矩阵和畸变系数存储为 Mat

c++ - move 类的构造函数

java - 如何将 Eclipse C++ 添加到 Eclipse 经典?

Qt Symbian 音频级别

c++ - 不使用 << 的带有值的 QVector 的单行实例化

qt - 选择 QGraphicsItem 时调用什么方法

qt - 如何动态创建Q_Properties