为上一个问题PySide2 QListView和QTableView添加功能 [英] add feature for previous question PySide2 QListView and 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屋!