如何用我自己的代码对QTableWidget进行排序? [英] How to sort a QTableWidget with my own code?
问题描述
我在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屋!