2010-02-20 8 views
6

Używam Qt4.5.2 na Linux. Mam prosty QTableWidget, w którym kolumna wyświetla daty w formacie przyjaznym dla ludzi. Niestety "terminy przyjazne człowiekowi" nie są łatwe do prawidłowego sortowania. Tak więc w QTableWidget przechowuję ukrytą kolumnę ze znacznikiem czasu UNIX odpowiadającym tej dacie.Jak sortować QTableWidget przy użyciu własnego kodu?

Próbuję się upewnić, że za każdym razem, gdy zostanie wysłane zapytanie o sortowanie w kolumnie DATA, w rzeczywistości sortowanie odbywa się w (niewidocznej) kolumnie TIMESTAMP. Próbowałem reimplementing sortByColumn (jest to w Pythonie) przez instacji od QTableWidget i określenia:

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

Jednak gdy klikam na jednym z nagłówków moim stole normalnej Metoda sortowania nadal nazwać.

Jak mogę to zmienić?

Odpowiedz

7

Można wyprowadzić własną klasę QTableWidgetItem, a następnie napisać własny operator __lt__. To złagodziłoby potrzebę dodatkowej kolumny. Coś wzdłuż linii:

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

Ten produkowany poprawne wyniki dla mnie, można uruchomić go samemu zweryfikować. W tekście komórki wyświetlany jest tekst "Sobota, 20 lutego 2010 r.", Ale po posortowaniu w kolumnie będzie on poprawnie sortowany według pola sortKey, które jest "2010-02-20" (format ISO).

Och, Należy również zauważyć, że NIE będzie to działało z PySide, ponieważ wygląda na to, że operator __lt__ nie jest związany, gdzie - jak to jest z PyQt4. Spędziłem chwilę próbując debugować, dlaczego to nie działa, a następnie przełączyłem się z PySide na PyQt4 i działało dobrze. Można zauważyć, że __lt__ nie jest wymieniony tutaj:

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

ale jest tutaj:

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

+0

Cześć, to naprawdę pomogło mi. Potrzebowałem własnego operatora '__lt__', aby móc sortować możliwe do sprawdzenia elementy tabeli w pierwszej kolumnie, ale teraz, gdy używam' tableWidget.setSortingEnabled (1) 'z jakiegoś powodu' __lt__' jest nazywane ponad 100 razy, gdy mam ~ 15 wierszy, nawet jeśli nie kliknęłam w nagłówek tej kolumny, aby ją posortować. Jeszcze większy problem polega na tym, że w tej sytuacji nie jest to właściwe. kilka wierszy się miesza to wszystko, ale działa dobrze po kliknięciu nagłówka. Czy istnieje kilka funkcji blokowania, które przekazujemy podczas przeciążania '__lt__'? – Aleksandar