PyQt QTreeWidget.clear() 导致崩溃
我已经安装了 python 2.5 和 PyQt 4.8.6。操作系统 - Windows XP Sp2。我使用以下代码来填充TreeWidget:
def updateTreeWidget(self, widget, results):
""" Updates the widget with given results """
widget.clear()
for item in results:
temp = QtGui.QTreeWidgetItem()
j = 0
for elem in item:
temp.setText(j , str(elem))
j += 1
widget.addTopLevelItem(temp)
for column in range(widget.columnCount()):
widget.resizeColumnToContents(column)
它会在第二次使用它时导致崩溃。如果我注释掉以下行之一:
widget.addTopLevelItem(temp)
或者
widget.clear()
它可以正常工作。
我每 60 秒调用一次线程中的函数。这是 MyThread 类的定义。
class MyThread(threading.Thread):
def __init__(self, db, widget, function, script, parameter):
threading.Thread.__init__(self)
self.db = db
self.function = function
self.script = script
self.parameter = parameter
self.widget = widget
self.event = threading.Event()
def run(self):
while 1:
self.event.wait(60)
parameter = [getCurrentTimeStr()] + self.parameter
res = self.db.getQuery(self.script % tuple(parameter))
self.function(self.widget, res)
该线程在主窗口 init() 中启动:
class MainWnd(QtGui.QMainWindow):
def __init__(self, parent = None):
# some code
self.db = DbAccess()
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_mainWnd()
self.ui.setupUi(self)
self.thread = MyThread(self.db, self.ui.treeWidget, self.updateTreeWidget, self.script, self.param)
self.thread.start()
该小部件是使用 Qt Designer 创建的。
I've got python 2.5 and PyQt 4.8.6 installed. Os - Windows Xp Sp2. I use the following code to fill TreeWidget:
def updateTreeWidget(self, widget, results):
""" Updates the widget with given results """
widget.clear()
for item in results:
temp = QtGui.QTreeWidgetItem()
j = 0
for elem in item:
temp.setText(j , str(elem))
j += 1
widget.addTopLevelItem(temp)
for column in range(widget.columnCount()):
widget.resizeColumnToContents(column)
It causes crashes at the second use of it. If I comment out one of the following lines:
widget.addTopLevelItem(temp)
or
widget.clear()
it works without problems.
I call the function in the thread every 60s. Here is the definition of MyThread class.
class MyThread(threading.Thread):
def __init__(self, db, widget, function, script, parameter):
threading.Thread.__init__(self)
self.db = db
self.function = function
self.script = script
self.parameter = parameter
self.widget = widget
self.event = threading.Event()
def run(self):
while 1:
self.event.wait(60)
parameter = [getCurrentTimeStr()] + self.parameter
res = self.db.getQuery(self.script % tuple(parameter))
self.function(self.widget, res)
This thread is started when in main window init():
class MainWnd(QtGui.QMainWindow):
def __init__(self, parent = None):
# some code
self.db = DbAccess()
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_mainWnd()
self.ui.setupUi(self)
self.thread = MyThread(self.db, self.ui.treeWidget, self.updateTreeWidget, self.script, self.param)
self.thread.start()
The widget was created using Qt Designer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
从与 Qt 事件循环不同的线程更新 GUI 元素是一个很大的禁忌。
解决此问题的惯用方法是使用排队信号/槽连接或单次 QTimer 来传递线程边界并在主线程上执行函数。
Updating GUI elements from a thread that is not the same as Qt's event loop is a big no-no.
The customary way to solve this is to used a queued signal/slot connection or a singleshot QTimer to pass thread boundaries and execute your function on the main thread.