PyQt QTableWidget в Python — создание табличного виджета
Класс QTableWidget позволяет создать табличный виджет в Python, отображающий табличную форму элементов. Элементы в QTableWidget создаются с помощью класса QTableWidgetItem.
Знакомство с PyQt QTableWidget
Следующий код создает виджет таблицы с использованием класса QTableWidget:
table = QTableWidget(parent)
Родительский элемент — родительский виджет или главное окно.
Имея объект QTableWidget, вы можете задать количество столбцов для таблицы с помощью метода setColumnCount():
table.setColumnCount(columns)
Чтобы задать горизонтальные метки для столбцов таблицы, используйте метод setHorizontalHeaderLabels():
table.setHorizontalHeaderLabels(labels)
Каждый столбец имеет индекс, начинающийся с нуля. Для каждого столбца можно настроить его ширину с помощью метода setColumnWidth():
table.setColumnWidth(column, width)
Чтобы задать количество строк в таблице, используйте метод setRowCount():
table.setRowCount(rows)
Если вы знаете количество строк и столбцов, которые может иметь таблица на момент создания, вы можете использовать следующее:
table = QTableWidget(rows, columns, parent)
Чтобы добавить элемент в таблицу, используйте метод setItem():
table.setItem(row, column, item)
Пример PyQt QTableWidget
Мы разработаем приложение, которое использует QTableWidget для управления данными сотрудников:
Если ввести имя, фамилию и возраст и нажать «add», программа добавит нового сотрудника в таблицу. Также, если выбрать строку и нажать значок удаления, таблица удалит строку.
Вот полная программа:
import sys from PyQt6.QtWidgets import( QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QDockWidget, QFormLayout, QLineEdit, QWidget, QPushButton, QSpinBox, QMessageBox, QToolBar, QMessageBox ) from PyQt6.QtCore import Qt,QSize from PyQt6.QtGui import QIcon, QAction class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('Employees') self.setWindowIcon(QIcon('./assets/usergroup.png')) self.setGeometry(100, 100, 600, 400) employees = [ {'First Name': 'John', 'Last Name': 'Doe', 'Age': 25}, {'First Name': 'Jane', 'Last Name': 'Doe', 'Age': 22}, {'First Name': 'Alice', 'Last Name': 'Doe', 'Age': 22}, ] self.table = QTableWidget(self) self.setCentralWidget(self.table) self.table.setColumnCount(3) self.table.setColumnWidth(0, 150) self.table.setColumnWidth(1, 150) self.table.setColumnWidth(2, 50) self.table.setHorizontalHeaderLabels(employees[0].keys()) self.table.setRowCount(len(employees)) row = 0 for e in employees: self.table.setItem(row, 0, QTableWidgetItem(e['First Name'])) self.table.setItem(row, 1, QTableWidgetItem(e['Last Name'])) self.table.setItem(row, 2, QTableWidgetItem(str(e['Age']))) row += 1 dock = QDockWidget('New Employee') dock.setFeatures(QDockWidget.DockWidgetFeature.NoDockWidgetFeatures) self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, dock) # create form form = QWidget() layout = QFormLayout(form) form.setLayout(layout) self.first_name = QLineEdit(form) self.last_name = QLineEdit(form) self.age = QSpinBox(form, minimum=18, maximum=67) self.age.clear() layout.addRow('First Name:', self.first_name) layout.addRow('Last Name:', self.last_name) layout.addRow('Age:', self.age) btn_add = QPushButton('Add') btn_add.clicked.connect(self.add_employee) layout.addRow(btn_add) # add delete & edit button toolbar = QToolBar('main toolbar') toolbar.setIconSize(QSize(16,16)) self.addToolBar(toolbar) delete_action = QAction(QIcon('./assets/remove.png'), '&Delete', self) delete_action.triggered.connect(self.delete) toolbar.addAction(delete_action) dock.setWidget(form) def delete(self): current_row = self.table.currentRow() if current_row < 0: return QMessageBox.warning(self, 'Warning','Please select a record to delete') button = QMessageBox.question( self, 'Confirmation', 'Are you sure that you want to delete the selected row?', QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No ) if button == QMessageBox.StandardButton.Yes: self.table.removeRow(current_row) def valid(self): first_name = self.first_name.text().strip() last_name = self.last_name.text().strip() if not first_name: QMessageBox.critical(self, 'Error', 'Please enter the first name') self.first_name.setFocus() return False if not last_name: QMessageBox.critical(self, 'Error', 'Please enter the last name') self.last_name.setFocus() return False try: age = int(self.age.text().strip()) except ValueError: QMessageBox.critical(self, 'Error', 'Please enter a valid age') self.age.setFocus() return False if age <= 0 or age >= 67: QMessageBox.critical( self, 'Error', 'The valid age is between 1 and 67') return False return True def reset(self): self.first_name.clear() self.last_name.clear() self.age.clear() def add_employee(self): if not self.valid(): return row = self.table.rowCount() self.table.insertRow(row) self.table.setItem(row, 0, QTableWidgetItem( self.first_name.text().strip()) ) self.table.setItem( row, 1, QTableWidgetItem(self.last_name.text()) ) self.table.setItem( row, 2, QTableWidgetItem(self.age.text()) ) self.reset() if __name__ == '__main__': app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())
Как это работает.
- Сначала инициализируем список сотрудников как список словарей:
employees = [ {'First Name': 'John', 'Last Name': 'Doe', 'Age': 25}, {'First Name': 'Jane', 'Last Name': 'Doe', 'Age': 22}, {'First Name': 'Alice', 'Last Name': 'Doe', 'Age': 22}, ]
- Во-вторых, создайте новый QTableWidget и установите его в качестве центрального виджета главного окна:
self.table = QTableWidget(self) self.setCentralWidget(self.table)
- В-третьих, задайте количество столбцов в таблице и настройте ширину столбцов:
self.table.setColumnCount(3) self.table.setColumnWidth(0, 150) self.table.setColumnWidth(1, 150) self.table.setColumnWidth(2, 50)
- В-четвертых, задайте горизонтальные заголовки для таблицы:
self.table.setHorizontalHeaderLabels(employees[0].keys())
- В-пятых, установите количество строк равным количеству элементов в списке сотрудников:
self.table.setRowCount(len(employees))
- В-шестых, добавьте каждого сотрудника из списка сотрудников в таблицу:
row = 0 for e in employees: self.table.setItem(row, 0, QTableWidgetItem(e['First Name'])) self.table.setItem(row, 1, QTableWidgetItem(e['Last Name'])) self.table.setItem(row, 2, QTableWidgetItem(str(e['Age']))) row += 1
- В-седьмых, определите метод delete(), который выполняется, когда пользователь выбирает строку и нажимает кнопку удаления на панели инструментов:
def delete(self): current_row = self.table.currentRow() if current_row < 0: return QMessageBox.warning(self, 'Warning','Please select a record to delete') button = QMessageBox.question( self, 'Confirmation', 'Are you sure that you want to delete the selected row?', QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No ) if button == QMessageBox.StandardButton.Yes: self.table.removeRow(current_row)
Метод currenRow() возвращает текущую выбранную строку. Он возвращает -1, если не выбрана ни одна строка. В этом случае мы используем QMessageBox для вывода предупреждающего сообщения.
Если пользователь выбирает строку, мы используем QMessageBox, чтобы задать вопрос для подтверждения удаления. Если пользователь нажимает OK, мы используем метод removeRow() QTableWidget, чтобы удалить выбранную строку.
- Восьмое, определите метод add_employee() для добавления нового сотрудника в таблицу:
def add_employee(self): if not self.valid(): return row = self.table.rowCount() self.table.insertRow(row) self.table.setItem(row, 0, QTableWidgetItem(self.first_name.text().strip())) self.table.setItem(row, 1, QTableWidgetItem(self.last_name.text())) self.table.setItem(row, 2, QTableWidgetItem(self.age.text())) self.reset()
Метод add_employee() выполнит следующие действия:
- Проверьте сотрудника с помощью метода valid().
- Добавьте новую строку в таблицу с помощью метода insertRow().
- Установите элемент для каждого столбца вновь вставленной строки, используя метод setItem().
- Сбросьте форму сотрудника с помощью метода reset().