2010-02-20 11 views
6

Ich verwende Qt4.5.2 unter Linux. Ich habe ein einfaches QTableWidget, in dem eine Spalte Daten in einem benutzerfreundlichen Format anzeigt. Leider sind "menschenfreundliche Daten" nicht einfach zu sortieren. Also, im QTableWidget halte ich eine versteckte Spalte mit dem UNIX-Zeitstempel, der diesem Datum entspricht.Wie sortiere ich ein QTableWidget mit meinem eigenen Code?

Ich versuche sicherzustellen, dass, wenn eine Anfrage nach der Spalte DATE sortiert wird, in der Realität die Sortierung in der (unsichtbaren) Spalte TIMESTAMP erfolgt. Ich habe versucht, die Neuimplementierung sortByColumn (dies ist in Python) durch von QTableWidget Subklassen und definieren:

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

Doch wenn ich auf einem der Kopf meiner Tabelle klicken Sie auf die normale Sortiermethode weiterhin aufgerufen werden.

Wie kann ich es überschreiben?

Antwort

7

Sie können Ihre eigene Klasse von QTableWidgetItem ableiten und dann Ihren eigenen __lt__ Operator schreiben. Dies würde die Notwendigkeit für eine zusätzliche Spalte ebenfalls verringern. Etwas entlang der Linien von:

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_()) 

Das ist für mich richtigen Ergebnisse produziert, können Sie es laufen, sich zu überprüfen. Der Zellentext zeigt Text wie "Samstag 20. Februar 2010" an, aber wenn Sie die Spalte sortieren, wird sie korrekt nach dem Feld sortKey sortiert, das "2010-02-20" (iso-formatiert) ist.

Oh, es sollte auch beachtet werden, dass dies nicht mit PySide funktioniert, weil es scheint, dass der __lt__-Operator nicht gebunden ist, wo-wie es mit PyQt4 ist. Ich verbrachte eine Weile damit zu debuggen, warum es nicht funktionierte und dann wechselte ich von PySide zu PyQt4 und es funktionierte gut. Sie können feststellen, dass die __lt__ hier nicht aufgeführt ist:

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

aber es ist hier:

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

+0

Hallo, das hat mir wirklich geholfen. Ich brauchte meinen eigenen '__lt__'-Operator, damit ich checkbare tablewidget-Elemente in der ersten Spalte sortieren kann, aber jetzt, wenn ich 'tableWidget.setSortingEnabled (1)' aus irgendeinem Grund verwende, wird '__lt__' 100+ Mal aufgerufen, wenn ich ~ 15 Zeilen habe. auch wenn ich nicht auf den Header dieser Spalte geklickt habe, um sie zu sortieren. Noch größeres Problem ist, dass es in dieser Situation nicht richtig sortiert. Einige Zeilen werden gemischt, das ist alles, aber es funktioniert gut, wenn ich auf Header klicke. Gibt es einige Blockierungsfunktionen, die wir beim Überladen von '__lt__' bestehen? – Aleksandar