hynet1024 发表于 2023-6-29 21:21:21

关于QTextEdit控件即时显示求助

我有个Qt6生成的界面,其中有个QTextEdit控件body,使用Python3写了一段代码:self.ui.body.append(f‘{name}邮件已发送'),向控件中循环写入多行文本, 希望显示每次发送的邮件信息,但发现是循环结束之后才将所有内容一次显示出来

请教:怎样才能做到每次循环都同步显示写入的内容呢?(含历史写入内容)

PS:可以接受使用其它类型的控件

Ewan-Ahiouy 发表于 2023-6-29 21:25:04

您可以尝试使用QPlainTextEdit控件代替QTextEdit控件,并结合QApplication.processEvents()方法来实现每次循环都同步显示写入的内容,包括历史写入内容。代码示例如下:

from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QPlainTextEdit

class MainWindow(QMainWindow):
    def __init__(self):
      super().__init__()
      self.body = QPlainTextEdit(self)
      self.setCentralWidget(self.body)

    def append_text(self, text):
      cursor = self.body.textCursor()
      cursor.movePosition(Qt.TextCursor.End)
      cursor.insertText(text)
      self.body.setTextCursor(cursor)
      QApplication.processEvents()

app = QApplication([])
window = MainWindow()

for i in range(5):
    name = f"User {i}"
    window.append_text(f"{name}邮件已发送\n")

window.show()
app.exec()

在上述示例代码中,我们自定义了一个MainWindow类继承自QMainWindow,在窗口中使用QPlainTextEdit作为控件来显示文本内容。在append_text()方法中,我们通过设置文本光标的位置和插入文本来实现每次循环都将内容追加到控件中,并在每次追加后调用QApplication.processEvents()方法来确保界面刷新。

请注意,为了保证界面的及时响应,建议在循环较快或者需要频繁更新界面的情况下,适当添加QApplication.processEvents()方法进行界面刷新。

isdkz 发表于 2023-6-29 21:27:34

你可能遇到的问题是你的循环太快了,界面无法立即更新。Qt GUI更新是通过事件循环处理的,如果你的代码阻塞了事件循环(比如在主线程中的一个快速循环),GUI就没有机会更新。

你可以尝试使用 QCoreApplication.processEvents() 在你的循环中手动处理事件队列。下面是一个简单的例子:

from PyQt6.QtWidgets import QApplication
from PyQt6.QtCore import QCoreApplication

for name in names:
    self.ui.body.append(f'{name}邮件已发送')
    QApplication.processEvents() # 在这里处理事件


QApplication.processEvents() 方法将强制Qt立即处理所有挂起的事件。这通常包括绘制和更新窗口部件。

然而,过度使用这个方法可能会带来其他问题,比如响应用户的不预期输入。如果你的邮件发送过程太长,最好的方式是使用QThread或者其他方法把它放到一个单独的线程,这样它就不会阻塞主线程的事件循环了。

hynet1024 发表于 2023-6-29 21:42:18

Ewan-Ahiouy 发表于 2023-6-29 21:25
您可以尝试使用QPlainTextEdit控件代替QTextEdit控件,并结合QApplication.processEvents()方法来实现每次 ...

谢谢,已解决!
页: [1]
查看完整版本: 关于QTextEdit控件即时显示求助