PyQT5 работа с QTableView (сортировка не по str, поиск по выбранным столбцам, авто-ширина)
Предыстория: как я понял, для сортировки и поиска лучше использовать не QTableWidget, а QTableView. По последнему нашёл немного информации и то, не особо понятно. Поэтому решил создать тему с различным функционалом в одном примере, который в большой мере исчерпает как мои вопросы, так и вопросы столкнувшихся с данным инструментом.
Симулирую ситуацию: есть таблица, в которую, из какой-нибудь БД вытягиваются строки данных в виде кортежей. Присутствуют данные типов int, float, str, дата со временем (в примере unixtime в виде int, но подскажите, для сортировки лучше так или в далее описанном представлении?), которая отображается, допустим, в виде чч:мм:сс ДД.ММ.ГГГГ.
Реализуемый функционал:
1) Я что-то не так понял с заполнением таблицы, т.к. помимо добавляемых строк добавляется столько же пустых, объясните, что не так
2) При заполнении таблицы столбики автоматически подбирают ширину, чтобы было по размеру. В QTableWidget находил функцию self.tableWidget.horizontalHeader().setSectionResizeMode(номер_столбца, QtWidgets.QHeaderView.ResizeToContents).
3) Сортировка по float, int и дате (стандартная сортировка self.tableView.setSortingEnabled(True) сортирует столбцы как значения типа str)
4) Поиск по нескольким столбцам, допустим по имени или ID.
5) Поиск типа str с учётом русского языка
Код:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(543, 303)
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(20, 270, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.loadData)
self.tableView = QtWidgets.QTableView(Dialog)
self.tableView.setGeometry(QtCore.QRect(10, 10, 521, 251))
self.tableView.setSortingEnabled(True)
self.tableView.setObjectName("tableView")
self.lineEdit = QtWidgets.QLineEdit(Dialog)
self.lineEdit.setGeometry(QtCore.QRect(340, 270, 191, 20))
self.lineEdit.setObjectName("lineEdit")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "Загрузить"))
self.lineEdit.setPlaceholderText(_translate("Dialog", "Поиск по имени или ID"))
def loadData(self):
headers = ["Имя", "Очки", "Дата регистрации", "ID"]
model = QtGui.QStandardItemModel()
model.setHorizontalHeaderLabels(headers)
items = [
('Oleg', 22.98, 1587900157, 188530139),
('Max', 223.05, 1587900543, 17578),
('Vladimir324235576576294592', -99.12, 1587900003, 1),
('Anton', -11.32, 1587900322, 5675677),
('Глеб', 17.21, 1587900932, 2277786),
('Nataliya', 989.16, 1587900113, 7887678),
('Виталий', -233.04, 1587900199, 124214)
]
for row_number, row_data in enumerate(items):
tableitem = []
model.insertRow(row_number)
for value in row_data:
item = QtGui.QStandardItem(str(value))
tableitem.append(item)
model.insertRow(row_number, tableitem)
self.tableView.setModel(model)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
ui (на всякий случай):
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>543</width>
<height>303</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>20</x>
<y>270</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Загрузить</string>
</property>
</widget>
<widget class="QTableView" name="tableView">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>521</width>
<height>251</height>
</rect>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit">
<property name="geometry">
<rect>
<x>340</x>
<y>270</y>
<width>191</width>
<height>20</height>
</rect>
</property>
<property name="placeholderText">
<string>Поиск по имени или ID</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
Можно по одному функционалу, потом соберу весь в одну программу.
Заранее спасибо!

