Сортировка в QTableWidget PyQt5

Рейтинг: 0Ответов: 1Опубликовано: 20.02.2023

У меня есть небольшой интерфейс на PyQT5 - таблица QTableWidget, которая заполняется данными по нажатию на кнопку "Считать". Я добавил сортировку для этой таблицы:

self.table.setSortingEnabled(True)

и обнаружил, что встроенная сортировка (по нажатию на название колонки) сортирует числа в алфавитном порядке, см. пример на скрине. То есть вместо 1, 2, 3.... я получаю 1, 10, 100.... 2, 20, 200..... Добавить в ячейки таблицы значения типа int вместо str тоже не получается, тогда вылазит ошибка. Как я могу переопределить сортировку столбцов в таблице, в т.ч. сортировку столбца с датой, который тоже должен сортироваться по логике от самого раннего события к самому позднему?

import random
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from datetime import datetime as dt
from styles import (AlignDelegate)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # конфигурация главного окна
        self.central_widget = QWidget(self)
        self.setGeometry(50, 50, 1500, 800)
        self.setCentralWidget(self.central_widget)
        self.layout_main_window = QVBoxLayout()
        self.central_widget.setLayout(self.layout_main_window)
        
        # конфигурация кнопки
        self.layout_toolbar = QHBoxLayout()
        self.layout_toolbar_buttons = QHBoxLayout()
        self.layout_toolbar_buttons.addStretch(1)
        self.btn_start_reading = QPushButton("Считать")
        self.btn_start_reading.clicked.connect(self.start_read)
        self.layout_toolbar_buttons.addWidget(self.btn_start_reading)
        self.layout_toolbar.addLayout(self.layout_toolbar_buttons)
        self.layout_main_window.addLayout(self.layout_toolbar)

        # конфигурация таблицы
        self.layout_table = QHBoxLayout()
        self.table = QTableWidget()
        self.table.setColumnCount(9)
        self.table.setRowCount(13500)
        self.table.setHorizontalHeaderLabels(['№', 'Дата и время', 'БКУ', 'КЛ', 'АУ', 'Канал', 'Код события', 'Доп. параметр', 'Описание'])
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.horizontalHeader().setVisible(True)
        for col in range(8):
            self.table.setColumnWidth(col, 100)
        self.table.setColumnWidth(1, 300)
        self.table_alignment = AlignDelegate(self.table)
        self.table.setItemDelegate(self.table_alignment)
        self.table.setSortingEnabled(True)
        self.layout_table.addWidget(self.table)
        self.layout_main_window.addLayout(self.layout_table)
      

    def start_read(self):
        dates_l = [  
            dt(2022, 11, 1, 1, 56, 11), dt(2022, 10, 2, 2, 57, 7), dt(2022, 9, 3, 3, 8, 14),
            dt(2022, 8, 4, 4, 11, 56)]
        bku_l = [1, 2, 3, 4]
        kl_l = [1, 2, 3, 4]
        au_l = [1, 2, 3, 4]
        channel_l = [1, 2, 3, 4]
        event_code_l = [138, 79, 205, 148]
        addit_param_l = [1, 2, 3, 4]
        description = ['aa', 'aб', 'ав', 'ба', 'бб', 'бв', 'ва']
        for i in range(1000):
            event = [i+1,  random.choice(dates_l), random.choice(bku_l),
                random.choice(kl_l), random.choice(au_l), random.choice(channel_l),
                random.choice(event_code_l), random.choice(addit_param_l), random.choice(description)]
            self.table.setItem(i, 0, QTableWidgetItem(str(event[0])))
            self.table.setItem(i, 1, QTableWidgetItem(str(event[1].strftime('%Y.%m.%d %H:%M:%S'))))
            self.table.setItem(i, 2, QTableWidgetItem(str(event[2])))
            self.table.setItem(i, 3, QTableWidgetItem(str(event[3])))
            self.table.setItem(i, 4, QTableWidgetItem(str(event[4])))
            self.table.setItem(i, 5, QTableWidgetItem(str(event[5])))
            self.table.setItem(i, 6, QTableWidgetItem(str(event[6])))
            self.table.setItem(i, 7, QTableWidgetItem(str(event[7])))
            self.table.setItem(i, 8, QTableWidgetItem(str(event[8])))


app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())

введите сюда описание изображения

Ответы

▲ 3Принят

На этот вопрос ответ давался не однократно. Вы заполнили таблицу строками, и они сортируются как строки. Заполняйте ячейки числами и они будут сортироваться как числа.

один из моих ответов на подобный вопрос тут Альтернатива методу setSortingEnabled(True)

или можете наследоваться от QTableWidgetItem, определять в нем механизм сравнения (перегружать операторы больше-меньше) и заполнять таблицу ими