通过 QStardItemModel() 在 QTreeView()-Object 中存储和检索 items/rows 上的数据
store and retrieve data on items/rows in a QTreeView()-Object via QStardItemModel()
我正在将 SQLite 数据库中的数据填充到 PyQt5 TreeView 控件 (QTreeView) 中。
数据通过 QStandardItemModel() 写入。
问题:我想记住每行的 row_id,而不显示它。
我曾经在查询中 select 它但隐藏了该列。
但是当从索引为 0 的列中查询 row_id 时,这会失败,因为它不可见。
我不知道 a.) 如何存储 row_id 以便 b.) 稍后检索它。
我想遍历 selected 行并使用相应的 row_id 执行一些操作(例如批量删除、批量编辑、批量复制等)
model.setData 总是需要一个列索引...Qt.UserRole 似乎无法检索数据。
代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class App(QWidget):
MAIL_RANGE = 4
ID, FROM, SUBJECT, DATE = range(MAIL_RANGE)
def __init__(self):
super().__init__()
self.left = 10
self.top = 10
self.width = 640
self.height = 240
self.initUI()
self.dataView.setSelectionMode(QAbstractItemView.ExtendedSelection) # <- enable selection of rows in tree
self.dataView.setEditTriggers(QAbstractItemView.NoEditTriggers) # <- disable editing items in tree
for i in range(0, 2):
self.dataView.resizeColumnToContents(i)
self.pbOk = QPushButton(self)
self.pbOk.setText("Ok")
self.pbOk.move(400,0)
self.pbOk.show()
# connect handlers
self.dataView.doubleClicked.connect(self.on_dataView_doubleClicked)
self.pbOk.clicked.connect(self.on_pbOk_clicked)
def on_dataView_doubleClicked(self):
print("on_dataView_doubleClicked() called.")
def on_pbOk_clicked(self):
print("on_pbOk_clicked() called.")
# get all IDs
message: str = ""
col_ind: int = 0
for item in self.dataView.selectedIndexes():
if col_ind % (self.MAIL_RANGE) == 0: # indicates a row beginning
text = item.data(Qt.DisplayRole) # or ix.data()
message = message + "\n" + str(text)
self.create_dialog(text)
col_ind += 1
print(message)
def create_dialog(self, id):
print("dialog called for " + str(id))
myDlg = QDialog(self)
lbl = QLabel(myDlg)
lbl.setText("Hello id: " + str(id))
myDlg.show()
myDlg.resize(300,200)
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
self.dataGroupBox = QGroupBox("Inbox")
self.dataView = QTreeView()
self.dataView.setRootIsDecorated(False)
self.dataView.setAlternatingRowColors(True)
dataLayout = QHBoxLayout()
dataLayout.addWidget(self.dataView)
self.dataGroupBox.setLayout(dataLayout)
model = self.createMailModel(self)
self.dataView.setModel(model)
self.addMail(model, 1, 'service@github.com', 'Your Github Donation','03/25/2017 02:05 PM')
self.addMail(model, 2, 'support@github.com', 'Github Projects','02/02/2017 03:05 PM')
self.addMail(model, 3, 'service@phone.com', 'Your Phone Bill','01/01/2017 04:05 PM')
self.addMail(model, 4, 'service@abc.com', 'aaaYour Github Donation','03/25/2017 02:05 PM')
self.addMail(model, 5, 'support@def.com', 'bbbGithub Projects','02/02/2017 03:05 PM')
self.addMail(model, 6, 'service@xyz.com', 'cccYour Phone Bill','01/01/2017 04:05 PM')
self.dataView.setColumnHidden(0, True)
mainLayout = QVBoxLayout()
mainLayout.addWidget(self.dataGroupBox)
self.setLayout(mainLayout)
self.show()
def createMailModel(self,parent):
model = QStandardItemModel(0, self.MAIL_RANGE, parent)
model.setHeaderData(self.ID, Qt.Horizontal, "ID")
model.setHeaderData(self.FROM, Qt.Horizontal, "From")
model.setHeaderData(self.SUBJECT, Qt.Horizontal, "Subject")
model.setHeaderData(self.DATE, Qt.Horizontal, "Date")
return model
def addMail(self, model, mailID, mailFrom, subject, date):
model.insertRow(0)
model.setData(model.index(0, self.ID), mailID)
model.setData(model.index(0, self.FROM), mailFrom)
model.setData(model.index(0, self.SUBJECT), subject)
model.setData(model.index(0, self.DATE), date)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
总结:
1.) 在 addMail() 上,我想将 ID 添加到插入的行。
2.) 在 on_pbOk_clicked() 事件中,我想遍历 selected 行并获取每一行的所有 ID。
如果我将 ID 添加为单独的列,我以后将无法检索它,因为这不适用于隐藏的列。
当您确定选择是按行进行时,只需获取行并对其进行迭代,在这种情况下,使用 set 获取选定的行并在列上进行迭代。
def on_pbOk_clicked(self):
message: str = ""
rows = set(ix.row() for ix in self.dataView.selectedIndexes())
for row in rows:
values_for_row = []
for col in range(App.MAIL_RANGE):
it = self.dataView.model().item(row, col)
values_for_row.append(it.text())
text = " ".join(values_for_row)
self.create_dialog(text)
message += "\n" + text
print(message)
我正在将 SQLite 数据库中的数据填充到 PyQt5 TreeView 控件 (QTreeView) 中。 数据通过 QStandardItemModel() 写入。
问题:我想记住每行的 row_id,而不显示它。 我曾经在查询中 select 它但隐藏了该列。 但是当从索引为 0 的列中查询 row_id 时,这会失败,因为它不可见。
我不知道 a.) 如何存储 row_id 以便 b.) 稍后检索它。 我想遍历 selected 行并使用相应的 row_id 执行一些操作(例如批量删除、批量编辑、批量复制等)
model.setData 总是需要一个列索引...Qt.UserRole 似乎无法检索数据。
代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class App(QWidget):
MAIL_RANGE = 4
ID, FROM, SUBJECT, DATE = range(MAIL_RANGE)
def __init__(self):
super().__init__()
self.left = 10
self.top = 10
self.width = 640
self.height = 240
self.initUI()
self.dataView.setSelectionMode(QAbstractItemView.ExtendedSelection) # <- enable selection of rows in tree
self.dataView.setEditTriggers(QAbstractItemView.NoEditTriggers) # <- disable editing items in tree
for i in range(0, 2):
self.dataView.resizeColumnToContents(i)
self.pbOk = QPushButton(self)
self.pbOk.setText("Ok")
self.pbOk.move(400,0)
self.pbOk.show()
# connect handlers
self.dataView.doubleClicked.connect(self.on_dataView_doubleClicked)
self.pbOk.clicked.connect(self.on_pbOk_clicked)
def on_dataView_doubleClicked(self):
print("on_dataView_doubleClicked() called.")
def on_pbOk_clicked(self):
print("on_pbOk_clicked() called.")
# get all IDs
message: str = ""
col_ind: int = 0
for item in self.dataView.selectedIndexes():
if col_ind % (self.MAIL_RANGE) == 0: # indicates a row beginning
text = item.data(Qt.DisplayRole) # or ix.data()
message = message + "\n" + str(text)
self.create_dialog(text)
col_ind += 1
print(message)
def create_dialog(self, id):
print("dialog called for " + str(id))
myDlg = QDialog(self)
lbl = QLabel(myDlg)
lbl.setText("Hello id: " + str(id))
myDlg.show()
myDlg.resize(300,200)
def initUI(self):
self.setGeometry(self.left, self.top, self.width, self.height)
self.dataGroupBox = QGroupBox("Inbox")
self.dataView = QTreeView()
self.dataView.setRootIsDecorated(False)
self.dataView.setAlternatingRowColors(True)
dataLayout = QHBoxLayout()
dataLayout.addWidget(self.dataView)
self.dataGroupBox.setLayout(dataLayout)
model = self.createMailModel(self)
self.dataView.setModel(model)
self.addMail(model, 1, 'service@github.com', 'Your Github Donation','03/25/2017 02:05 PM')
self.addMail(model, 2, 'support@github.com', 'Github Projects','02/02/2017 03:05 PM')
self.addMail(model, 3, 'service@phone.com', 'Your Phone Bill','01/01/2017 04:05 PM')
self.addMail(model, 4, 'service@abc.com', 'aaaYour Github Donation','03/25/2017 02:05 PM')
self.addMail(model, 5, 'support@def.com', 'bbbGithub Projects','02/02/2017 03:05 PM')
self.addMail(model, 6, 'service@xyz.com', 'cccYour Phone Bill','01/01/2017 04:05 PM')
self.dataView.setColumnHidden(0, True)
mainLayout = QVBoxLayout()
mainLayout.addWidget(self.dataGroupBox)
self.setLayout(mainLayout)
self.show()
def createMailModel(self,parent):
model = QStandardItemModel(0, self.MAIL_RANGE, parent)
model.setHeaderData(self.ID, Qt.Horizontal, "ID")
model.setHeaderData(self.FROM, Qt.Horizontal, "From")
model.setHeaderData(self.SUBJECT, Qt.Horizontal, "Subject")
model.setHeaderData(self.DATE, Qt.Horizontal, "Date")
return model
def addMail(self, model, mailID, mailFrom, subject, date):
model.insertRow(0)
model.setData(model.index(0, self.ID), mailID)
model.setData(model.index(0, self.FROM), mailFrom)
model.setData(model.index(0, self.SUBJECT), subject)
model.setData(model.index(0, self.DATE), date)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
总结:
1.) 在 addMail() 上,我想将 ID 添加到插入的行。
2.) 在 on_pbOk_clicked() 事件中,我想遍历 selected 行并获取每一行的所有 ID。
如果我将 ID 添加为单独的列,我以后将无法检索它,因为这不适用于隐藏的列。
当您确定选择是按行进行时,只需获取行并对其进行迭代,在这种情况下,使用 set 获取选定的行并在列上进行迭代。
def on_pbOk_clicked(self):
message: str = ""
rows = set(ix.row() for ix in self.dataView.selectedIndexes())
for row in rows:
values_for_row = []
for col in range(App.MAIL_RANGE):
it = self.dataView.model().item(row, col)
values_for_row.append(it.text())
text = " ".join(values_for_row)
self.create_dialog(text)
message += "\n" + text
print(message)