为啥 QTextBrowser 中的文本不是一个一个显示,而是一次显示全部?

Posted

技术标签:

【中文标题】为啥 QTextBrowser 中的文本不是一个一个显示,而是一次显示全部?【英文标题】:Why text inside QTextBrowser is not displayed one-by-one instead it displays all-at-once?为什么 QTextBrowser 中的文本不是一个一个显示,而是一次显示全部? 【发布时间】:2017-10-15 21:14:51 【问题描述】:

我用过的sn-p如下

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 的内容。怎么了?

【问题讨论】:

在追加后添加qApp->processEvents(); 使上述方法强制GUI循环更新的原因是,用于各种任务(如监听信号、调用槽等)的GUI不会立即执行所有任务。另一种选择是 while 的每次迭代都由 QTimer 处理。 【参考方案1】:

问题是您处于一个紧密循环中 (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
        
    

【讨论】:

那么,有没有其他选择,也就是说,可以通过使用 textBrowser 以外的其他小部件来提高性能(对不起,我是初学者,你可以告诉我小部件(如果有的话) )我会阅读文档)。 @secretsinside 你只能在每添加 N 个文件时调用 processEvents,作为一个想法【参考方案2】:

我同意史蒂夫回答的第一部分:对 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'));

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

【讨论】:

但是这段代码并没有一一显示内容,我实际上问的是,就我阅读并运行上面的代码而言,它正在获取列表中的文件名并最后附加通过将每个条目加入一个新行。 啊,我误解了你的问题。是的,如果你想让它一个一个显示,那么唯一真正的选择是使用史蒂夫的答案,在添加每个项目后调用processEvents()

以上是关于为啥 QTextBrowser 中的文本不是一个一个显示,而是一次显示全部?的主要内容,如果未能解决你的问题,请参考以下文章

单击其中的链接后,QTextBrowser 中的 PySide/PyQt 文本消失

从文件中动态更新 Qdialog 中的 QTextBrowser(由另一个作业更新)

如何在 QTextBrowser 中居中选定文本

PyQt4 中的 QTextBrowser 超链接

Qt入门系列开发教程基础控件篇QTextBrowser文本浏览控件

QTextBrowser append() 使文本变成超链接