如何用我自己的代码对QTableWidget进行排序? [英] How to sort a QTableWidget with my own code?

查看:689
本文介绍了如何用我自己的代码对QTableWidget进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Linux上使用Qt4.5.2.我有一个简单的QTableWidget,其中的一列以人类友好的格式显示日期.不幸的是,人性化的日期"不容易正确地排序.因此,在QTableWidget中,我保留了一个隐藏列,其中包含与该日期对应的UNIX时间戳.

我试图确保每当发出对DATE列进行排序的请求时,实际上都是在(不可见的)TIMESTAMP列上进行排序.我尝试通过从QTableWidget进行子类化并定义以下内容来重新实现sortByColumn(在Python中):

   def sortByColumn(self, col, order):
       print 'got request to sort col %d in order %s' % (col, str(order) )

但是,每当我单击表的标题之一时,就会继续调用普通的排序方法.

如何覆盖它?

解决方案

您可以派生自己的QTableWidgetItem类,然后编写自己的__lt__运算符.这也将减少对额外列的需求.类似于以下内容:

from PyQt4 import QtCore, QtGui
import sys
import datetime

class MyTableWidgetItem(QtGui.QTableWidgetItem):
    def __init__(self, text, sortKey):
        #call custom constructor with UserType item type
        QtGui.QTableWidgetItem.__init__(self, text, QtGui.QTableWidgetItem.UserType)
        self.sortKey = sortKey

    #Qt uses a simple < check for sorting items, override this to use the sortKey
    def __lt__(self, other):
        return self.sortKey < other.sortKey

app = QtGui.QApplication(sys.argv)
window = QtGui.QMainWindow()
window.setGeometry(0, 0, 400, 400)

table = QtGui.QTableWidget(window)
table.setGeometry(0, 0, 400, 400)
table.setRowCount(3)
table.setColumnCount(1)

date1 = datetime.date.today()
date2 = datetime.date.today() + datetime.timedelta(days=1)
date3 = datetime.date.today() + datetime.timedelta(days=2)

item1 = MyTableWidgetItem(str(date1.strftime("%A %d. %B %Y")), str(date1))
item2 = MyTableWidgetItem(str(date2.strftime("%A %d. %B %Y")), str(date2))
item3 = MyTableWidgetItem(str(date3.strftime("%A %d. %B %Y")), str(date3))

table.setItem(0, 0, item1)
table.setItem(2, 0, item2)
table.setItem(1, 0, item3)
table.setSortingEnabled(True)

window.show()
sys.exit(app.exec_())

这对我产生了正确的结果,您可以自己运行进行验证.单元格文本显示诸如"2010年2月20日星期六"之类的文本,但是当您对该列进行排序时,它将按sortKey字段"2010-02-20"(iso格式)正确排序.

哦,还应该注意的是,这对PySide不起作用,因为看来__lt__运算符没有绑定,就像PyQt4一样.调试为什么它不起作用,然后我从PySide切换到PyQt4,它运行良好.您可能会注意到__lt__不在此处列出:

http://www.pyside.org/docs/pyside/PySide/QtGui/QTableWidgetItem.html

但它在这里:

http://doc.qt.digia.com/4.5/qtablewidgetitem.html#operator-lt

I am using Qt4.5.2 on Linux. I have a simple QTableWidget, in which a column displays dates in a human-friendly format. Unfortunately "human-friendly dates" are not easy to sort correctly. So, in the QTableWidget I keep a hidden column with the UNIX timestamp corresponding to that date.

I am trying to make sure that, whenever a request to sort on the DATE column is issued, in reality the sort be done on the (invisible) TIMESTAMP column. I tried reimplementing sortByColumn (this is in Python) by subclassing from QTableWidget and defining:

   def sortByColumn(self, col, order):
       print 'got request to sort col %d in order %s' % (col, str(order) )

Yet, whenever I click on one of the headers of my table the normal sort method continues to be called.

How can I override it?

解决方案

You could derive your own class of QTableWidgetItem and then write your own __lt__ operator. This would alleviate the need for an extra column as well. Something along the lines of:

from PyQt4 import QtCore, QtGui
import sys
import datetime

class MyTableWidgetItem(QtGui.QTableWidgetItem):
    def __init__(self, text, sortKey):
        #call custom constructor with UserType item type
        QtGui.QTableWidgetItem.__init__(self, text, QtGui.QTableWidgetItem.UserType)
        self.sortKey = sortKey

    #Qt uses a simple < check for sorting items, override this to use the sortKey
    def __lt__(self, other):
        return self.sortKey < other.sortKey

app = QtGui.QApplication(sys.argv)
window = QtGui.QMainWindow()
window.setGeometry(0, 0, 400, 400)

table = QtGui.QTableWidget(window)
table.setGeometry(0, 0, 400, 400)
table.setRowCount(3)
table.setColumnCount(1)

date1 = datetime.date.today()
date2 = datetime.date.today() + datetime.timedelta(days=1)
date3 = datetime.date.today() + datetime.timedelta(days=2)

item1 = MyTableWidgetItem(str(date1.strftime("%A %d. %B %Y")), str(date1))
item2 = MyTableWidgetItem(str(date2.strftime("%A %d. %B %Y")), str(date2))
item3 = MyTableWidgetItem(str(date3.strftime("%A %d. %B %Y")), str(date3))

table.setItem(0, 0, item1)
table.setItem(2, 0, item2)
table.setItem(1, 0, item3)
table.setSortingEnabled(True)

window.show()
sys.exit(app.exec_())

This produced correct results for me, you can run it yourself to verify. The cell text displays text like "Saturday 20. February 2010" but when you sort on the column it will correctly sort by the sortKey field which is "2010-02-20" (iso formatted).

Oh, it should also be noted that this will NOT work with PySide because it appears that the __lt__ operator is not bound, where-as it is with PyQt4. I spent a while trying to debug why it wasn't working and then I switched from PySide to PyQt4 and it worked fine. You may notice that the __lt__ is not listed here:

http://www.pyside.org/docs/pyside/PySide/QtGui/QTableWidgetItem.html

but it is here:

http://doc.qt.digia.com/4.5/qtablewidgetitem.html#operator-lt

这篇关于如何用我自己的代码对QTableWidget进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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