PyQt4 erzwingt die Ansicht von FetchMore von QAbstractItemModel

8

Ich habe eine QTableView, die dynamisch Daten von einem benutzerdefinierten Modell lädt, das QAbstractItemModel erbt. Das Modell implementiert fetchMore und canFetchMore.

Das Problem ist, dass ich alle Zeilen für kleine Datensätze auswählen möchte, aber wenn ich ctrl-a in der Ansicht drücke, werden nur die Zeilen ausgewählt, die gerade geladen sind.

Gibt es Mechanismen, die QTableView zwingen, mehr Zeilen zu holen? Idealerweise möchte ich einen Fortschrittsbalken anzeigen, der den Bruchteil der Daten anzeigt, die aus dem Modell geladen wurden. Alle paar Sekunden möchte ich das Modell zwingen, ein bisschen mehr von den Daten zu laden, aber ich möchte immer noch den Benutzer mit den Daten interagieren lassen, die bisher geladen wurden. Auf diese Weise kann der Benutzer nach Abschluss des Fortschrittsbalkens Strg-A drücken und sich sicher sein, dass alle Daten ausgewählt sind.

Edit: Ich habe einen anderen motivierenden Anwendungsfall. Ich möchte zu einer bestimmten Zeile springen, aber wenn diese Zeile nicht geladen ist, macht meine Schnittstelle nichts.

Wie kann ich ein QAbstractItemModel dazu zwingen, mehr (oder bis zu einer bestimmten Zeile) zu holen und dann die QTableView zu zwingen, es anzuzeigen?

Wenn ich fetchMore und canFetchMore nicht implementiere, funktioniert die vorherige Funktionalität, aber das Laden der Tabellen ist sehr langsam. Wenn ich diese Methoden umsetze, passiert das Gegenteil. Keine Antwort auf dieses Problem zu haben, verursacht Probleme mit der Benutzerfreundlichkeit meiner qt-Oberfläche, also eröffne ich ein Kopfgeld für diese Frage.

Hier ist eine Methode, mit der ich eine bestimmte Zeile auswähle.

%Vor%

Wenn der Benutzer manuell über die betreffende Zeile gescrollt hat, funktioniert diese Funktion. Wenn der Benutzer die bestimmte Zeile jedoch nicht gesehen hat, scrollt diese Funktion nur zum Anfang der Ansicht zurück.

    
Erotemic 21.07.2016, 14:20
quelle

1 Antwort

4

Es ist wahrscheinlich zu spät für die Antwort hier, aber vielleicht würde es in Zukunft noch jemandem nützen.

Unten kann man ein funktionierendes Beispiel eines Listenmodells mit den Methoden canFetchMore und fetchMore + einer Ansicht mit ein paar benutzerdefinierten Methoden finden:

  1. Methode, die versucht, mehr Elemente aus dem Modell zu laden, wenn das Modell noch nicht geladen ist
  2. Methode, die die spezifischen Zeilen aus dem Modell abrufen kann, wenn sie noch nicht geladen wurden

Die Unterklasse QMainWindow im Beispiel hat einen Timer, mit dem die erste der oben genannten Methoden wiederholt aufgerufen wird, wobei jedes Mal die Ladung eines anderen Postenstapels aus dem Modell in die Ansicht gezwungen wird. Das Laden von Elementen in Stapeln über kleine Zeitintervalle ermöglicht es, den UI-Thread nicht vollständig zu blockieren und die bisher geladenen Elemente mit wenig bis keinen Verzögerungen zu bearbeiten. Das Beispiel enthält einen Fortschrittsbalken, der den Teil der bisher geladenen Elemente anzeigt.

Die Unterklasse QMainWindow hat auch eine Drehbox, mit der man eine bestimmte Reihe auswählen kann, die in der Ansicht angezeigt wird. Wenn das entsprechende Objekt bereits aus dem Modell abgerufen wurde, scrollt die Ansicht einfach dorthin. Andernfalls ruft es das Element dieser Zeile zuerst synchron aus dem Modell ab, d. H. UI blockiert.

Hier ist der vollständige Code der Lösung, getestet mit Python 3.5.2 und PyQt5:

%Vor%

Ich möchte noch erwähnen, dass dieses Beispiel erwartet, dass die Methode fetchMore synchron arbeitet. Bei anspruchsvolleren Ansätzen muss fetchMore dies jedoch nicht tun. Wenn Ihr Modell seine Elemente beispielsweise aus einer Datenbank lädt, wäre eine synchrone Kommunikation mit der Datenbank im UI-Thread eine schlechte Idee. Stattdessen könnte fetchMore implementation die asynchrone Sequenz der Signal / Slot-Kommunikation mit einem Objekt starten, das die Kommunikation mit der Datenbank behandelt, die in einem Hintergrundthread auftritt.

    
Dmitry 15.11.2016, 11:55
quelle