Сортировка по очкам PyQt5
- Как сделать что бы данные
NameиPointsбыли связаны друг с другом т.к. это очки у определенного игрока. - Как сделать сортировку по очкам?
Прошу помощи либо кодом либо советами про поиск информации полезной для решения данного вопроса.
widgets.py
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
class CustomTableWidget(QtWidgets.QTableWidget):
def KeyPressEvent(self, event: QtGui.QKeyEvent):
if event.key() == QtCore.Qt.Key_Enter:
print(" ")
elif event.key() == QtCore.Qt.Key_Return:
print(" ")
counter.py
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from widgets import CustomTableWidget
class Counter(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Counter, self).__init__(parent)
self.setWindowFlags(QtCore.Qt.Window)
QtWidgets.QMainWindow.__init__(self)
font = QtGui.QFont("Formula1", 10, QtGui.QFont.Bold)
self.setFont(font)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
grid_layout = QtWidgets.QGridLayout()
central_widget.setLayout(grid_layout)
table = CustomTableWidget(self)
table.setColumnCount(2)
table.setRowCount(1)
table.setHorizontalHeaderLabels(["Name" , "Points"])
table.horizontalHeaderItem(0).setToolTip("Player 1")
table.horizontalHeaderItem(1).setToolTip("Player 2")
table.horizontalHeaderItem(0).setTextAlignment(QtCore.Qt.AlignLeft)
table.horizontalHeaderItem(1).setTextAlignment(QtCore.Qt.AlignRight)
table.setItem(0, 0, self.createItem("25", QtCore.Qt.ItemIsEnabled))
table.setItem(0, 1, self.createItem("18", QtCore.Qt.ItemIsEnabled))
table.resizeColumnsToContents()
sort_button = QtWidgets.QPushButton("Sort")
apply_button = QtWidgets.QPushButton("Apply")
horisontal_layout = QtWidgets.QHBoxLayout()
horisontal_layout.addStretch(1)
horisontal_layout.addWidget(sort_button)
horisontal_layout.addStretch(1)
horisontal_layout.addWidget(apply_button)
horisontal_layout.addStretch(1)
horisontal_layout.setAlignment(QtCore.Qt.AlignRight)
grid_layout.addLayout(horisontal_layout, 0, 0)
grid_layout.addWidget(table, 1, 0)
def createItem(self, text, flags):
tableWidgetItem = QtWidgets.QTableWidgetItem(text)
tableWidgetItem.setFlags(flags)
return tableWidgetItem
if __name__ == "__main__":
application = QtWidgets.QApplication([])
window = Counter()
window.setWindowTitle("Counter")
window.setMinimumSize(480, 120)
window.show()
sys.exit(application.exec_())
Ответы (1 шт):
Если использовать:
класс
QTableViewпредоставляет реализацию модели/представления по умолчанию для табличного представления. https://doc.qt.io/qt-5/qtableview.htmlкласс
QStandardItemModelпредоставляет общую модель для хранения пользовательских данных. https://doc.qt.io/qt-5/qstandarditemmodel.htmlкласс
QSortFilterProxyModelобеспечивает поддержку сортировки и фильтрации данных https://doc.qt.io/qt-5/qsortfilterproxymodel.html#lessThan , в котором переопределить методlessThanhttps://doc.qt.io/qt-5/qsortfilterproxymodel.html#lessThan
то ваша задача может выглядеть так:
import sys
from random import randint
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.Qt import *
#from widgets import CustomTableWidget
#class CustomTableWidget(QtWidgets.QTableWidget):
class CustomTableView(QtWidgets.QTableView): # QTableView !!!
def __init__(self, parent=None):
super(CustomTableView, self).__init__(parent)
self.setSortingEnabled(True)
def KeyPressEvent(self, event: QtGui.QKeyEvent):
if event.key() == QtCore.Qt.Key_Enter:
print("Key_Enter ")
elif event.key() == QtCore.Qt.Key_Return:
print("Key_Return ")
# пользовательская реализация для сортировки по числам
class NumberSortModel(QSortFilterProxyModel):
def lessThan(self, left_index: "QModelIndex",
right_index: "QModelIndex") -> bool:
left_var: str = left_index.data(Qt.EditRole)
right_var: str = right_index.data(Qt.EditRole)
try:
return float(left_var) < float(right_var)
except (ValueError, TypeError):
pass
try:
return left_var < right_var
except TypeError: # in case of NoneType
return True
class Counter(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Counter, self).__init__(parent)
self.setWindowFlags(QtCore.Qt.Window)
QtWidgets.QMainWindow.__init__(self)
font = QtGui.QFont("Formula1", 10, QtGui.QFont.Bold)
self.setFont(font)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
grid_layout = QtWidgets.QGridLayout()
central_widget.setLayout(grid_layout)
'''
table = CustomTableWidget(self)
table.setColumnCount(2)
table.setRowCount(1)
table.setHorizontalHeaderLabels(["Name" , "Points"])
table.horizontalHeaderItem(0).setToolTip("Player 1")
table.horizontalHeaderItem(1).setToolTip("Player 2")
table.horizontalHeaderItem(0).setTextAlignment(QtCore.Qt.AlignLeft)
table.horizontalHeaderItem(1).setTextAlignment(QtCore.Qt.AlignRight)
table.setItem(0, 0, self.createItem("25", QtCore.Qt.ItemIsEnabled))
table.setItem(0, 1, self.createItem("18", QtCore.Qt.ItemIsEnabled))
table.resizeColumnsToContents()
'''
# ++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# create model
self.model = QStandardItemModel(self)
self.model.setHorizontalHeaderLabels(["Name" , "Points"])
# create sort proxy
self.proxy = NumberSortModel()
self.proxy.setSourceModel(self.model)
# create view
self.table = CustomTableView(self)
self.table.setModel(self.proxy)
# fill model
for i in range(10):
self.model.appendRow([QStandardItem(f'Name{randint(10, 99)}'),
QStandardItem(str(randint(1, 100)))])
# ++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sort_button = QtWidgets.QPushButton("Sort")
apply_button = QtWidgets.QPushButton("Apply")
horisontal_layout = QtWidgets.QHBoxLayout()
horisontal_layout.addStretch(1)
horisontal_layout.addWidget(sort_button)
horisontal_layout.addStretch(1)
horisontal_layout.addWidget(apply_button)
horisontal_layout.addStretch(1)
horisontal_layout.setAlignment(QtCore.Qt.AlignRight)
grid_layout.addLayout(horisontal_layout, 0, 0)
grid_layout.addWidget(self.table, 1, 0)
'''
def createItem(self, text, flags):
tableWidgetItem = QtWidgets.QTableWidgetItem(text)
tableWidgetItem.setFlags(flags)
return tableWidgetItem
'''
if __name__ == "__main__":
application = QtWidgets.QApplication([])
window = Counter()
window.setWindowTitle("Counter")
window.setMinimumSize(480, 380)
window.show()
sys.exit(application.exec_())
