在连接到单个数据模型的多个对话框上更新多个视图

时间:2013-03-28 01:41:30

标签: python model-view-controller model pyqt qcombobox

我有两个表单,两个视图连接到同一个dataModel类,但是当我在一个表单上更改数据时,它不会在另一个表单上更改。

我正在尝试在几个不同的对话框/表单上获取一个comboBox,以便在底层数据从另一个对话框/表单更改时进行更新。

这是我的代码:

class Model(QStringListModel):

    def __init__(self, parent=None):
        super(Model, self).__init__(parent)
        data = QStringList()
        data << "one" << "two" << "three" << "four" << "five"
        self.setStringList(data)


class Form_2(QDialog):

    def __init__(self, parent=None):
        super(Form_2, self).__init__(parent)
        self.model = Model()
        self.combo = QListView()
        self.combo.setModel(self.model)

        layout = QVBoxLayout()
        layout.addWidget(self.combo)
        self.setLayout(layout)


class Form_1(QDialog):

    def __init__(self, parent=None):
        super(Form_1, self).__init__(parent)
        self.model = Model()
        self.listView = QListView()
        self.listView.setModel(self.model)
        self.combo = QComboBox()
        self.combo.setModel(self.model)
        self.form2_button = QPushButton("Open Form_2")

        layout = QVBoxLayout()
        layout.addWidget(self.listView)
        layout.addWidget(self.combo)
        layout.addWidget(self.form2_button)
        self.setLayout(layout)

        self.connect(self.form2_button, SIGNAL("clicked()"), self.form_2)

    def form_2(self):
        self.ft = Form_2()
        self.ft.show()


app = QApplication(sys.argv)
form = Form_1()
form.show()
app.exec_()

2 个答案:

答案 0 :(得分:0)

以下是基于相同模型的多个视图在修改任何视图时如何更新自身的基本示例:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

from PyQt4 import QtGui, QtCore

class MyDialog(QtGui.QWidget):
    def __init__(self, modelSource, parent=None):
        super(MyDialog, self).__init__(parent)

        self.tableView = QtGui.QTableView(self)
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.setModel(modelSource)

        self.listView = QtGui.QListView(self)
        self.listView.setModel(modelSource)
        self.listView.setModelColumn(0)

        self.comboBox = QtGui.QComboBox(self)
        self.comboBox.setModel(modelSource)
        self.comboBox.setModelColumn(1)

        self.layoutGrid = QtGui.QGridLayout(self)
        self.layoutGrid.addWidget(self.comboBox, 0, 0, 1, 2)
        self.layoutGrid.addWidget(self.listView, 1, 0, 1, 1)
        self.layoutGrid.addWidget(self.tableView, 1, 1, 1, 1)

class MyWindow(QtGui.QWidget):
    _dialogs = []
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)

        self.modelSource = QtGui.QStandardItemModel(self)

        for rowNumber in range(3):
            items = []
            for columnNumber in range(3):
                item = QtGui.QStandardItem()
                item.setText("row: {0} column {1}".format(rowNumber, columnNumber))

                items.append(item)

            self.modelSource.appendRow(items)

        self.labelDialogs = QtGui.QLabel(self)
        self.labelDialogs.setText("Select a number of dialogs to create:")

        self.spinBoxDialogs = QtGui.QSpinBox(self)
        self.spinBoxDialogs.setValue(3)

        self.pushButtonShow = QtGui.QPushButton(self)
        self.pushButtonShow.setText("Show Dialogs!")
        self.pushButtonShow.clicked.connect(self.on_pushButtonShow_clicked)

        self.pushButtonClose = QtGui.QPushButton(self)
        self.pushButtonClose.setText("Close Dialogs")
        self.pushButtonClose.clicked.connect(self.on_pushButtonClose_clicked)

        self.layoutHorizontal = QtGui.QHBoxLayout(self)
        self.layoutHorizontal.addWidget(self.labelDialogs)
        self.layoutHorizontal.addWidget(self.spinBoxDialogs)
        self.layoutHorizontal.addWidget(self.pushButtonShow)
        self.layoutHorizontal.addWidget(self.pushButtonClose)

    @QtCore.pyqtSlot()
    def on_pushButtonShow_clicked(self): 
        self._dialogs = []
        dialogsNumber = self.spinBoxDialogs.value()

        for dialogNumber in range(dialogsNumber):  
            dialog = MyDialog(self.modelSource)
            dialog.show()
            dialog.move(100, 100)

            self._dialogs.append(dialog)

    @QtCore.pyqtSlot()
    def on_pushButtonClose_clicked(self): 
        for dialog in self._dialogs:
            dialog.close()

        self._dialogs = []

if __name__ == "__main__":
    import sys

    app = QtGui.QApplication(sys.argv)
    app.setApplicationName('MyWindow')

    main = MyWindow()
    main.show()

    sys.exit(app.exec_())

答案 1 :(得分:0)

感谢ccc.larc给我答案。我们基本上只需要使用模型的一个实例,如果有多个模型实例则不起作用。所以你总是要传递你希望它使用的模型的同一个实例。

如果我理解正确这是@ X.Jacobs所说的,我只是展示我的新代码,这更简单,可以更好地理解与我之前的代码形成鲜明对比(不起作用)

所以我上面的代码只需要稍作改动。

class Model(QStringListModel):

    def __init__(self, parent=None): 
        super(Model, self).__init__(parent)
        data = QStringList()
        data << "one" << "two" << "three" << "four" << "five"
        self.setStringList(data)


class Form_2(QDialog):

    def __init__(self, model, parent=None): #get the model from the calling form
        super(Form_2, self).__init__(parent)
        self.model = model
        self.combo = QListView()
        self.combo.setModel(self.model)

        layout = QVBoxLayout()
        layout.addWidget(self.combo)
        self.setLayout(layout)


class Form_1(QDialog):

    def __init__(self, parent=None):
        super(Form_1, self).__init__(parent)
        self.model = Model()
        self.listView = QListView()
        self.listView.setModel(self.model)
        self.combo = QComboBox()
        self.combo.setModel(self.model)
        self.form2_button = QPushButton("Open Form_2")

        layout = QVBoxLayout()
        layout.addWidget(self.listView)
        layout.addWidget(self.combo)
        layout.addWidget(self.form2_button)
        self.setLayout(layout)

        self.connect(self.form2_button, SIGNAL("clicked()"), self.form_2)

    def form_2(self):
        self.ft = Form_2(self.model) #pass the same model to the new form
        self.ft.show()


app = QApplication(sys.argv)
form = Form_1()
form.show()
app.exec_()