繁体   English   中英

在pyqt5中排序QTableView

[英]Sort QTableView in pyqt5

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

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的新手。 我试图从文档中获取信息,但我没有从文档中获得线索,也没有在网上找到一个好的例子。

更新:

我解开了谜题:

self.layoutAboutToBeChanged.emit()发出信号(eclipse中的codecompletion有点误导)

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模型的人,试试这个:

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,可能来自这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM