按数字排序QTableWidgetItem

0 投票
2 回答
1497 浏览
提问于 2025-04-17 14:51

我正在尝试用Python和PyQt4创建一个表格。

现在它的排序方式是这样的:

100, 10, 1, 2 

等等……

我希望它能按这样的方式排序:

1,2,10,100

等等

我现在使用的是

self.table.setSortingEnabled(True)

但我觉得这可能是导致它这样排序的原因?能不能请大家帮我正确排序一下?

窗口的完整代码在这里:

def BuildCustomerDetails(self):

    # Create Table
    self.mainLayout = QtGui.QGridLayout()

    # Construct table items

    db = sqlite3.connect("Database")
    cursor = db.cursor()

        #ID
    cursor.execute("""SELECT ID FROM Customer;""")
    items = cursor.fetchall()
    ID = []
    for row in items:
        item = row[0]
        ID.append(item)



        #First name
    cursor.execute("""SELECT FirstName FROM Customer;""")
    items = cursor.fetchall()
    firstName = []
    for row in items:
        item = row[0]
        firstName.append(item)
    height = len(items)

        #Surname
    cursor.execute("""SELECT Surname FROM Customer;""")
    items = cursor.fetchall()
    Surname = []
    for row in items:
        item = row[0]
        Surname.append(item)

        #First Line Address
    cursor.execute("""SELECT firstLineAddress FROM Customer;""")
    items = cursor.fetchall()
    firstLineAddress = []
    for row in items:
        item = row[0]
        firstLineAddress.append(item)

        #Second Line Address
    cursor.execute("""SELECT SecondLineAddress FROM Customer;""")
    items = cursor.fetchall()
    SecondLineAddress = []
    for row in items:
        item = row[0]
        SecondLineAddress.append(item)

        #Town
    cursor.execute("""SELECT Town FROM Customer;""")
    items = cursor.fetchall()
    Town = []
    for row in items:
        item = row[0]
        Town.append(item)

        #Postcode
    cursor.execute("""SELECT Postcode FROM Customer;""")
    items = cursor.fetchall()
    Postcode = []
    for row in items:
        item = row[0]
        Postcode.append(item)


    # TABLE
    self.table = QtGui.QTableWidget(height,7,self)

    self.horizontalHeaderItem1 = QtGui.QTableWidgetItem("ID")
    self.horizontalHeaderItem2 = QtGui.QTableWidgetItem("First Name")
    self.horizontalHeaderItem3 = QtGui.QTableWidgetItem("Surname")
    self.horizontalHeaderItem4 = QtGui.QTableWidgetItem("Address Line 1")
    self.horizontalHeaderItem5 = QtGui.QTableWidgetItem("Address Line 2")
    self.horizontalHeaderItem6 = QtGui.QTableWidgetItem("Town")
    self.horizontalHeaderItem7 = QtGui.QTableWidgetItem("Post Code")


    self.table.setHorizontalHeaderItem(0,self.horizontalHeaderItem1)
    self.table.setHorizontalHeaderItem(1,self.horizontalHeaderItem2)
    self.table.setHorizontalHeaderItem(2,self.horizontalHeaderItem3)
    self.table.setHorizontalHeaderItem(3,self.horizontalHeaderItem4)
    self.table.setHorizontalHeaderItem(4,self.horizontalHeaderItem5)
    self.table.setHorizontalHeaderItem(5,self.horizontalHeaderItem6)
    self.table.setHorizontalHeaderItem(6,self.horizontalHeaderItem7)

    self.table.setWindowFlags(Qt.Dialog)
    self.table.setSortingEnabled(True)

    ## ADD DATABASE ITEMS TO TABLE

        #ID
    for i in range(1, height):
        item = QtGui.QTableWidgetItem(ID[i])
        self.table.setItem(i,0,item)

        #product code
    for i in range(1, height):
        item = QtGui.QTableWidgetItem(firstName[i])
        self.table.setItem(i,1,item)

        #Surname
    for i in range(1, height):
        item = QtGui.QTableWidgetItem(Surname[i])
        self.table.setItem(i,2,item)

        #firstLineAddress
    for i in range(1, height):
        item = QtGui.QTableWidgetItem(firstLineAddress[i])
        self.table.setItem(i,3,item)

        #SecondLineAddress
    for i in range(1, height):
        item = QtGui.QTableWidgetItem(SecondLineAddress[i])
        self.table.setItem(i,4,item)

        #Town
    for i in range(1, height):
        item = QtGui.QTableWidgetItem(Town[i])
        self.table.setItem(i,5,item)

        #Postcode
    for i in range(1, height):
        item = QtGui.QTableWidgetItem(Postcode[i])
        self.table.setItem(i,6,item)


    # Create Widgets
    self.AddButton = QtGui.QPushButton("Add Customer",self)
    self.RemoveButton = QtGui.QPushButton("Remove Customer",self)
    self.MoreButton = QtGui.QPushButton("More Details",self)
    self.BackButton = QtGui.QPushButton("Back",self)

    # Create Layouts
    self.VLayout = QtGui.QVBoxLayout()
    self.HLayout = QtGui.QHBoxLayout()

    # Assemble

    self.VLayout.addWidget(self.AddButton)
    self.VLayout.addWidget(self.RemoveButton)
    self.VLayout.addWidget(self.MoreButton)
    self.VLayout.addWidget(self.BackButton)

    self.HLayout.addWidget(self.table)

    self.mainLayout.addLayout(TopBar(self),0,0,1,5)
    self.mainLayout.addLayout(self.VLayout,2,4)
    self.mainLayout.addLayout(self.HLayout,1,0,4,4)

    self.table.itemSelectionChanged.connect(self.getCell)


    self.MoreButton.clicked.connect(self.MoreCustomerDetailsLaunch)
    self.BackButton.clicked.connect(self.Back)
    self.AddButton.clicked.connect(self.AddCustomerLaunch)


    Menu(self)

    return self.mainLayout

谢谢

山姆

2 个回答

1

重新实现 QTableWidgetItem 可以这样做:

class MyTableWidgetItem(QtGui.QTableWidgetItem):
    def __init__(self, number):
        QtGui.QTableWidgetItem.__init__(self, number, QtGui.QTableWidgetItem.UserType)
        self.__number = number

    def __lt__(self, other):
        return self.__number < other.__number

所以,在需要按数字排序的地方,使用 MyTableWidgetItem 替代 QTableWidgetItem,像这样:

for i in range(1, height):
        item = MyTableWidgetItem(numbers[i])
        self.table.setItem(i,0,item)
1

QTableWidget这个类没有提供可以自定义排序的功能。如果你想要实现这个功能,可以尝试重新定义一下QTableWidgetItem__lt__操作符,至少在C++中这样做似乎是有效的,具体可以参考这个回答。

另外一种方法是在从Python端添加项目到表格时就进行排序,而不是在视图中启用排序功能。当你从数据库获取数据时,应该按照你想要的列进行排序,然后再为这些数据创建QTableWidgetItem。显然,如果你想动态更新列表,或者想要改变排序方式从升序变成降序,这样做会变得相当复杂。

撰写回答