如何在PyQt5中的动作触发信号上更改QTreeView模型?

时间:2018-11-21 05:13:55

标签: python pyqt5 qtreeview

我正在尝试构建一个PyQt5应用程序,该应用程序将显示树视图并在按下按钮时动态填充它。但是,每当我尝试从分配给动作触发信号的函数中设置或填充模型时,它就会崩溃(进程以退出代码134(信号6:SIGABRT中断)完成)(尽管如果实例化该模型就可以了,加载数据,然后在窗口__init__本身而不是在分配给信号的函数中将模型分配给TreeView。我如何实现期望的行为?整个模型的内容(包括列集)应在运行时经常发生完全更改。该用户界面是在Qt Designer中设计的,并使用pyuic5生成。

这是我的窗口代码:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        #  model = MyModel() #  UPDATE: useless, this wasn't here in the last pre-question version of the code actually
        self.ui.actionLoad.triggered.connect(MainWindow.load) # UPDATE: Here is a mistake - should be self.load, not MainWindow.load

    #  @staticmethod #  UPDATE: this wasn't here in the last pre-question version of the code actually
    def load(self):
        model = MyModel()
        self.ui.treeViewLeft.setModel(model)
        self.model.load() # UPDATE: Here is a mistake - should be model.load(), not self.model.load()

这是我的模型代码:

class MyModel(QStandardItemModel):
    def __init__(self, *args, **kwargs):
        super(MyModel, self).__init__(*args, **kwargs)

    def load(self):
        self.clear()
        self.setHorizontalHeaderLabels(["Name", "Attr1", "Attr2"])
        self.appendRow([QStandardItem('item1'), QStandardItem('attr11'), QStandardItem('attr21')])
        self.appendRow([QStandardItem('item2'), QStandardItem('attr12'), QStandardItem('attr22')])
        self.appendRow([QStandardItem('item3'), QStandardItem('attr13'), QStandardItem('attr23')])

1 个答案:

答案 0 :(得分:0)

在这种情况下,建议您在CMD或终端中执行代码,因为许多IDE在这些情况下都有局限性。通过运行它,您会收到以下错误消息:

Traceback (most recent call last):
  File "main.py", line 29, in load
    self.ui.treeViewLeft.setModel(model)
AttributeError: 'bool' object has no attribute 'ui'
Aborted (core dumped)

静态方法指示此方法不属于类的对象,而是属于类本身,并且,如果要修改对象,则它不应是静态方法,因此请删除该装饰器。另一方面,您必须使用self将信号连接到插槽。

下一个解决方案是

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        model = MyModel()
        self.ui.actionLoad.triggered.connect(self.load)

    def load(self):
        model = MyModel(self)
        self.ui.treeViewLeft.setModel(model)
        model.load()