我正在尝试使用桌子制作房间预订系统。在表中有复选框,我希望这样,以便用户单击书本按钮时,程序将看到已选中了哪些复选框,以便可以从表中删除这些复选框。
我已经通过PyQt5设计器创建了表格,在表格的每个空间中都具有如下复选框:
UI文件代码有很多行,如下所示:
item = QtWidgets.QTableWidgetItem()
item.setFlags(QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Unchecked)
self.tableWidget.setItem(0, 0, item)
item = QtWidgets.QTableWidgetItem()
item.setFlags(QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Unchecked)
self.tableWidget.setItem(0, 1, item)
这是否意味着所有复选框都称为item?有没有一种方法可以为每个复选框单独命名?
抱歉,这似乎是一个基本问题-预先感谢
答案 0 :(得分:1)
您必须遍历表格并检查每个项目的状态,使用过滤后的项目,您可以获得带有标签的行和列。
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.tableWidget = QtWidgets.QTableWidget(6, 5)
self.book_button = QtWidgets.QPushButton("Book")
self.book_button.clicked.connect(self.book_clicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.tableWidget)
lay.addWidget(self.book_button)
self.tableWidget.setHorizontalHeaderLabels("P1 P2 P3 P4 P5 P6".split())
self.tableWidget.setVerticalHeaderLabels("C101 C214 C320 F04 E201".split())
for i in range(self.tableWidget.rowCount()):
for j in range(self.tableWidget.columnCount()):
item = QtWidgets.QTableWidgetItem()
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
item.setCheckState(QtCore.Qt.Unchecked)
self.tableWidget.setItem(i, j, item)
@QtCore.pyqtSlot()
def book_clicked(self):
items = []
for i in range(self.tableWidget.rowCount()):
for j in range(self.tableWidget.columnCount()):
item = self.tableWidget.item(i, j)
if item.checkState() == QtCore.Qt.Checked:
items.append(item)
for it in items:
r = it.row()
c = it.column()
v, h = self.tableWidget.horizontalHeaderItem(c).text(), self.tableWidget.verticalHeaderItem(r).text()
print(h, v)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
答案 1 :(得分:1)
只需修改上面的代码!
1)在构造函数中声明空列表值。
self._checked_items = []
2)在“ book_clicked”方法添加行内:
self._checked_items.append([h, v])
3)声明一个checked_items的吸气剂:
def checked_items(self):
return self._checked_items
4)在主要方法中打印checked_items:
print(w.checked_items())
但是我建议您使用QTableView()而不是QTableWidget()。 QTableWidget()基于项目,QTableView()基于模型。
当然,起初看起来比较复杂,但是后来,当您了解如何使用基于模型的小部件时,您会喜欢的!
您要做的是实现自定义CheckedItemsModel,它扩展了QAbstractItemModel。查看文档,您会发现很多示例。
答案 2 :(得分:1)
我为你做到了,你很幸运))
主窗口。
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QHeaderView
from examples.checkedItemsModel import CheckedItemsModel
from examples.checkedItemsUI import Ui_CheckedItemsView
class CheckedItems(QtWidgets.QMainWindow):
def __init__(self, model= None, parent = None):
super(CheckedItems, self).__init__(parent)
self._ui = Ui_CheckedItemsView()
self._ui.setupUi(self)
self._model = model
self._ui.ui_table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self._ui.ui_table_view.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)
# set the table model
self._ui.ui_table_view.setModel(self._model)
# create connecitons
self._ui.btn_book.clicked.connect(self.print_checked_items)
def print_checked_items(self):
model = self._ui.ui_table_view.model()
items = model.checkedItems()
self._ui.ui_result.setPlainText(str(items))
print(items)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
# data for table creation
column_headers = ['P1', 'P2', 'P3', 'P4', 'P5', 'P6']
row_headers = ['C101', 'C214', 'C320', 'F04', 'E201']
# create table model
model = CheckedItemsModel(column_headers, row_headers)
# pass model to custom widget
w = CheckedItems(model)
w.show()
sys.exit(app.exec_())
模型的实现:
import typing
from PyQt5 import QtCore
from PyQt5.QtCore import QAbstractTableModel, Qt, QModelIndex
class CheckedItemsModel(QAbstractTableModel):
def __init__(self, column_headers= [], row_headers=[], parent = None):
super(CheckedItemsModel, self).__init__(parent)
self._column_headers = column_headers
self._row_headers = row_headers
# create all unchecked items by default
self._items = []
for i in range(len(self._row_headers)):
self._items.append([])
for j in range(len(self._column_headers)):
self._items[i].append(Qt.Unchecked)
def rowCount(self, parent: QModelIndex = QtCore.QModelIndex()) -> int:
return len(self._row_headers)
def columnCount(self, parent: QModelIndex = ...) -> int:
return len(self._column_headers)
def data(self, index: QModelIndex, role: int = QtCore.Qt.DisplayRole) -> typing.Any:
if role == QtCore.Qt.DisplayRole:
return ''#str(index.row()) + ', ' + str(index.column())
if role == QtCore.Qt.CheckStateRole:
if self._items[index.row()][index.column()] == Qt.Checked:
return QtCore.Qt.Checked
else:
return QtCore.Qt.Unchecked
def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> typing.Any:
if role == QtCore.Qt.DisplayRole:
if orientation == Qt.Horizontal:
return self._column_headers[section]
else:
return self._row_headers[section]
def setData(self, index: QModelIndex, value: typing.Any, role: int = QtCore.Qt.EditRole) -> bool:
if role == Qt.EditRole:
self._items[index.row()][index.column()] = value
self.dataChanged.emit(index, index)
return True
if role == Qt.CheckStateRole:
self._items[index.row()][index.column()] = value
self.dataChanged.emit(index, index)
return True
def flags(self, index: QModelIndex):
return Qt.ItemIsUserCheckable | Qt.ItemIsEnabled
def checkedItems(self):
items = []
for i in range(self.rowCount()):
for j in range(self.columnCount()):
if self._items[i][j] == QtCore.Qt.Checked:
items.append('(' + str(self._row_headers[i]) + ', ' + str(self._column_headers[j]) + ')')
return items
和Qt Designer中的View类(自动将.ui文件转换为.py):
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_CheckedItems.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_CheckedItemsView(object):
def setupUi(self, CheckedItemsView):
CheckedItemsView.setObjectName("CheckedItemsView")
CheckedItemsView.resize(685, 470)
self.centralwidget = QtWidgets.QWidget(CheckedItemsView)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.ui_table_view = QtWidgets.QTableView(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.ui_table_view.sizePolicy().hasHeightForWidth())
self.ui_table_view.setSizePolicy(sizePolicy)
self.ui_table_view.setMinimumSize(QtCore.QSize(200, 200))
self.ui_table_view.setObjectName("ui_table_view")
self.verticalLayout.addWidget(self.ui_table_view)
self.ui_result = QtWidgets.QTextEdit(self.centralwidget)
self.ui_result.setReadOnly(True)
self.ui_result.setObjectName("ui_result")
self.verticalLayout.addWidget(self.ui_result)
self.buttonsLayout = QtWidgets.QHBoxLayout()
self.buttonsLayout.setObjectName("buttonsLayout")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.buttonsLayout.addItem(spacerItem)
self.btn_book = QtWidgets.QPushButton(self.centralwidget)
self.btn_book.setObjectName("btn_book")
self.buttonsLayout.addWidget(self.btn_book)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.buttonsLayout.addItem(spacerItem1)
self.verticalLayout.addLayout(self.buttonsLayout)
self.verticalLayout.setStretch(0, 5)
self.verticalLayout.setStretch(1, 1)
self.horizontalLayout.addLayout(self.verticalLayout)
CheckedItemsView.setCentralWidget(self.centralwidget)
self.retranslateUi(CheckedItemsView)
QtCore.QMetaObject.connectSlotsByName(CheckedItemsView)
def retranslateUi(self, CheckedItemsView):
_translate = QtCore.QCoreApplication.translate
CheckedItemsView.setWindowTitle(_translate("CheckedItemsView", "MainWindow"))
self.btn_book.setText(_translate("CheckedItemsView", "Book"))