Hallo,
ich habe ein Programm, welches Daten aus einer SQL DB abfragt und in einer Tabelle darstellt. Da sich die Daten schnell ändern frage ich die DB alle 5 Sekunden ab, und erzeuge daraus ein liststore. Da ich zuerst ein liststore.clear machen muss, flackert die Tabelle jedes mal wenn sie neu aufgebaut wird.
Hat jemand vielleicht eine Idee, wie ich das besser/anders machen kann ?
Danke,
Wolle
treeview & liststore: flackert beim Neuaufbau
Anstatt das Model immer zu löschen (model.clear()) kannst du die jeweiligen TreeIter auch einfach updaten. Ich habe dazu immer ein Dict mit Referenzen auf die jeweiligen TreeIter angelegt, so dass man einfacher daran gelangt: http://paste.pocoo.org/show/270119/
Achtung, in dem Code sind ein paar Don'ts, mir spring gerade besonders dieser try-except-Block ins Auge. Ich hoffe, die grundlegende Idee wird daraus verständlich.
Damit konnte ich das Flackern bei mir abstellen (wenn ich mich recht erinnere).
Gruß,
brb
Achtung, in dem Code sind ein paar Don'ts, mir spring gerade besonders dieser try-except-Block ins Auge. Ich hoffe, die grundlegende Idee wird daraus verständlich.
Damit konnte ich das Flackern bei mir abstellen (wenn ich mich recht erinnere).
Gruß,
brb
Hallo,
vielleicht kannst du mir nochmal helfen mit dem treeview:
Ich habe einige nicht erklärbare Fehlermeldungen:
Ich habe deinen Code fast 1 zu 1 übernommen. Ich habe lediglich noch ein paar Zeilen zugefügt, in denen ich überflüssige Einträge aus dem TreeView lösche.
Manchmal stürzt das Programm auch einfach ab, nachdem der TreeView geleert wurde.
So langsam werde ich Ratlos, da sich nicht genau nachvollziehen lässt, woher das kommt.
Hier der code.
Gruß, Wolle
vielleicht kannst du mir nochmal helfen mit dem treeview:
Ich habe einige nicht erklärbare Fehlermeldungen:
oderWarning (from warnings module):
File "/home/wolfgang/Desktop/parcour/gui/main.py", line 943
gtk.main()
Warning: g_object_ref: assertion `object->ref_count > 0' failed
Im Moment starte ich das Aktualisieren des TreeViews von einem weiteren thread, indem ich per __gsignals__ die entsprechende Funktion in meinem Hauptthread starte. Ich starte sie alle 2 sekunden, aber ich habe auch schon mal alle 5 Sekunden versucht (ohne Erfolg).Warning (from warnings module):
File "/home/wolfgang/Desktop/parcour/gui/main.py", line 945
gtk.main()
Warning: g_object_ref: assertion `G_IS_OBJECT (object)' failed
Ich habe deinen Code fast 1 zu 1 übernommen. Ich habe lediglich noch ein paar Zeilen zugefügt, in denen ich überflüssige Einträge aus dem TreeView lösche.
Manchmal stürzt das Programm auch einfach ab, nachdem der TreeView geleert wurde.
So langsam werde ich Ratlos, da sich nicht genau nachvollziehen lässt, woher das kommt.
Hier der code.
Gruß, Wolle
Zuletzt geändert von w.olle am Sonntag 14. November 2010, 14:17, insgesamt 1-mal geändert.
Mit welcher Fehlermeldung / welchem Verhalten?w.olle hat geschrieben:Manchmal stürzt das Programm auch einfach ab, nachdem der TreeView geleert wurde.
so Konstrukte wie diese solltest du vermeiden:
Code: Alles auswählen
except:
Hallo,
es ist immer das Gleiche: Nachdem die ersten paar Zeilen zum TreeView (gtk.ListStore) hinzugefügt wurden kommt immer folgende Meldung:
Es stürtzt nicht jedesmal ab, aber wenn, dann immer, wenn der TreeView geleert wird (sieht man am print 'del'). Gerade kam beim Absturz z.B. die folgende Meldung:
...und beim zweiten Druchlauf stürtzte es mit dieser Meldung ab:
Ich habe inzwischen try - except weggenommen, aber daher kann es eigentlich nicht kommen. Ich bin ziemlich ratlos. Leider kann ich TreeView.clear() nicht nehmen, da auch öfters nur einzelne Zeilen gelöscht werden.
Gruß, Wolle
es ist immer das Gleiche: Nachdem die ersten paar Zeilen zum TreeView (gtk.ListStore) hinzugefügt wurden kommt immer folgende Meldung:
Code: Alles auswählen
Warning (from warnings module):
File "/home/wolfgang/Desktop/parcour/gui/test.py", line 943
gtk.main()
Warning: g_object_ref: assertion `object->ref_count > 0' failed
Warning (from warnings module):
File "/home/wolfgang/Desktop/parcour/gui/test.py", line 943
gtk.main()
Warning: g_object_ref: assertion `G_IS_OBJECT (object)' failed
Warning (from warnings module):
File "/home/wolfgang/Desktop/parcour/gui/test.py", line 943
gtk.main()
Warning: g_object_unref: assertion `G_IS_OBJECT (object)' failed
Code: Alles auswählen
del
del
del
del
Warning (from warnings module):
File "/home/wolfgang/Desktop/parcour/gui/test.py", line 943
gtk.main()
GtkWarning: gtk_list_store_get_value: assertion `VALID_ITER (iter, list_store)' failed
Warning (from warnings module):
File "/home/wolfgang/Desktop/parcour/gui/test.py", line 943
gtk.main()
Warning: g_object_set_property: assertion `G_IS_VALUE (value)' failed
del
Warning (from warnings module):
File "/home/wolfgang/Desktop/parcour/gui/test.py", line 943
gtk.main()
Warning: g_value_unset: assertion `G_IS_VALUE (value)' failed
Code: Alles auswählen
Warning (from warnings module):
File "/home/wolfgang/Desktop/parcour/gui/test.py", line 943
gtk.main()
GtkWarning: /build/buildd/gtk+2.0-2.22.0/gtk/gtktreeview.c:5025 (gtk_tree_view_bin_expose): assertion `has_next' failed.
There is a disparity between the internal view of the GtkTreeView,
and the GtkTreeModel. This generally means that the model has changed
without letting the view know. Any display from now on is likely to
be incorrect.
Gruß, Wolle
Ich finde den Codeabschnitt ab 92 irgendwie etwas merkwürdig:
Ich könnte mir gut vorstellen, dass das Problem damit zusammenhängt, dass du über die TreeIter des TreeStores iterierst, gleichzeitig aber auch Iters entfernst - ich denke, dass das zu Fehlern führt. Hier könnten unter Umständen TreeRowReferences sinnvoll sein.
Zur Not würde ich erstmal die zu löschenden Iter in eine Liste packen und *nach* dem Iterieren löschen.
Die Fehlermeldung "gtk_list_store_get_value: assertion `VALID_ITER (iter, list_store)' " zeigt ja, dass du irgendwie mit ungültigen TreeIter operierst. Wahrscheinlich hängt das echt damit zusammen, dass du das Objekt, über das du iterierst, beim iterieren veränderst.
Deine Thread-Klasse ist doch eigentlich nur ein selbstgebauter Ersatz für gobject.timeout_add(), oder? Dann würde ich das auch verwenden:
Wichtig ist dann aber, dass self.fill_store() "True" zurück gibt, damit es nächstes Mal wieder aufgerufen wird.
Ich könnte mir gut vorstellen, dass das Problem damit zusammenhängt, dass du über die TreeIter des TreeStores iterierst, gleichzeitig aber auch Iters entfernst - ich denke, dass das zu Fehlern führt. Hier könnten unter Umständen TreeRowReferences sinnvoll sein.
Zur Not würde ich erstmal die zu löschenden Iter in eine Liste packen und *nach* dem Iterieren löschen.
Die Fehlermeldung "gtk_list_store_get_value: assertion `VALID_ITER (iter, list_store)' " zeigt ja, dass du irgendwie mit ungültigen TreeIter operierst. Wahrscheinlich hängt das echt damit zusammen, dass du das Objekt, über das du iterierst, beim iterieren veränderst.
Deine Thread-Klasse ist doch eigentlich nur ein selbstgebauter Ersatz für gobject.timeout_add(), oder? Dann würde ich das auch verwenden:
Code: Alles auswählen
gobject.timeout_add(1000, self.fill_store)
Hey, super !!
ich habe zum einen gobject.timeout_add() eingefügt (super, kannte ich gar nicht), und ich verwende jetzt eine liste in der ich die zu löschenden iter sammle. Klappt bislang ohne Probleme.
Zur Vollständigkeit:
Ich habe noch vor jedem gtk.ListStore.set(), bzw. gtk.ListStore.remove() ein gtk.gdk.threads_enter() und dahinter ein gtk.gdk.threads_leave() eingefügt, damit die GUI besser läuft.
Hier der endgültige code
Danke, Dank, Danke für die schnelle Hilfe !!
ich habe zum einen gobject.timeout_add() eingefügt (super, kannte ich gar nicht), und ich verwende jetzt eine liste in der ich die zu löschenden iter sammle. Klappt bislang ohne Probleme.
Zur Vollständigkeit:
Ich habe noch vor jedem gtk.ListStore.set(), bzw. gtk.ListStore.remove() ein gtk.gdk.threads_enter() und dahinter ein gtk.gdk.threads_leave() eingefügt, damit die GUI besser läuft.
Hier der endgültige code
Danke, Dank, Danke für die schnelle Hilfe !!

Hallo Wolle,
freut mich, dass es läuft - allerdings benötigst du threads_enter() bzw. threads_leave() nur, wenn du tatsächlich aus einem anderen Thread ein GTK-Objekt manipulierst. Und das machst du ja nicht mehr, weil gobject.timeout_add() meines Wissens auf den GTK-Thread aufspringt (ähnlich wie idle_add()).
Kurz gesagt: Eigentlich (TM) sollte das mit threads_enter() / threads_leave() keinen Unterschied bewirken
.
Besten Gruß,
brb
freut mich, dass es läuft - allerdings benötigst du threads_enter() bzw. threads_leave() nur, wenn du tatsächlich aus einem anderen Thread ein GTK-Objekt manipulierst. Und das machst du ja nicht mehr, weil gobject.timeout_add() meines Wissens auf den GTK-Thread aufspringt (ähnlich wie idle_add()).
Kurz gesagt: Eigentlich (TM) sollte das mit threads_enter() / threads_leave() keinen Unterschied bewirken

Besten Gruß,
brb