我想在点击QHeaderView的标题时对QTableView进行排序。我在互联网上找到了几个代码示例,如下所示:Sort QTableView in pyqt5 但它对我不起作用。我也看看Summerfield的Rapid Gui编程书,但我也能找到一些有用的东西。
在这个快速示例中,我如何按名称或年龄对表进行排序?
这是我的代码:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import pandas as pd
import operator
# This class was generated from the Qt Creator
class Ui_tableView_ex(object):
def setupUi(self, tableView_ex):
tableView_ex.setObjectName("tableView_ex")
tableView_ex.resize(800, 600)
self.centralwidget = QWidget(tableView_ex)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.myTable = QTableView(self.centralwidget)
self.myTable.setObjectName("monTablo")
self.gridLayout.addWidget(self.myTable, 0, 0, 1, 1)
tableView_ex.setCentralWidget(self.centralwidget)
self.retranslateUi(tableView_ex)
QMetaObject.connectSlotsByName(tableView_ex)
def retranslateUi(self, tableView_ex):
_translate = QCoreApplication.translate
tableView_ex.setWindowTitle(_translate("tableView_ex", "MainWindow"))
class TableTest(QMainWindow, Ui_tableView_ex):
def __init__(self, parent=None):
super(TableTest, self).__init__(parent)
self.setupUi(self)
self.model = TableModel()
self.myTable.setModel(self.model)
self.myTable.setShowGrid(False)
self.hView = HeaderView(self.myTable)
self.myTable.setHorizontalHeader(self.hView)
self.myTable.verticalHeader().hide()
# adding alternate colours
self.myTable.setAlternatingRowColors(True)
self.myTable.setStyleSheet("alternate-background-color: rgb(209, 209, 209)"
"; background-color: rgb(244, 244, 244);")
# self.myTable.setSortingEnabled(True)
# self.myTable.sortByColumn(1, Qt.AscendingOrder)
class HeaderView(QHeaderView):
def __init__(self, parent):
QHeaderView.__init__(self, Qt.Horizontal, parent)
self.model = TableModel()
self.setModel(self.model)
# Setting font for headers only
self.font = QFont("Helvetica", 12)
self.setFont(self.font)
# Changing section backgroud color. font color and font weight
self.setStyleSheet("::section{background-color: pink; color: green; font-weight: bold}")
self.setSectionResizeMode(1)
self.setSectionsClickable(True)
class TableModel(QAbstractTableModel):
def __init__(self):
QAbstractTableModel.__init__(self)
super(TableModel, self).__init__()
self.headers = ["Name", "Age", "Grades"]
self.stocks = [["George", "26", "80%"],
["Bob", "16", "95%"],
["Martha", "22", "98%"]]
self.data = pd.DataFrame(self.stocks, columns=self.headers)
def update(self, in_data):
self.data = in_data
def rowCount(self, parent=None):
return len(self.data.index)
def columnCount(self, parent=None):
return len(self.data.columns.values)
def setData(self, index, value, role=None):
if role == Qt.EditRole:
row = index.row()
col = index.column()
column = self.data.columns.values[col]
self.data.set_value(row, column, value)
self.update(self.data)
return True
def data(self, index, role=None):
if role == Qt.DisplayRole:
row = index.row()
col = index.column()
value = self.data.iloc[row, col]
return value
def headerData(self, section, orientation, role=None):
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
return self.data.columns.values[section]
# -----------------NOT WORKING!!!---------------
# =================================================
def sort(self, Ncol, order):
"""Sort table by given column number.
"""
self.layoutAboutToBeChanged.emit()
self.data = sorted(self.data, key=operator.itemgetter(Ncol))
if order == Qt.DescendingOrder:
self.data.reverse()
self.layoutChanged.emit()
# =================================================
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
app.setStyle(QStyleFactory.create("Fusion"))
main_window = TableTest()
main_window.show()
app.exec_()
sys.exit()
我尝试修改了一些内容,但没有任何结果,当我取消注释setSortingEnabled(True)行时,窗口甚至都没有打开。因此,我无法知道我是否更接近解决方案!我还想根据等级更改文本颜色(红色低于50,绿色高于50)。为此,我没有那么多搜索,所以我会在问问题之前自己尝试一下,但如果你有任何提示,我将非常感激!
感谢您的帮助!
答案 0 :(得分:3)
你的排序函数是问题,你没有使用pandas DataFrame
排序函数,self.data
变成python list
,然后其他函数失败,程序崩溃。
要正确排序DataFrame
,请使用sort_values
函数,如下所示:
def sort(self, Ncol, order):
"""Sort table by given column number."""
self.layoutAboutToBeChanged.emit()
self.data = self.data.sort_values(self.headers[Ncol],
ascending=order == Qt.AscendingOrder)
self.layoutChanged.emit()