Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python qabstractemodel中的不敏感排序_Python_Sorting_Pyqt4_Qtableview_Qabstracttablemodel - Fatal编程技术网

Python qabstractemodel中的不敏感排序

Python qabstractemodel中的不敏感排序,python,sorting,pyqt4,qtableview,qabstracttablemodel,Python,Sorting,Pyqt4,Qtableview,Qabstracttablemodel,我在尝试使用QabstracteModel创建自己的排序函数时遇到问题。它可以工作,但不区分大小写。我曾尝试使用QSortFilterProxyModel,但没有成功。我的排序功能: def sort(self, col, order): self.emit(SIGNAL("layoutAboutToBeChanged()")) self.tableData = sorted(self.tableData, key=operator.itemgetter(col))

我在尝试使用QabstracteModel创建自己的排序函数时遇到问题。它可以工作,但不区分大小写。我曾尝试使用QSortFilterProxyModel,但没有成功。我的排序功能:

def sort(self, col, order):
    self.emit(SIGNAL("layoutAboutToBeChanged()"))
    self.tableData = sorted(self.tableData, key=operator.itemgetter(col))       
    if order == Qt.AscendingOrder:
        self.tableData.reverse()
    self.emit(SIGNAL("layoutChanged()"))
我正在使用QTableView。我怎样才能使它不区分大小写

完整示例:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import operator
import sys

class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()

        header = ["one", "two"]
        tableDict = [["abcdef", "tuvwx"], ["aBcde", "TUvWx"], ["acdef","tUvWX"], ["Acdef", "TUVwx"], ["ACdef", "TUVwx"]]
        self.myTable = newTableModel(header, tableDict)

        mainLayout = QHBoxLayout()
        mainLayout.addWidget(self.myTable.tableView)
        self.setLayout(mainLayout)
        self.setWindowTitle("Test table")

class newTableModel(QAbstractTableModel): 
    def __init__(self, header, data, parent=None, *args):
        super(newTableModel, self).__init__(parent)
        self.tableView = QTableView()
        self.tableData = data
        self.header = header

        self.tableView.setShowGrid(True)
        self.tableView.setFrameStyle( QFrame.NoFrame )
        self.tableView.setFocusPolicy( Qt.NoFocus )
        self.tableView.setSelectionMode( QAbstractItemView.NoSelection )

        vHeader = self.tableView.verticalHeader()
        vHeader.setVisible(False)
        vHeader.setStretchLastSection(False)
        hHeader = self.tableView.horizontalHeader()
        hHeader.setVisible(True)
        hHeader.setStretchLastSection(False)
        self.tableView.setSortingEnabled(True)

        self.tableView.setModel(self)
        self.tableView.resizeRowsToContents()
        self.tableView.resizeColumnsToContents()
        vHeader.setResizeMode(QHeaderView.ResizeToContents)

        self.tableView.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.tableView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

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

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

    def data(self, index, role=Qt.DisplayRole):
        row = index.row()
        col = index.column()
        if role == Qt.DisplayRole:
            return "{0}".format(self.tableData[row][col])
        return None

    def setData(self, index, value, role):
        if index.isValid():
             return True
        return False

    def flags(self, index):
        fl = QAbstractTableModel.flags(self, index)
        if index.column() == 0:
            fl |= Qt.ItemIsUserCheckable
        return fl

    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.header[col]

    def sort(self, col, order):
        self.emit(SIGNAL("layoutAboutToBeChanged()"))
        self.tableData = sorted(self.tableData, key=operator.itemgetter(col))      
        if order == Qt.AscendingOrder:
            self.tableData.reverse()
        self.emit(SIGNAL("layoutChanged()"))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

示例中的表数据显示排序-不区分大小写。

您只需将传递给
排序
函数的排序键中的值转换为小写(或大写)。为了提高效率,还可以使用反向参数,以避免在单独的步骤中执行此操作:

def sort(self, col, order):
    self.layoutAboutToBeChanged.emit()
    self.tableData = sorted(
        self.tableData,
        key=lambda row: row[col].lower(),
        reverse=(order != Qt.AscendingOrder),
        )
    self.layoutChanged.emit()
请注意,
sorted
进行稳定排序,因此相等的值(在应用键后)将保留其原始位置。因此,示例中的第二列在排序时不会显示任何更改,因为值都是“相同的”(如果忽略大小写)

更新

这里有一个适用于字符串和数字的解决方案。它假定列不是两种类型的混合体:

def sort(self, col, order):
    if self.tableData and self.tableData[0]:
        self.layoutAboutToBeChanged.emit()
        if isinstance(self.tableData[0][col], str):
            sortkey = lambda row: row[col].lower()
        else:
            sortkey = operator.itemgetter(col)
        self.tableData = sorted(
            self.tableData, key=sortkey,
            reverse=(order != Qt.AscendingOrder))
        self.layoutChanged.emit()

提供一个我已经更新的代码,现在有完整的示例使用
self.dataChanged.emit(self.index(0,0),self.index(self.rowCount()-1,self.columnCount()-1))
在函数末尾,还将
def rowCount(self,parent)
更改为
def rowCount(self,parent=QModelIndex())
def columnCount(self,parent)
def columnCount(self,parent=QModelIndex())
我必须做一些其他错误的事情,因为仍然不起作用。例如,在我有字符串的第一列中,许多名字,首先是大字母,然后是小写字母。我想要分类Aa,Bb,。。。谢谢你的解释和帮助!如何检查数据是否不是str类型?原因此解决方案不适用于我拥有的多类型表(数字和字符串,取决于列)<代码>下限()不能用于int或float。但是它对弦很酷@戴夫。你可以只做
str(row[col]).lower()
。我以前试过,但那不利于排序(例如11、115、178、25、278等)@Dave。所以列实际上是所有字符串或所有数字,而不是一个混合体?是的,在列中分开。有些列仅为
str
,有些列为
int
float
。我在寻找某种检查类型的方法,然后我可以针对每种情况使用特定的
sorted()
方法