一个模型,两个不同的视图 - PySide

Posted

技术标签:

【中文标题】一个模型,两个不同的视图 - PySide【英文标题】:One Model, two different views - PySide 【发布时间】:2018-01-31 19:42:47 【问题描述】:

我有 4 列的 QAbstractTableModel。

我正在尝试在视图 (QTableView) 上显示前 3 列,当在此类视图中选择一行时,第二个视图 (QListView) 应显示模型的第 4 列。

我发现了一些关于 QProxyModel 的东西,但我很难把我的想法包起来。还有一个“解决方案”,我发现了类似的东西HERE,但不知何故我想要相反的结果。

我试图显示的数据是这样的: [['green', 'car', 'available',['a','b','c','d']]]]

因此,在 Table View 上它会显示:绿色 - 汽车 - 可用。 当点击这样的行时,列表视图会在最后一个位置显示数组:a - b - c - d。

我希望这是有道理的。

有关说明、文档、示例的提示?

感谢您的宝贵时间。

【问题讨论】:

【参考方案1】:

对于这种特殊情况,使用代理模型是不合适的,每次点击应该做的是获取QModelIndex,使用QModelIndex我们获取模型和按下的行以便在最后我们获得保存的列表,我们可以将此列表作为源传递给模型QStringListModel,我们将在QListView 中建立它。要隐藏列,我们使用QTableView 中的hideColumn()

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *


class TableModel(QAbstractTableModel):
    def __init__(self, *args, **kwargs):
        QAbstractTableModel.__init__(self, *args, **kwargs)

        self.values = [['green', 'car', 'available', ['a', 'b', 'c', 'd']],
                       ['red', 'airplane', 'available', ['b', 'c', 'd', 'e']],
                       ['yellow', 'boat', 'not available', ['c', 'd', 'e', 'f']]]

    def columnCount(self, parent=QModelIndex()):
        return 4

    def rowCount(self, parent=QModelIndex()):
        return len(self.values)

    def data(self, index, role=Qt.DisplayRole):
        if 0 <= index.row() < self.rowCount() and 0 <= index.column() < self.columnCount():
            if role == Qt.DisplayRole:
                return self.values[index.row()][index.column()]


class Widget(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        splitter = QSplitter()
        self.tv = QTableView()
        self.lv = QListView()
        self.setLayout(QHBoxLayout())
        splitter.addWidget(self.tv)
        splitter.addWidget(self.lv)
        self.layout().addWidget(splitter)
        model = TableModel()
        self.tv.setModel(model)
        self.tv.hideColumn(3)

        self.tv.clicked.connect(self.on_clicked)

    def on_clicked(self, ix):
        model = ix.model()
        m_list = model.index(ix.row(), 3).data()
        self.lv.setModel(QStringListModel(m_list))


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

【讨论】:

男人!又是你!谢谢你这么棒的回答。赞成。 很抱歉打扰您,但您的帮助很棒。您能否指出如何构建一个 ItemDelegate 的方向,它只是一个正方形的颜色,单击时允许我选择它将显示的颜色?我试图理解 Paint 方法,但从字面上看,它似乎是编码的......很难开始。 ...好吧,无论如何,谢谢。

以上是关于一个模型,两个不同的视图 - PySide的主要内容,如果未能解决你的问题,请参考以下文章

如何保存 PySide 树视图模型结构

python 普通的PySide模型/视图

使用 PySide2 和 QTableView 如何使用 pandas 模型在表格视图中获得多个委托?

使用 Pyside 的 Qt 树视图

在 Qt 中使用不同模型访问另一个列表视图的委托中的列表视图模型数据

PySide 填空 TableModel