简体   繁体   English

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

[英]How to change a QTreeView model on an action triggered signal in PyQt5?

I am trying to build a PyQt5 application that would display a tree view and populate it dynamically on a button press. 我正在尝试构建一个PyQt5应用程序,该应用程序将显示树视图并在按下按钮时动态填充它。 But it crashes (Process finished with exit code 134 (interrupted by signal 6: SIGABRT)) whenever I try to set or populate the model from within a function assigned to an action triggered signal (although it works just fine if I instantiate the model, load the data and assign the model to the TreeView in the window __init__ itself rather than in a function assigned to a signal). 但是,每当我尝试从分配给动作触发信号的函数中设置或填充模型时,它就会崩溃(进程以退出代码134(信号6:SIGABRT中断)完成)(尽管如果实例化该模型就可以了,加载数据,然后在__init__窗口本身而不是在分配给信号的函数中将模型分配给TreeView。 How do I achieve the desired behaviour? 我如何实现期望的行为? The whole model content (including the set of columns) is meant to completely change often during runtime. 整个模型的内容(包括列集)应在运行时经常发生完全更改。 The UI is designed in Qt Designer and generated with pyuic5. UI是在Qt Designer中设计的,并使用pyuic5生成。

Here is my window code: 这是我的窗口代码:

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()

Here is my model code: 这是我的模型代码:

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')])

I recommend you execute your code in the CMD or terminal in these cases since many IDEs have limitations in these cases. 在这种情况下,建议您在CMD或终端中执行代码,因为许多IDE在这些情况下都有局限性。 By running it you get this error message: 通过运行它,您会收到以下错误消息:

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)

A static method indicates that this method does not belong to an object of the class but to the class itself, and if you want to modify an object it should not be a static method so remove that decorator. 静态方法表示此方法不属于该类的对象,而是属于类本身,并且,如果要修改对象,则不应是静态方法,因此请删除该装饰器。 On the other hand you must connect the signal to the slot by using self. 另一方面,您必须使用self将信号连接到插槽。

The solution is the next: 解决方案是下一个:

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM