使用QToolBar和QListView导航面包屑 [英] Breadcrumbs navigation using QToolBar and QListView
问题描述
我有类似这样的JSON数据
I have JSON data something like this
{"books":{
"web":{
"front-end":{
"html":["the missing manual", "core html5 canvas"],
"css":["css pocket reference", "css in depth"],
"js":["you don't know js", "eloquent javascript"]
},
"back-end":{
"php":["modern php", "php web services"],
"python":["dive into python", "python for everybody",
"Think Python", "Effective Python", "Fluent Python"]
}
},
"database":{
"sql":{
"mysql":["mysql in a nutshell", "mysql cookbook"],
"postgresql":["postgresql up and running", "practical postgresql"]
},
"nosql":{
"mongodb":["mongodb in action", "scaling mongodb"],
"cassandra":["practical cassandra", "mastering cassandra"]
}}}}
现在,我想使用QAbstractListModel
和QToolBar
作为面包屑导航(QAction)在QListView
中填充此数据. QListView
将以用户身份更新
触发键.那么我该如何实现呢?
Now I want to populate this data in QListView
using QAbstractListModel
with the QToolBar
as breadcrumb navigation (QAction). QListView
will update as user
triggers key. So how can I implement this?
推荐答案
第一件事是将json转换为模型,在这种情况下使用QStandardItemModel
.然后,我们在QListView
中使用该模型,并使用setRootIndex()
指示将要显示的项目,另一方面,使用父树将QActions
添加到QToolBar
中.
The first thing is to convert the json into a model, in this case QStandardItemModel
is used. Then we use that model in the QListView
using setRootIndex()
to indicate the items that will be displayed, on the other hand QActions
are added to the QToolBar
using the parent tree.
from PyQt5 import QtCore, QtGui, QtWidgets
data = {"books":{
"web":{
"front-end":{
"html":["the missing manual", "core html5 canvas"],
"css":["css pocket reference", "css in depth"],
"js":["you don't know js", "eloquent javascript"]
},
"back-end":{
"php":["modern php", "php web services"],
"python":["dive into python", "python for everybody",
"Think Python", "Effective Python", "Fluent Python"]
}
},
"database":{
"sql":{
"mysql":["mysql in a nutshell", "mysql cookbook"],
"postgresql":["postgresql up and running", "practical postgresql"]
},
"nosql":{
"mongodb":["mongodb in action", "scaling mongodb"],
"cassandra":["practical cassandra", "mastering cassandra"]
}}}}
def dict_to_model(item, d):
if isinstance(d, dict):
for k, v in d.items():
it = QtGui.QStandardItem(k)
item.appendRow(it)
dict_to_model(it, v)
elif isinstance(d, list):
for v in d:
dict_to_model(item, v)
else:
item.appendRow(QtGui.QStandardItem(str(d)))
class Navigation(QtCore.QObject):
clicked = QtCore.pyqtSignal(QtCore.QModelIndex)
def __init__(self, json_data, parent=None):
super(Navigation, self).__init__(parent)
self.toolbar = QtWidgets.QToolBar()
self.toolbar.actionTriggered.connect(self.on_actionTriggered)
self.model = QtGui.QStandardItemModel(self)
dict_to_model(self.model.invisibleRootItem(), json_data)
it = self.model.item(0, 0)
ix = self.model.indexFromItem(it)
root_action = self.toolbar.addAction(it.text())
root_action.setData(QtCore.QPersistentModelIndex(ix))
self.listview = QtWidgets.QListView()
self.listview.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.listview.clicked.connect(self.on_clicked)
self.listview.setModel(self.model)
self.listview.setRootIndex(ix)
@QtCore.pyqtSlot(QtCore.QModelIndex)
def on_clicked(self, index):
if not self.model.hasChildren(index):
self.clicked.emit(index)
return
action = self.toolbar.addAction(index.data())
action.setData(QtCore.QPersistentModelIndex(index))
self.listview.setRootIndex(index)
@QtCore.pyqtSlot(QtWidgets.QAction)
def on_actionTriggered(self, action):
ix = action.data()
model = ix.model()
self.listview.setRootIndex(QtCore.QModelIndex(ix))
self.toolbar.clear()
ixs = []
while ix.isValid():
ixs.append(ix)
ix = ix.parent()
for ix in reversed(ixs):
action = self.toolbar.addAction(ix.data())
action.setData(ix)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
navigation = Navigation(data, self)
navigation.clicked.connect(self.on_clicked)
tree_view = QtWidgets.QTreeView()
tree_view.setModel(navigation.model)
navigation.model.setHorizontalHeaderLabels(["Tree Example"])
tree_view.expandAll()
self.addToolBar(navigation.toolbar)
widget = QtWidgets.QWidget()
self.setCentralWidget(widget)
lay = QtWidgets.QHBoxLayout(widget)
lay.addWidget(navigation.listview)
lay.addWidget(tree_view)
@QtCore.pyqtSlot(QtCore.QModelIndex)
def on_clicked(self, index):
print(index.data())
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
这篇关于使用QToolBar和QListView导航面包屑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!