TreeWidget 快速更新导致崩溃

问题描述

在我生命的最后一年构建了一个使用 TreeWidget 快速显示数据的 pyside2 应用程序后,我陷入了死胡同。启动应用程序后,数据将毫无问题地附加。然而,几分钟后,程序变得非常不稳定/缓慢,最终变得无响应。有时它会彻底崩溃并关闭。没有错误消息、堆栈跟踪或日志可以关闭。 (是否有某种类型的日志我应该探索?)

发生冻结时,cpu 使用率从大约 9% 跃升至 20%。

如果程序最小化或光标与 TreeWidget 交互,问题就会出现。 TreeWidget 似乎跟不上添加数据的频率。

最初,我认为问题出在 scrollToItem(如果没有它,程序似乎稍微稳定一些),但是当我构建下面的示例进行说明时,我无法让它像在我的主程序上那样崩溃.这非常令人沮丧,因为我不知道我的代码的哪一部分可能会以与示例不同的方式影响应用程序。

在示例中,当窗口未聚焦或最小化时,您可能会注意到一些卡顿现象。但是,当焦点返回到窗口时,它总是恢复正常。 在我的主程序中,它将无限期挂起。 与示例一样,将数据推送到 TreeWidget 的机制是通过发出信号在另一个线程中实现的。 (除了一个类用于保存所有线程共享的所有信号 - 我认为这应该不是问题,对吧?)

我还可能错过什么?在不发布整个项目的情况下,如何缩小问题范围? QTreeView性能有影响吗?有没有像 ListView 这样的多列替代品?

from pyside2 import QtCore,QtWidgets,QtGui
import random

class MainWindow(QtWidgets.QApplication):
    def __init__(self):
        super().__init__()

        win = QtWidgets.QMainWindow()
        v = CANView()
        b = QtWidgets.QPushButton('Go')
        b.clicked.connect(self.onButtonPush)

        g = QtWidgets.QVBoxLayout()
        g.addWidget(b)
        g.addWidget(v)

        f = QtWidgets.qframe()
        f.setLayout(g)
        win.setCentralWidget(f)
        win.show()

        self.thread = CANThread()
        self.thread.newMessageSignal.connect(v.onFrame)

        self.exec_()

    def onButtonPush(self):
        self.thread.start()


class CANView(QtWidgets.QTreeWidget):
    def __init__(self):
        super().__init__()
        self.setHeaderLabels(['Timestamp','CAN ID','Data'])
        self.setIndentation(0)


    def onFrame(self,a,b,c):
        treeItem = RandomItem(a,c)
        if(self.invisibleRootItem().childCount() > 5000):
            self.taketopLevelItem(0)
        self.addTopLevelItem(treeItem)
        self.scrollToItem(treeItem,QtWidgets.QAbstractItemView.ScrollHint.PositionAtBottom)



class CANThread(QtCore.QThread):
    newMessageSignal = QtCore.Signal(int,int,int)

    def __init__(self):
        super().__init__()
        self.counter = 0


    def run(self):
        while(True):
            self.newMessageSignal.emit(self.counter,random.randint(0,0x7FFFFFFF),0x7FFFFFFF))
            self.counter += 1
            QtCore.QThread.msleep(random.randint(0,15))


fontMono = QtGui.QFont('Lucida Console')
colorLightFont = QtGui.QColor('#888888')
class RandomItem(QtWidgets.QTreeWidgetItem):
    def __init__(self,c):
        super().__init__()
        self.setText(0,f'{a:X}')
        self.setText(1,f'{b:X}')
        self.setText(2,f'{c:X}')
        self.setFont(1,fontMono)
        self.setFont(2,fontMono)

    
if __name__ == '__main__':
    MainWindow()

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...