在pyqt5中对QTableView进行排序 [英] Sort QTableView in pyqt5

查看:1173
本文介绍了在pyqt5中对QTableView进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在PyQT5中对QTableView进行排序。
我找到了一个使用PyQT4的示例,但是在PyQT5中,不再有SIGNAL。
这是我的示例代码

I want to sort a QTableView in PyQT5. I found an example that uses PyQT4, but in PyQT5 SIGNALs are not existing anymore. This is my example code

class MainWindow(QWidget):
def __init__(self, parent=None):
    super(MainWindow, self).__init__(parent)
    # create table
    self.get_table_data()
    table = self.createTable() 

    # layout
    layout = QVBoxLayout()
    layout.addWidget(table) 
    self.setLayout(layout) 

def get_table_data(self):
    stdouterr = os.popen("dir c:\\").read()
    lines = stdouterr.splitlines()
    lines = lines[5:]
    lines = lines[:-2]
    self.tabledata = [re.split(r"\s+", line, 4)
                 for line in lines]

def createTable(self):
    # create the view
    tv = QTableView()

    # set the table model
    header = ['date', 'time', '', 'size', 'filename']
    tm = MyTableModel(self.tabledata, header, self) 
    tv.setModel(tm)
    # set the minimum size
    tv.setMinimumSize(400, 300)

    # hide grid
    tv.setShowGrid(False)

    tv.setSelectionBehavior(QAbstractItemView.SelectRows)
    # set the font

    # hide vertical header
    vh = tv.verticalHeader()
    vh.setVisible(False)

    # set horizontal header properties
    hh = tv.horizontalHeader()
    hh.setStretchLastSection(True)

    # set column width to fit contents
    tv.resizeColumnsToContents()

    # set row height
    nrows = len(self.tabledata)
    for row in range(nrows):
        tv.setRowHeight(row, 18)

    # enable sorting
    tv.setSortingEnabled(True)

    return tv
    self.setWindowTitle("Finance")

class MyTableModel(QAbstractTableModel): 
def __init__(self, datain, headerdata, parent=None, *args): 
    """ datain: a list of lists
        headerdata: a list of strings
    """
    QAbstractTableModel.__init__(self, parent, *args) 
    self.arraydata = datain
    self.headerdata = headerdata

def rowCount(self, parent): 
    return len(self.arraydata) 

def columnCount(self, parent): 
    return len(self.arraydata[0]) 

def data(self, index, role): 
    if not index.isValid(): 
        return QVariant() 
    elif role != Qt.DisplayRole: 
        return QVariant() 
    return QVariant(self.arraydata[index.row()][index.column()]) 

def headerData(self, col, orientation, role):
    if orientation == Qt.Horizontal and role == Qt.DisplayRole:
        return QVariant(self.headerdata[col])
    return QVariant()
def sort(self, Ncol, order):
    """Sort table by given column number.
    """
    self.emit(SIGNAL("layoutAboutToBeChanged()"))
    self.arraydata = sorted(self.arraydata, key=operator.itemgetter(Ncol))        
    if order == Qt.DescendingOrder:
        self.arraydata.reverse()
    self.emit(SIGNAL("layoutChanged()"))

if __name__ == '__main__':

from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)

helloPythonWidget = MainWindow()
helloPythonWidget.show()

sys.exit(app.exec_())

使用self.layoutAboutToBeChanged()和pyqtSignal的方法多种多样,但是老实说,我不理解,因为我对python和PyQT还是陌生的。
我试图从文档中获取信息,但是我没有从文档中得到任何线索,也没有在网络上找到一个很好的例子。

I tried many different ways to use self.layoutAboutToBeChanged() and pyqtSignal, but to be honest, I don't understand it, since I'm new to python and PyQT in general yet. I tried to get infos from the Documentation, but i didn't get a clue from documentation and didn't found an good example on the web.

更新:

我解决了这个难题:

self.layoutAboutToBeChanged.emit()发出信号(日食中的代码补全有点误导)

self.layoutAboutToBeChanged.emit() emits the signal (codecompletion in eclipse is a bit misleading)

def sort(self, Ncol, order):
    """Sort table by given column number.
    """
    self.layoutAboutToBeChanged.emit()
    self.arraydata = sorted(self.arraydata, key=operator.itemgetter(Ncol))        
    if order == Qt.DescendingOrder:
        self.arraydata.reverse()
    self.layoutChanged.emit()

这是解决方案

推荐答案

对于那些想要将pandas数据框导入qt模型的人来说,请尝试以下操作:

for those of you guys who wants to import pandas dataframe into qt model try this:

class PandasModel(QtCore.QAbstractTableModel):

    def __init__(self, data, parent=None):
        """

        :param data: a pandas dataframe
        :param parent: 
        """
        QtCore.QAbstractTableModel.__init__(self, parent)
        self._data = data
        # self.headerdata = data.columns


    def rowCount(self, parent=None):
        return len(self._data.values)

    def columnCount(self, parent=None):
        return self._data.columns.size

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if index.isValid():
            if role == QtCore.Qt.DisplayRole:
                return str(self._data.values[index.row()][index.column()])
        return None

    def headerData(self, rowcol, orientation, role):
        # print(self._data.columns[rowcol])
        # print(self._data.index[rowcol])
        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            return self._data.columns[rowcol]
        if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole:
            return self._data.index[rowcol]
        return None

    def flags(self, index):
        flags = super(self.__class__, self).flags(index)
        flags |= QtCore.Qt.ItemIsEditable
        flags |= QtCore.Qt.ItemIsSelectable
        flags |= QtCore.Qt.ItemIsEnabled
        flags |= QtCore.Qt.ItemIsDragEnabled
        flags |= QtCore.Qt.ItemIsDropEnabled
        return flags

    def sort(self, Ncol, order):
        """Sort table by given column number.
        """
        try:
            self.layoutAboutToBeChanged.emit()
            self._data = self._data.sort_values(self._data.columns[Ncol], ascending=not order)
            self.layoutChanged.emit()
        except Exception as e:
            print(e)

我忘记了从哪里获得基本的pandasmodel,可能是从此处

I have forgotten where I got the base pandasmodel, probably from here

这篇关于在pyqt5中对QTableView进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆