Сортировка столбцов QTableWidget PyQt6

В оригинальном файле с интерфейсом есть QTableWidget который в котором рисуется таблица куда выводятся данные из базы:

self.table_widget = QtWidgets.QTableWidget(parent=self.frame_7)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.table_widget.sizePolicy().hasHeightForWidth())
self.table_widget.setSizePolicy(sizePolicy)
self.table_widget.setObjectName("table_widget")
self.table_widget.setColumnCount(0)
self.table_widget.setRowCount(0)
self.verticalLayout_8.addWidget(self.table_widget)

Уже в самой программе определяем колонки:

    self.ui.table_widget.setColumnCount(2)
    self.ui.table_widget.setHorizontalHeaderLabels(["Info", "Datetime"])

Далее в колонке "Datetime" подгружаются данные формата yyyy-MM-dd HH:mm:ss (дата) , и при сортировке по ней, он это делает, как я подчерпнул из других источников, по лингвистическому признакам, тк считает данные как str. Это собственно делать не надо, нужны были сортировки даты.

Для применения сортировки был создан отдельный класс для модели сортировки:

class DateTimeSortProxyModel(QSortFilterProxyModel):
    def lessThan(self, left, right):
        left_date = QDateTime.fromString(self.sourceModel().data(left), 'yyyy-MM-dd HH:mm:ss')
        right_date = QDateTime.fromString(self.sourceModel().data(right), 'yyyy-MM-dd HH:mm:ss')
        return left_date < right_date

И я попытался установить данный класс через setModel установить его, но оказалось , что для QTableWidget данный метод является приватным. и не работает на прямую.

В базу данные заносятся вот так:

reminder_datetime = QDateTime.fromString(record['datetime'], 'yyyy-MM-dd HH:mm:ss')

Тогда попробовал свою таблицу перевести в копию класса QTableView, там сортировка включается работает.

    # изменение модели сортировки для таблицы напоминаний
    self.proxy_model = DateTimeSortProxyModel()
    self.proxy_model.setSourceModel(self.ui.table_widget.model())

    self.view = QtWidgets.QTableView()
    self.view.setMinimumSize(self.ui.table_widget.size())
    layout = QtWidgets.QVBoxLayout(self.ui.table_widget)
    layout.addWidget(self.view)
    layout.setContentsMargins(0, 0, 0, 0)
    self.view.setModel(self.proxy_model)
    self.view.setParent(self.ui.table_widget)
    self.view.setSortingEnabled(True)
    self.view.sortByColumn(0, QtCore.Qt.SortOrder.AscendingOrder)

Но после этого у меня престают работать функции с removeRow , тк ,потом я посмотрев документацию, QTableView просто не обладает ими.

Собственно вопрос как установить модель сортировки для QTableWidget и не потерять часть функционала?


Ответы (1 шт):

Автор решения: LivsiMD

Вопрос решался куда проще чем я заморочился.

Все так же для установки модели используем переход в QTableView

изменение модели сортировки для таблицы напоминаний

self.proxy_model = DateTimeSortProxyModel()
self.proxy_model.setSourceModel(self.ui.table_widget.model())

self.view = QtWidgets.QTableView()
self.view.setMinimumSize(self.ui.table_widget.size())
layout = QtWidgets.QVBoxLayout(self.ui.table_widget)
layout.addWidget(self.view)
layout.setContentsMargins(0, 0, 0, 0)
self.view.setModel(self.proxy_model)
self.view.setParent(self.ui.table_widget)
self.view.setSortingEnabled(True)
self.view.sortByColumn(0, QtCore.Qt.SortOrder.AscendingOrder)

Далее изначально мы обращались к объекту QTableWidget, выбирали строку и удаляли ее. Но тк теперь передо мной был QTableView , removeRow применить было нельзя Закомментированные строки, это первоначальный код функции по удалению строк из базы.

Суть решения - выбираем строку вновь обрисованном объекте QTableView, а удаляем в QTableWidget.

def delete_selected_row_rem(self):
    # selected_row = self.view.currentIndex()
    # if selected_row >= 0:
    #     self.ui.table_widget.removeRow(selected_row)
    #     self.save_records_rem()
    selected_index = self.view.currentIndex()
    if selected_index.isValid():
        selected_row = selected_index.row()
        self.ui.table_widget.removeRow(selected_row)
        self.save_records_rem()
→ Ссылка