如何动态更新QTextEdit

2 投票
2 回答
23334 浏览
提问于 2025-04-18 10:48

我在我的图形界面(GUI)中有一个QTextEdit,它放在主窗口里。我想要实时更新这个文本框的内容,方法是从一个远程更新的列表中获取数据。但是我不知道怎么才能不断地检查这个列表,而又不使用a) 无限循环或者b) 线程。

a) 无限循环会导致图形界面崩溃,因为它会一直占用资源。

b) 使用线程会出现一个错误,错误信息是:

QObject: Cannot create children for a parent that is in a different thread.

这个错误我明白。

那我该怎么做才能解决这个问题呢?

2 个回答

2

建议使用 QThread,毕竟把你的代码从 Python 线程转到 QThread 应该不难。使用信号和槽是我认为唯一干净的解决方案。这就是 Qt 的工作方式,如果你能适应这种方式,事情会变得更简单。下面是一个简单的例子:

import sip
sip.setapi('QString', 2)

from PyQt4 import QtGui, QtCore

class UpdateThread(QtCore.QThread):

    received = QtCore.pyqtSignal([str], [unicode])

    def run(self):
        while True:
            self.sleep(1) # this would be replaced by real code, producing the new text...
            self.received.emit('Hiho')

if __name__ == '__main__':

    app = QtGui.QApplication([])

    main = QtGui.QMainWindow()
    text = QtGui.QTextEdit()
    main.setCentralWidget(text)

    # create the updating thread and connect
    # it's received signal to append
    # every received chunk of data/text will be appended to the text
    t = UpdateThread()
    t.received.connect(text.append)
    t.start()

    main.show()
    app.exec_()
12

这是它在没有线程的情况下是如何工作的 :)

1) 创建一个 pyqt 文本编辑器的日志视图:

self.logView = QtGui.QTextEdit()

2) 将 pyqt 文本编辑器添加到布局中:

layout = QtGui.QGridLayout()
layout.addWidget(self.logView,-ROW NUMBER-,-COLUMN NUMBER-)
self.setLayout(layout)

3) 这个神奇的函数是:

def refresh_text_box(self,MYSTRING): 
    self.logView.append('started appending %s' % MYSTRING) #append string
    QtGui.QApplication.processEvents() #update gui for pyqt

在你的循环中调用上面的函数,或者像这样直接将拼接好的结果字符串传递给上面的函数:

self.setLayout(layout)
self.setGeometry(400, 100, 100, 400)
QtGui.QApplication.processEvents()#update gui so that pyqt app loop completes and displays frame to user
while(True):
    refresh_text_box(MYSTRING)#MY_FUNCTION_CALL
    MY_LOGIC
#then your gui loop
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dialog = MAIN_FUNCTION()
sys.exit(dialog.exec_())

撰写回答