为什么QTextBrowser中的文本不是逐个显示,而是一次全部显示



我使用的片段如下

QDirIterator it(dir, filters, QDir::NoDotAndDotDot | QDir::AllEntries , QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
    while(it.hasNext())
    {
        it.next();
        if(QFileInfo(it.filePath()).isFile())
        {
            QString name=it.fileName();
            ui->textBrowser_filename->append(name);
        }
    }

它遍历所有目录,而不是像我说的那样逐个显示文件名,而是一次显示 textBrowser 的内容。怎么了?

问题是你处于一个紧密的循环中(while(it.hasNext())),Qt将无法渲染你要求它的任何内容,直到你退出该循环并且UI线程的控制返回到Qt事件循环。

您可以使用QCoreApplication::processEvents让它在每个循环上呈现,但根据您添加到文本浏览器的文件数量,它可能会变得缓慢

QDirIterator it(dir, filters, QDir::NoDotAndDotDot | QDir::AllEntries , QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
    while(it.hasNext())
    {
        it.next();
        if(QFileInfo(it.filePath()).isFile())
        {
            QString name=it.fileName();
            ui->textBrowser_filename->append(name);
            QCoreApplication::processEvents(); // this will cause the filename to appear
        }
    }

我同意史蒂夫回答的第一部分:GUI的更新是昂贵的,并且仅在控制返回到Qt主应用程序事件循环时才发生。

但是,与其在循环中手动调用processEvents()(通常应避免这样做),我建议通过连接要添加的所有文件名来构造单个字符串,然后仅对 QTextBrowser::append() 函数进行一次调用。

这样:

QStringList list;
while (it.hasNext()) {
    if (QFileInfo(it.filePath()).isFile()) {
        list << it.fileName();
    }
    it.next();
}
ui->textBrowser_filename->append(list.join('n'));

如果这确实需要很长时间,就像您有数百或数千个文件一样,您可以运行在后台线程中创建字符串列表的代码段(使用 QThreadPoolQRunnableQtConcurrent 等),完成后,使用大字符串更新文本浏览器。