Mam niestandardową strukturę danych, którą chcę wyświetlić w aplikacji PyQt przy użyciu QTableView. Używam podklasy QAbstractTableModel do komunikacji z danymi. Sama struktura danych znajduje się w osobnym module i nic nie wie o PyQt.Jak zaktualizować QAbstractTableModel i QTableView po posortowaniu źródła danych?
Wyświetlanie i edytowanie danych za pomocą QTableView działa, ale teraz chciałbym posortować dane, a następnie zaktualizować model i widok.
Po zapoznaniu się z dokumentacją Qt dla QAbstractTableModel i jego przodka QAbstractItemModel, moje pierwsze podejście było spróbować tego:
class MyModel(QtCore.QAbstractTableModel):
__init__(self, data_structure):
super().__init__()
self.data_structure = data_structure
# ...
def sort_function(self):
self.layoutAboutToBeChanged.emit()
# custom_sort() is built into the data structure
self.data_structure.custom_sort()
self.layoutChanged.emit()
Jednak to nie aktualizuje widok. Próbowałem również emitować sygnał dataChanged na wszystkich danych używanych przez model, ale nie udało się zaktualizować również widok.
Zrobiłem dalsze badania. Jeśli rozumiem poprawnie, problem polega na tym, że QPersistentModelIndexes w modelu nie są aktualizowane, a rozwiązaniem byłoby ręczne ich zaktualizowanie.
Czy jest lepszy sposób to zrobić? Jeśli nie, to w jaki sposób chciałbym je zaktualizować (najlepiej bez konieczności pisania nowej funkcji sortującej, która śledzi każdą zmianę indeksu)?
Twój kod * powinien * działać, a Ty * nie powinieneś * martwić się trwałymi indeksami. Napisałem modele, które emitują te same sygnały co "funkcja sortowania" i poprawnie aktualizują widoki. Czy jesteś pewien, że twoja funkcja zostanie wywołana, 'custom_sort()' faktycznie zmienia dane i te zmiany są odzwierciedlane przez metodę 'data()' twojego modelu? –
@FerdinandBeyer Ahh, to był problem! Już sprawdziłem, że dane zostały zmienione, ale nie myślałem, aby sprawdzić samą metodę data(). custom_sort() kopiował niektóre elementy, które trzeba było sortować w miejscu. Dziękuję Ci bardzo! –
Bez problemu. Możesz zamieścić swoje rozwiązanie jako odpowiedź i zaakceptuj je, aby to pytanie zostało oznaczone jako odpowiedź! –