如何动态更新QTextEdit
我在我的图形界面(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_())