PyQt5:当您单击QHeaderView的标题时,如何对QTableView进行排序? - python

当我单击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)。为此,我没有进行太多搜索,因此在提出疑问之前,我将自己尝试一下,但是如果您有任何提示,将不胜感激!

谢谢您的帮助!

参考方案

您的排序功能是问题,您没有使用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()

Python-crontab模块 - python

我正在尝试在Linux OS(CentOS 7)上使用Python-crontab模块我的配置文件如下:{ "ossConfigurationData": { "work1": [ { "cronInterval": "0 0 0 1 1 ?", "attribute&…

Python Pandas导出数据 - python

我正在使用python pandas处理一些数据。我已使用以下代码将数据导出到excel文件。writer = pd.ExcelWriter('Data.xlsx'); wrong_data.to_excel(writer,"Names which are wrong", index = False); writer.…

如何每隔n秒运行一个函数,但又不中断其他代码?也许在后台运行? - python

Python是我的第一语言,因此如果没有意义,请理解我。我正在用python制作虚拟宠物。我将Tkinter用于GUI。我想每5秒在Action类中运行一次display方法。但是,如果我使用线程,时间表或时间并将代码放在按钮的正前方,它就会冻结并只运行显示方法。如何在不中断按钮和其他部件的情况下每5秒运行一次显示方法?class Pet: def __in…

Python:在不更改段落顺序的情况下在文件的每个段落中反向单词? - python

我想通过反转text_in.txt文件中的单词来生成text_out.txt文件,如下所示:text_in.txt具有两段,如下所示:Hello world, I am Here. I am eighteen years old. text_out.txt应该是这样的:Here. am I world, Hello old. years eighteen a…

用大写字母拆分字符串,但忽略AAA Python Regex - python

我的正则表达式:vendor = "MyNameIsJoe. I'mWorkerInAAAinc." ven = re.split(r'(?<=[a-z])[A-Z]|[A-Z](?=[a-z])', vendor) 以大写字母分割字符串,例如:'我的名字是乔。 I'mWorkerInAAAinc”变成…