为上一个问题PySide2 QListView和QTableView添加功能 [英] add feature for previous question PySide2 QListView and QTableView

查看:1363
本文介绍了为上一个问题PySide2 QListView和QTableView添加功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上一个问题是 PySide2 QListView QTableView同步问题

想象一下在数据结构中还有另一个dict4:

Imagine to have another dict4 in the data structure:

'dict4':{'k8':'v8', 'EXISTING_DICT':'dict2'},

意思是,一个词典可以包括另一个现有的词典.

Meaning, that a dictionary could include another existing dictionary.

因此,不应直接显示QTableView中的表示形式,而是:

So the representation in the QTableView shouldn't be directly showed, but:

1)在QTableView中仅显示其名称:

1) Show just the name of it in the QTableView:

k1 | v1
-------
k2 | v2
-------
k3 | v3
-------
dict2

2)如果双击它:在QListView中选择现有字典,这将触发以在QTableView中显示其内容,在这种情况下:

2) If double click it on it: select the existing dictionary in the QListView, which will trigger to show its contents in the QTableView, which in this case:

k4 | v4

推荐答案

在这种情况下,想法是使用一个角色来指示该字段指向另一个项目,然后使用setSpan联接项目,最后检查是否选择了该项目通过选择是否在QTableView中指向另一个元素

In this case the idea is to use a role to indicate that the field points to another item, then use setSpan to join items and finally check if the item selected in the QTableView points to another element by selecting if it is so

from PySide2 import QtCore, QtGui, QtWidgets

dict_of_dicts={
    'dict1':{'k1':'v1', 'k2':'v2', 'k3':'v3', 'EXISTING_DICT': 'dict3'},
    'dict2':{'k4':'v4', 'EXISTING_DICT': 'dict1'},
    'dict3':{'k5':'v5', 'k6':'v6', 'k7':'v7', 'EXISTING_DICT': 'dict4'},
    'dict4':{'k8':'v8', 'EXISTING_DICT':'dict2'},
}

def create_model_from_dict(d, parent=None):
    model = QtGui.QStandardItemModel(0, 2, parent)
    for k, v in dict_of_dicts.items():
        it = QtGui.QStandardItem(k)
        model.appendRow(it)
        for k_, v_ in v.items():
            if k_ != "EXISTING_DICT":
                it.appendRow([QtGui.QStandardItem(k_), QtGui.QStandardItem(v_)])
            else:
                child_it = QtGui.QStandardItem(v_)
                child_it.setTextAlignment(QtCore.Qt.AlignCenter)
                child_it.setData(True, QtCore.Qt.UserRole + 1000)
                it.appendRow(child_it)
    return model

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        model = create_model_from_dict(dict_of_dicts, self)

        self.tableview = QtWidgets.QTableView()
        self.tableview.setModel(model)
        self.tableview.selectionModel().selectionChanged.connect(self.handleSelectionChangedTV)

        self.listview = QtWidgets.QListView()
        self.listview.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.listview.setModel(model)
        self.listview.selectionModel().selectionChanged.connect(self.handleSelectionChangedLV)
        self.listview.selectionModel().select(model.index(0, 0), QtCore.QItemSelectionModel.Select)

        hlay = QtWidgets.QHBoxLayout(self)
        hlay.addWidget(self.listview)
        hlay.addWidget(self.tableview)

    @QtCore.Slot(QtCore.QItemSelection)
    def handleSelectionChangedLV(self, item):
        ixs = item.indexes()
        if ixs:
            self.tableview.setRootIndex(ixs[0])
            model = self.tableview.model()
            self.tableview.clearSpans()
            for r in range(model.rowCount(self.tableview.rootIndex())):
                index = model.index(r, 0, self.tableview.rootIndex())
                if index.data(QtCore.Qt.UserRole + 1000):
                    self.tableview.setSpan(r, 0, 1, 2)

    @QtCore.Slot(QtCore.QItemSelection)
    def handleSelectionChangedTV(self, item):
        ixs = item.indexes()
        if ixs:
            ix = ixs[0]
            if ix.data(QtCore.Qt.UserRole + 1000):
                items = self.listview.model().findItems(ix.data())
                if items:
                    self.tableview.clearSelection()
                    self.listview.selectionModel().select(items[0].index(), QtCore.QItemSelectionModel.ClearAndSelect)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

更新:

from PySide2 import QtCore, QtGui, QtWidgets

dict_of_dicts={
    'dict1':{'k1':'v1', 'k2':'v2', 'k3':'v3', 'EXISTING_DICT': 'dict3'},
    'dict2':{'k4':'v4', 'EXISTING_DICT': 'dict1'},
    'dict3':{'k5':'v5', 'k6':'v6', 'k7':'v7', 'EXISTING_DICT': 'dict4'},
    'dict4':{'k8':'v8', 'EXISTING_DICT':'dict2'},
}

def create_model_from_dict(d, parent=None):
    model = QtGui.QStandardItemModel(0, 2, parent)
    for k, v in dict_of_dicts.items():
        it = QtGui.QStandardItem(k)
        model.appendRow(it)
        for k_, v_ in v.items():
            if k_ != "EXISTING_DICT":
                it.appendRow([QtGui.QStandardItem(k_), QtGui.QStandardItem(v_)])
            else:
                child_it = QtGui.QStandardItem(v_)
                child_it.setTextAlignment(QtCore.Qt.AlignCenter)
                child_it.setData(True, QtCore.Qt.UserRole + 1000)
                it.appendRow(child_it)
    return model

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        model = create_model_from_dict(dict_of_dicts, self)

        self.tableview = QtWidgets.QTableView()
        self.tableview.setModel(model)
        self.tableview.doubleClicked.connect(self.handleSelectionChangedTV)

        self.listview = QtWidgets.QListView()
        self.listview.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.listview.setModel(model)
        self.listview.selectionModel().selectionChanged.connect(self.handleSelectionChangedLV)
        self.listview.selectionModel().select(model.index(0, 0), QtCore.QItemSelectionModel.Select)

        hlay = QtWidgets.QHBoxLayout(self)
        hlay.addWidget(self.listview)
        hlay.addWidget(self.tableview)

    @QtCore.Slot(QtCore.QItemSelection)
    def handleSelectionChangedLV(self, item):
        ixs = item.indexes()
        if ixs:
            self.tableview.setRootIndex(ixs[0])
            model = self.tableview.model()
            self.tableview.clearSpans()
            for r in range(model.rowCount(self.tableview.rootIndex())):
                index = model.index(r, 0, self.tableview.rootIndex())
                if index.data(QtCore.Qt.UserRole + 1000):
                    self.tableview.setSpan(r, 0, 1, 2)

    @QtCore.Slot(QtCore.QModelIndex)
    def handleSelectionChangedTV(self, ix):
        if ix.data(QtCore.Qt.UserRole + 1000):
            items = self.listview.model().findItems(ix.data())
            if items:
                self.tableview.clearSelection()
                self.listview.selectionModel().select(items[0].index(), QtCore.QItemSelectionModel.ClearAndSelect)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

UPDATE2

from PySide2 import QtCore, QtGui, QtWidgets

dict_of_dicts={
    'dict1':{'k1':'v1', 'k2':'v2', 'k3':'v3', 'EXISTING_DICT': 'dict3'},
    'dict2':{'k4':'v4', 'EXISTING_DICT': 'dict1'},
    'dict3':{'k5':'v5', 'k6':'v6', 'k7':'v7', 'EXISTING_DICT': 'dict4'},
    'dict4':{'k8':'v8', 'EXISTING_DICT':'dict2'},
}

def create_model_from_dict(d, parent=None):
    model = QtGui.QStandardItemModel(0, 2, parent)
    for k, v in dict_of_dicts.items():
        it = QtGui.QStandardItem(k)
        model.appendRow(it)
        for k_, v_ in v.items():
            if k_ != "EXISTING_DICT":
                it.appendRow([QtGui.QStandardItem(k_), QtGui.QStandardItem(v_)])
            else:
                child_it = QtGui.QStandardItem(v_)
                child_it.setTextAlignment(QtCore.Qt.AlignCenter)
                child_it.setData(True, QtCore.Qt.UserRole + 1000)
                it.appendRow(child_it)
    return model

class TableView(QtWidgets.QTableView):
    leftDoubleClicked = QtCore.Signal(QtCore.QModelIndex)

    def mouseDoubleClickEvent(self, event):
        super(TableView, self).mouseDoubleClickEvent(event)
        if event.buttons() & QtCore.Qt.LeftButton:
            ix = self.indexAt(event.pos())
            if ix.isValid(): self.leftDoubleClicked.emit(ix)

class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        model = create_model_from_dict(dict_of_dicts, self)

        self.tableview = TableView()
        self.tableview.setModel(model)
        self.tableview.leftDoubleClicked.connect(self.handleSelectionChangedTV)

        self.listview = QtWidgets.QListView()
        self.listview.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.listview.setModel(model)
        self.listview.selectionModel().selectionChanged.connect(self.handleSelectionChangedLV)
        self.listview.selectionModel().select(model.index(0, 0), QtCore.QItemSelectionModel.Select)

        hlay = QtWidgets.QHBoxLayout(self)
        hlay.addWidget(self.listview)
        hlay.addWidget(self.tableview)

    @QtCore.Slot(QtCore.QItemSelection)
    def handleSelectionChangedLV(self, item):
        ixs = item.indexes()
        if ixs:
            self.tableview.setRootIndex(ixs[0])
            model = self.tableview.model()
            self.tableview.clearSpans()
            for r in range(model.rowCount(self.tableview.rootIndex())):
                index = model.index(r, 0, self.tableview.rootIndex())
                if index.data(QtCore.Qt.UserRole + 1000):
                    self.tableview.setSpan(r, 0, 1, 2)

    @QtCore.Slot(QtCore.QModelIndex)
    def handleSelectionChangedTV(self, ix):
        if ix.data(QtCore.Qt.UserRole + 1000):
            items = self.listview.model().findItems(ix.data())
            if items:
                self.tableview.clearSelection()
                self.listview.selectionModel().select(items[0].index(), QtCore.QItemSelectionModel.ClearAndSelect)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

这篇关于为上一个问题PySide2 QListView和QTableView添加功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆