我在PyQt
GUI
上有一个文本字段,用于从另一个文件打印文本,但是该文件可能会经常更改,因此我希望textfield每10秒更新一次,以便用户可以看到实时文件文本。
这是我正在使用的淡化版本,但是线程不起作用:/tmp/py.state.test
文件写得太连续,所以我希望这个更改出现在QTextBrowser
上。就像现在一样,如果我运行该程序,它将正确地初始化文本,但它在运行时不会更新。
from PyQt4 import QtGui, QtCore
from PyQt4.Qt import *
import sys, os, threading, time
class TestWindow(Qt.Gui.QWidget):
def __init__(self):
super(TASwitchWindow, self).__init__()
self.initUI()
def initUI(self):
t=threading.Thread(target.self.cfglabel())
t.start()
t.join()
self.setGeometry(200,200,800,600)
self.setWindowTitle('TA Switch Tab')
self.show()
def cfglabel(self):
self.lbl = QtGui.QTextBrowser(self)
self.lbl.resize(760,40)
self.lbl.move(20,440)
with open ("/tmp/py.state.test", "r") as myfile:
data=myfile.read().replace('\n', '')
self.lbl.append(data)
time.sleep(10)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
win = TestWindow()
sys.exit(app.exec_())
道歉,可能存在拼写错误,因为我的代码在另一个系统上,我不得不重新输入它。如果有人能告诉我如何每10秒更新一次文本,那就太棒了。使用QLabel
或其他内容而不是TextBrowser
会更好吗?感谢
答案 0 :(得分:1)
听起来你真的想要实现一个计时器。 QTimers非常易于使用。
@"Unilateral pulmonary emphysema [MacLeod's syndrome]"
答案 1 :(得分:1)
您的代码存在一些问题,导致其无法正常工作。
您正在从线程更新GUI。这在Qt中是禁止的。必须从主线程完成与GUI对象的所有交互,否则您的程序将随机崩溃。您需要使用QThread
并从QThread
向主线程中的一个插槽发出信号,然后与GUI对象进行交互(信号发射是线程安全的,几乎所有其他都不是)
当您实例化Python线程时,您没有传递对要在线程中运行的方法的引用。你写过t=threading.Thread(target.self.cfglabel())
。请注意cfglabel
之后的额外括号。你实际做的是在主线程中运行cfglabel
方法,并使用它的返回值(在你的情况下为None
)作为应该在线程中运行的方法。显然这不起作用!代码行应改为t=threading.Thread(target.self.cfglabel)
等待线程在应用程序开始运行之前完成(t.join()
)。所以当然线程永远不会在后台运行以不断更新GUI。您不想在用例中加入该主题。
上面提到的#3中的更改要求您保存对线程的引用,以便在initUI
方法完成运行后不会对其进行垃圾回收。我建议将其存储为实例属性:aka self.t
。
重新加载文件的代码不在while
循环中。所以目前它只加载文件一次,而不是每10秒重新加载一次。您不希望cfglabel
方法永远结束(当它结束时,线程也是如此,您将不再获得更新)。因此,您希望代码变为:
_
def cfglabel(self):
self.lbl = QtGui.QTextBrowser(self)
self.lbl.resize(760,40)
self.lbl.move(20,440)
while True:
self.lbl.clear()
with open ("/tmp/py.state.test", "r") as myfile:
data=myfile.read().replace('\n', '')
self.lbl.append(data)
time.sleep(10)
请注意,上面的代码没有考虑上面第1点中提出的必要修改,并且可能会导致程序崩溃。与self.lbl
的所有操作都需要移动到主线程中,您需要使用QThread
,以便定义和发出自定义信号。
希望这有助于未来的线程化工作,但在这种情况下,使用QTimer
是最简单的选择,前提是文本文件的读取不会成为瓶颈。