Есть ли способ проверить, какие флажки были отмечены в таблице PyQt5? - PullRequest
1 голос
/ 30 марта 2019

Я пытаюсь сделать систему бронирования номеров, используя таблицу. В таблице у меня есть флажки, я хотел бы, чтобы, когда пользователь нажимает кнопку книги, программа видела, какие флажки были отмечены, чтобы можно было удалить эти флажки из таблицы.

Я создал таблицу в конструкторе PyQt5 с флажками в каждом пространстве таблицы, например так:

enter image description here

Код файла пользовательского интерфейса состоит из следующих строк:

        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? Есть ли способ, которым я могу использовать отдельное имя для каждого флажка?

Извините, если это кажется основным вопросом - заранее спасибо

Ответы [ 3 ]

1 голос
/ 01 апреля 2019

Просто немного измените приведенный выше код!

1) в конструкторе объявите пустое значение списка.

self._checked_items = []

2) внутри строки добавления метода book_clicked:

self._checked_items.append([h, v])

3) объявить получатель check_items:

def checked_items(self):
    return self._checked_items

4) напечатать checked_items в основном методе:

print(w.checked_items())

Но я предлагаю вам использовать QTableView (), а не QTableWidget ().QTableWidget () основан на элементах, QTableView () основан на моделях.

Конечно, в первый раз это выглядит сложнее, но позже, когда вы поймете, как использовать виджеты на основе моделей, вам понравится!

Что вам нужно сделать, это реализовать пользовательскую CheckedItemsModel, которая расширяет QAbstractItemModel.Посмотрите документацию, вы найдете много примеров.

1 голос
/ 02 апреля 2019

Я сделал это для вас, вам повезло)))

Главное окно.

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

И класс View (автоматически преобразованный .ui-файл в .py) из Qt Designer:

# -*- 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"))

Как выглядит программанапример, когда вы выполняете

1 голос
/ 31 марта 2019

Вы должны перебрать таблицу и проверить состояние каждого элемента, используя отфильтрованные элементы, вы можете получить строку и столбец с тем, что вы можете получить метки.

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_())
...