Hi Leute,
ich möchte gerne eine progressbar und der Funktion pulse() verwenden. Wenn ich die Methode aufrufe, wird der Balken ja aber nur einmal weiter gerückt, und wandert nicht die ganze Zeit hin und her so wie ich es zB aus Ubuntu gewohnt bin. Die Frage ist jetzt, gibt es eine Möglichkeit diesen Balken automatisch immer weiter wandern zu lassen? Ich möchte eigentlich nicht immer die pulse() Funktion aufrufen, ich finde das eigentlich etwas störend. Ich glaube auch das die Dialoge bei Ubuntu das nciht tuen, da der Balken sich dort sehr gleichmäßig bewegt.
Freue mich schon auf Antworten!
MFG, weißned
progressbar und pulse
-
- User
- Beiträge: 996
- Registriert: Mittwoch 9. Januar 2008, 13:48
Das ist doch totaler Blödsinn. Warum eine Fortschrittsanzeige benutzen, wenn du eh keinen Fortschritt anzeigen kannst? Verarsch doch deine Nutzer nicht :)
Wenn es sein muss: GTK bietet an, bestimmten Code nach N Millisekunden aufzurufen (Timeouts).
Wenn es sein muss: GTK bietet an, bestimmten Code nach N Millisekunden aufzurufen (Timeouts).
@Dauerbaustelle: Es zeigt dem Benutzer wenigstens an, dass die Anwendung etwas tut. Das ist für den Benutzer durchaus wichtig zu wissen, und zudem dauert eine Wartezeit gefühlt weniger lang, wenn man etwas beim Arbeiten zusehen kann.
@weißned: Lies mal die Dokumentation zu gtk.ProgressBar.puls, dann glaubst Du vielleicht, dass andere Anwendungen die Funktion auch immer wieder aufrufen (müssen!) um den Balken am Laufen zu halten.
@Dauerbaustelle: Fortschritt anzeigen zu wollen und zu wissen wie weit man fortgeschritten ist, sind ja zwar paar verschiedene Schuhe. Den Benutzer mit einem "pulsierenden" Balken darüber zu informieren, dass das Programm etwas tut was länger dauert, würde ich nicht als verarschen bezeichnen. Die Alternative ist doch, dass der Benutzer denkt das Programm ist abgestürzt, wenn sich nichts mehr tut.
@Dauerbaustelle: Fortschritt anzeigen zu wollen und zu wissen wie weit man fortgeschritten ist, sind ja zwar paar verschiedene Schuhe. Den Benutzer mit einem "pulsierenden" Balken darüber zu informieren, dass das Programm etwas tut was länger dauert, würde ich nicht als verarschen bezeichnen. Die Alternative ist doch, dass der Benutzer denkt das Programm ist abgestürzt, wenn sich nichts mehr tut.
Weils lässig aussieht? Weil ichs kann?
Ne eigentlich finde ich es ganz praktisch, da ich am Anfang nicht weiß wie lange es dauert bis zB ein Prozess beendet wurde. Mit dem pulse() kann ich dem User aber symbolisieren, das die Anwendung gerade etwas macht. Ich könnte natürlch auch einfach ein Label nehmen wo Bitte warten steht, aber wieso soll ich so etwas nicht nutzen?
Und wenn man so eine Funktion eingebaut hat, kann sie eigentlich gar nicht so daneben sein.
Wie meinst du das mit Timeouts? Aber jetzt wo du es sagst, könnte man es mit Timern machen
edit:
@BlackJack: Okay ja ich glaube des schon, aber irgendwie finde ich das bisschen doof. Wenn ich wirklich nen Prozess am laufen habe, dann kann ich das ja eigentlich gar nicht immer aufrufen >.<
Ich hab mal in den GDebi Source geschaut, blicke aber nicht wirklich durch. Die rufen pulse() aber auch nur 3 mal auf, und der Balken wandert aber öfter als 3 mal denke ich ^^
Ne eigentlich finde ich es ganz praktisch, da ich am Anfang nicht weiß wie lange es dauert bis zB ein Prozess beendet wurde. Mit dem pulse() kann ich dem User aber symbolisieren, das die Anwendung gerade etwas macht. Ich könnte natürlch auch einfach ein Label nehmen wo Bitte warten steht, aber wieso soll ich so etwas nicht nutzen?
Und wenn man so eine Funktion eingebaut hat, kann sie eigentlich gar nicht so daneben sein.
Wie meinst du das mit Timeouts? Aber jetzt wo du es sagst, könnte man es mit Timern machen
edit:
@BlackJack: Okay ja ich glaube des schon, aber irgendwie finde ich das bisschen doof. Wenn ich wirklich nen Prozess am laufen habe, dann kann ich das ja eigentlich gar nicht immer aufrufen >.<
Ich hab mal in den GDebi Source geschaut, blicke aber nicht wirklich durch. Die rufen pulse() aber auch nur 3 mal auf, und der Balken wandert aber öfter als 3 mal denke ich ^^
@weißned: Wenn Du `pulse()` nicht aufrufst, sondern Dein Code an der Stelle etwas längeres anderes macht, dann friert die GUI komplett ein und sieht für den Benutzer (und das Betriebssystem) so aus, als wenn das Programm abgestürzt ist. Irgendwie musst Du ja regelmässig die GUI-Hauptschleife anstossen.
-
- User
- Beiträge: 996
- Registriert: Mittwoch 9. Januar 2008, 13:48
Das war doch irgendwas mit ``gtk.idle_add`` oder so.
@BlackJack:
Hmm, naja eigentlich brauche ich doch sowieso einen Hintergrund Thread oder nicht? Ich hatte mir das so gedacht, wie ich es aus Java und Swing kenne. Ich setze set_pulsing(True), dann mache ich meinen Langwierigen Prozess in einem andern Thread, wenn ich damit fertig bin mache ich set_pulsing(False) und bin fertig. Die Progressbar lässt dann den Balken einfach von alleine hin und her wandern.
@Dauerbaustelle:
Ja das braucht man um die GUI von einem anderen Thread aus zu aktualisieren.
Hmm, naja eigentlich brauche ich doch sowieso einen Hintergrund Thread oder nicht? Ich hatte mir das so gedacht, wie ich es aus Java und Swing kenne. Ich setze set_pulsing(True), dann mache ich meinen Langwierigen Prozess in einem andern Thread, wenn ich damit fertig bin mache ich set_pulsing(False) und bin fertig. Die Progressbar lässt dann den Balken einfach von alleine hin und her wandern.
@Dauerbaustelle:
Ja das braucht man um die GUI von einem anderen Thread aus zu aktualisieren.
-
- User
- Beiträge: 996
- Registriert: Mittwoch 9. Januar 2008, 13:48
Ah, ich meinte ``gtk.timeout_add``.
Code: Alles auswählen
~ PAGER=cat python -c 'help("gobject.timeout_add")'
Help on built-in function timeout_add in gobject:
gobject.timeout_add = timeout_add(...)
timeout_add(interval, callable, user_data=None,
priority=None) -> source id
callable receives (user_data)
Sets a callable be called repeatedly until it returns False.
Achso okay, werde ich mir mal ansehen. Aber wie returne ich dann False? ^^Dauerbaustelle hat geschrieben:Ah, ich meinte ``gtk.timeout_add``.
Code: Alles auswählen
~ PAGER=cat python -c 'help("gobject.timeout_add")' Help on built-in function timeout_add in gobject: gobject.timeout_add = timeout_add(...) timeout_add(interval, callable, user_data=None, priority=None) -> source id callable receives (user_data) Sets a callable be called repeatedly until it returns False.
Ist es nicht einfacher einen Timer zu starten, und den dann wenn die Operation fertig ist wieder zu stoppen?
-
- User
- Beiträge: 996
- Registriert: Mittwoch 9. Januar 2008, 13:48
Indem du z.B. in einer Instanzvariable speicherst, ob das Zeug fertig ist.
Das ist ja im Prinzip das Gleiche wie ein Timer, eben mit GTK-Bordmitteln.
Das ist ja im Prinzip das Gleiche wie ein Timer, eben mit GTK-Bordmitteln.
-
- User
- Beiträge: 996
- Registriert: Mittwoch 9. Januar 2008, 13:48
Klar kann man. Ich weiß jetzt auch nicht wirklich, ob ein zusätzlicher Timer-Thread irgendwie einen großen Einfluss hat, aber ich würde der Einfachkeit halber die GTK-Bordmittel nutzen.
Prinzipiell kann man das auch recht leicht als Klasse realisieren - dann hat man die Instanzvariable und die Callback-Funktion von timeout_add() nicht in seiner Haupt-GUI-Klasse rumfliegen. Außerdem ist das ja echt eine Sache, die man immer wieder mal braucht.
Besten Gruß,
brb
Code: Alles auswählen
import gtk
import gobject
class PulseBar(gtk.ProgressBar):
def __init__(self, interval=120):
gtk.ProgressBar.__init__(self)
self.interval = interval
self._pulsing = False
def switch_pulsing(self):
if self._pulsing:
self.stop_pulsing()
else:
self.start_pulsing()
def start_pulsing(self):
self._pulsing = True
gobject.timeout_add(self.interval, self.do_pulse)
def do_pulse(self):
self.pulse()
return self._pulsing
def stop_pulsing(self):
self._pulsing = False
Code: Alles auswählen
window = gtk.Window()
vbox = gtk.VBox()
window.add(vbox)
pulsebar = PulseBar()
vbox.pack_start(pulsebar)
btn = gtk.Button("Start/Stop")
pulsebar.set_text("hallo")
pulsebar.set_pulse_step(0.2)
btn.connect("clicked", lambda widget: pulsebar.switch_pulsing())
vbox.pack_start(btn)
window.show_all()
gtk.main()
brb
-
- User
- Beiträge: 996
- Registriert: Mittwoch 9. Januar 2008, 13:48
``stop_pulsing`` würde man dann eher so implementieren, dass der Timer (``timeout_add``) beendet wird (``timeout_add`` gibt eine ID zurück).
Ja, stimmt, habe auch erst überlegt, das mit source_remove() zu machen. Das hat zudem den Vorteil, das tatsächlich sofort beendet wird und nicht - wie bei mir jetzt - noch ein weiterer Puls durchlaufen wird. Fand es jetzt aber auch nicht so dramatisch. Zudem bräuchte man für die Timeout-ID ebenfalls eine Instanzvariable, so dass ich jetzt nicht den Eindruck hatte, dass das eine sonderlich "besser" ist. Letztlich habe ich die jetzige Variante aber nur aus "Gewohnheit" so gemacht, so dass dein Einwand durchaus willkommen ist
Besten Gruß,
brb
Besten Gruß,
brb