如何在 QTableView 中使用选中的复选框检索多行
How to retrieve more than one row with the checked checkbox in QTableView
我正在开发一个应用程序,用户可以在其中 select 多个 (<=5) 行进行预览。我已经将 QSqlTableModel 与 QTableView 一起使用了。
为了检索数据,我使用了以下代码行:
out = (self.model.record(self.view.selectionModel().selectedIndexes() [0].row()).value("NAME"))
print(out)
它给了我行值。但是有一些主要问题:
- 如果我select复选框和取消select。不过,它正在考虑 selected.
- 如果我 select n 复选框,它只给出第 n 个 selection。简而言之,多个 selection 不起作用。
我假设我必须创建一个循环。但是我无法构建解决方案。
完整代码在此:
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QVBoxLayout, QPushButton
from PyQt5 import QtGui
from PyQt5.QtCore import Qt, QModelIndex
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel, QSqlQuery
from PyQt5.QtWidgets import (QApplication, QMainWindow, QMessageBox, QTableView, QPushButton, QGridLayout, QGroupBox, QVBoxLayout)
from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSignal
class RealMainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("QTableView Example")
self.resize(415, 200)
# Set up the model
self.button = QPushButton("check", self)
self.button.clicked.connect(self.selected)
self.button.move(1000, 1110)
self.model = TableModel(self)
self.model.setTable("Table2")
self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
#self.model.setHeaderData(0, Qt.Horizontal, "ID")
self.model.select()
# Set up the view
self.view = QTableView()
self.view.setModel(self.model)
#self.view.resizeColumnsToContents()
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QVBoxLayout(central_widget)
lay.addWidget(self.button)
lay.addWidget(self.view)
def selected(self):
out = (self.model.record(self.view.selectionModel().selectedIndexes()[0].row()).value("NAME"))
print(out)
class TableModel(QSqlTableModel):
def __init__(self, *args, **kwargs):
QSqlTableModel.__init__(self, *args, **kwargs)
self.checkeable_data = {}
def flags(self, index):
fl = QSqlTableModel.flags(self, index)
if index.column() == 0:
fl |= Qt.ItemIsUserCheckable
return fl
def data(self, index, role=Qt.DisplayRole):
if role == Qt.CheckStateRole and (
self.flags(index) & Qt.ItemIsUserCheckable != Qt.NoItemFlags
):
if index.row() not in self.checkeable_data.keys():
self.setData(index, Qt.Unchecked, Qt.CheckStateRole)
return self.checkeable_data[index.row()]
else:
return QSqlTableModel.data(self, index, role)
def setData(self, index, value, role=Qt.EditRole):
if role == Qt.CheckStateRole and (
self.flags(index) & Qt.ItemIsUserCheckable != Qt.NoItemFlags
):
self.checkeable_data[index.row()] = value
self.dataChanged.emit(index, index, (role,))
return True
return QSqlTableModel.setData(self, index, value, role)
def createConnection():
con = QSqlDatabase.addDatabase("QSQLITE")
con.setDatabaseName("ppcp_database.db")
if not con.open():
QMessageBox.critical(
None,
"QTableView Example - Error!",
"Database Error: %s" % con.lastError().databaseText(),
)
return False
return True
app = QApplication(sys.argv)
if not createConnection():
sys.exit(1)
win = RealMainWindow()
win.show()
sys.exit(app.exec_())
复选框的状态与选择相混淆。在您的情况下,您必须遍历 checkeable_data
并验证它是否被选中:
def selected(self):
names = []
for row, is_checked in self.model.checkeable_data.items():
if is_checked:
record = self.model.record(row)
name = record.value("NAME")
names.append(name)
print(names)
我正在开发一个应用程序,用户可以在其中 select 多个 (<=5) 行进行预览。我已经将 QSqlTableModel 与 QTableView 一起使用了。
为了检索数据,我使用了以下代码行:
out = (self.model.record(self.view.selectionModel().selectedIndexes() [0].row()).value("NAME"))
print(out)
它给了我行值。但是有一些主要问题:
- 如果我select复选框和取消select。不过,它正在考虑 selected.
- 如果我 select n 复选框,它只给出第 n 个 selection。简而言之,多个 selection 不起作用。
我假设我必须创建一个循环。但是我无法构建解决方案。
完整代码在此:
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QVBoxLayout, QPushButton
from PyQt5 import QtGui
from PyQt5.QtCore import Qt, QModelIndex
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel, QSqlQuery
from PyQt5.QtWidgets import (QApplication, QMainWindow, QMessageBox, QTableView, QPushButton, QGridLayout, QGroupBox, QVBoxLayout)
from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSignal
class RealMainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("QTableView Example")
self.resize(415, 200)
# Set up the model
self.button = QPushButton("check", self)
self.button.clicked.connect(self.selected)
self.button.move(1000, 1110)
self.model = TableModel(self)
self.model.setTable("Table2")
self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
#self.model.setHeaderData(0, Qt.Horizontal, "ID")
self.model.select()
# Set up the view
self.view = QTableView()
self.view.setModel(self.model)
#self.view.resizeColumnsToContents()
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QVBoxLayout(central_widget)
lay.addWidget(self.button)
lay.addWidget(self.view)
def selected(self):
out = (self.model.record(self.view.selectionModel().selectedIndexes()[0].row()).value("NAME"))
print(out)
class TableModel(QSqlTableModel):
def __init__(self, *args, **kwargs):
QSqlTableModel.__init__(self, *args, **kwargs)
self.checkeable_data = {}
def flags(self, index):
fl = QSqlTableModel.flags(self, index)
if index.column() == 0:
fl |= Qt.ItemIsUserCheckable
return fl
def data(self, index, role=Qt.DisplayRole):
if role == Qt.CheckStateRole and (
self.flags(index) & Qt.ItemIsUserCheckable != Qt.NoItemFlags
):
if index.row() not in self.checkeable_data.keys():
self.setData(index, Qt.Unchecked, Qt.CheckStateRole)
return self.checkeable_data[index.row()]
else:
return QSqlTableModel.data(self, index, role)
def setData(self, index, value, role=Qt.EditRole):
if role == Qt.CheckStateRole and (
self.flags(index) & Qt.ItemIsUserCheckable != Qt.NoItemFlags
):
self.checkeable_data[index.row()] = value
self.dataChanged.emit(index, index, (role,))
return True
return QSqlTableModel.setData(self, index, value, role)
def createConnection():
con = QSqlDatabase.addDatabase("QSQLITE")
con.setDatabaseName("ppcp_database.db")
if not con.open():
QMessageBox.critical(
None,
"QTableView Example - Error!",
"Database Error: %s" % con.lastError().databaseText(),
)
return False
return True
app = QApplication(sys.argv)
if not createConnection():
sys.exit(1)
win = RealMainWindow()
win.show()
sys.exit(app.exec_())
复选框的状态与选择相混淆。在您的情况下,您必须遍历 checkeable_data
并验证它是否被选中:
def selected(self):
names = []
for row, is_checked in self.model.checkeable_data.items():
if is_checked:
record = self.model.record(row)
name = record.value("NAME")
names.append(name)
print(names)