Countdown-Skript ohne sleep()

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
scrawl
User
Beiträge: 40
Registriert: Mittwoch 20. August 2008, 17:04
Kontaktdaten:

Countdown-Skript ohne sleep()

Beitragvon scrawl » Mittwoch 20. August 2008, 17:09

Hi,

ich würde in mein Programm gerne eine Countdown-Funktion integrieren, also dass ab einer bestimmten Zahl runtergezählt wird bis 0. Habe bisher aber nur Lösungen gefunden die time.sleep() benutzen, was dann dazu führt, dass die GUI sich aufhängt.
Weiß da jemand ne Lösung? Wäre euch sehr dankbar.

MfG scrawl
Benutzeravatar
Hyperion
Moderator
Beiträge: 7471
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Beitragvon Hyperion » Mittwoch 20. August 2008, 17:17

Threads! ([wiki]Threading Beispiel1)[/wiki]
scrawl
User
Beiträge: 40
Registriert: Mittwoch 20. August 2008, 17:04
Kontaktdaten:

Beitragvon scrawl » Mittwoch 20. August 2008, 17:21

Puh, ist das kompliziert. Da gehts ja mit Javascript noch einfacher.
Hat niemand zufällig nen fertiges Script für mich? :?
epsilon
User
Beiträge: 71
Registriert: Freitag 20. Juni 2008, 19:48

Beitragvon epsilon » Mittwoch 20. August 2008, 17:57

Soll die verbleibende Zeit angezeigt werden oder soll nur eine bestimmte Funktion ausgeführt werden, wenn die Zeit vorbei ist.

Bei Letzterem dürfte Timer nützlich sein.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Mittwoch 20. August 2008, 18:13

scrawl hat geschrieben:Da gehts ja mit Javascript noch einfacher.

Natürlich geht es einfacher, da der Browser den Interpreter in einem eigenen Thread hat und man Callbacks nach bestimmeter Zeit aufrufen kann.

In PyGTK ist soetwas auch einfach möglich, man nutzt einfach ``gobject.timeout_add()``, welches eine Funktion alle n Millisekunden aufruft ohne dass die GUI blockiert.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
scrawl
User
Beiträge: 40
Registriert: Mittwoch 20. August 2008, 17:04
Kontaktdaten:

Beitragvon scrawl » Mittwoch 20. August 2008, 18:19

@epsilon: Ersteres, leider.
@Leonidas: Danke, ich guck mir das mal an.
epsilon
User
Beiträge: 71
Registriert: Freitag 20. Juni 2008, 19:48

Beitragvon epsilon » Mittwoch 20. August 2008, 18:23

@epsilon: Ersteres, leider.


Ach so.

Welches GUI toolkit verwendest du überhaupt? 'ne timer Funktion wird es doch wohl überall geben.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Beitragvon Trundle » Mittwoch 20. August 2008, 19:07

@Hyperion: Threads sind nicht unbedingt immer die Universalantwort. Ich denke mal, dass dafür jedes Toolkit eine Funktion zur Verfügung stellt. Für PyGtk hat die Leonidas schon genannt, für wxPython ist es wohl `wx.CallLater` und alle anderen Toolkits dürften das wohl auch haben.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
scrawl
User
Beiträge: 40
Registriert: Mittwoch 20. August 2008, 17:04
Kontaktdaten:

Beitragvon scrawl » Mittwoch 20. August 2008, 19:11

@epsilon: Benutze PyGTK

@Leonidas: Danke, so funktionierts jetzt, bist mein Held :D
scrawl
User
Beiträge: 40
Registriert: Mittwoch 20. August 2008, 17:04
Kontaktdaten:

Beitragvon scrawl » Mittwoch 20. August 2008, 19:16

Hier mal mein Programm falls es noch wen interessiert (eines meiner ersten, nicht meckern^^)

Code: Alles auswählen

#!/usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk
import gobject
import time

class Lukas:
   time = 20
   clicks = 0
   
   def close_window(self, widget, event, data=None):
      gtk.main_quit()
      return False
      
   def increase_clicks(self, widget, event, data=None):
      self.clicks = self.clicks + 1
      self.str_clicks = str(self.clicks)
      self.score_display.set_text(self.str_clicks + ' Klicks')
      
   def countdown_time(self):
      self.time = self.time - 1
      self.str_time = str(self.time)
      print self.str_time
      self.time_display.set_text('Noch ' + self.str_time + ' Sekunden')
      if self.time == 0: # if time is up
         self.click_button.disconnect(self.clicker) # stop click count
         self.notify = gtk.Dialog('Zeit vorbei!')
         self.pointlabel = gtk.Label('Deine Punktzahl: ' + str(self.clicks))
         self.pointlabel.show()
         self.notify.add_action_widget(self.pointlabel, 1)
         self.notify.add_button('Nochmal', 2)
         self.notify.add_button('Beenden', 3)
         signal = self.notify.run()
         print signal
         if signal == 2: # restart
            self.restart_game()
            return False
         if signal == 3: # quit
            gtk.main_quit()
            return False
         return False
      return True
      
   def restart_game(self):
      print "Restarting"
      self.time = 20
      self.clicks = 0
      self.clicker = self.click_button.connect("clicked", self.increase_clicks, None)
      self.timer = self.click_button.connect("clicked", self.start_timer, None)
      self.score_display.set_text('0 Klicks')
      self.time_display.set_text('Noch 20 Sekunden')
      
   def start_timer(self, widget, event, data=None):
      print "Starting timer"
      gobject.timeout_add(1000, self.countdown_time)
      self.click_button.disconnect(self.timer)
   
   def __init__(self):
      self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
      self.window.set_title('Klick den Lukas')
      self.window.set_border_width(5)
      self.window.resize(300, 200)
      
      self.content_box = gtk.VBox(False, 0)
      self.click_button = gtk.Button('Klick mich')
      self.score_display = gtk.Label('0 Klicks')
      self.time_display = gtk.Label('Noch 20 Sekunden')
      
      self.content_box.pack_start(self.click_button, True, True, 0)
      self.content_box.pack_start(self.score_display, True, True, 0)
      self.content_box.pack_start(self.time_display, True, True, 0)
      
      self.window.add(self.content_box)
      
      self.window.connect("delete_event", self.close_window)
      self.clicker = self.click_button.connect("clicked", self.increase_clicks, None)
      self.timer = self.click_button.connect("clicked", self.start_timer, None)
      
      self.click_button.show()
      self.score_display.show()
      self.time_display.show()
      self.content_box.show()
      self.window.show()
      
def main():
   gtk.main()

if __name__ == '__main__':
   app = Lukas()
   main()



Nur eine Sache will noch nicht, nämlich wenn man auf 'Nochmal' klickt soll der auch den Dialog schließen. Weiß jemand wie das geht? In der Referenz hab ich nichts brauchbares gefunden.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Mittwoch 20. August 2008, 19:28

Der Dialog müsste mit ``self.notify.destroy()`` verschwinden.

Achja, ich habe den Thread nun in das GTK-Forum verschoben.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
lunar

Beitragvon lunar » Mittwoch 20. August 2008, 19:32

Eine Alternative für Linux wäre noch "signal.alarm()" in Verbindung mit einem Handler für SIGALRM.
scrawl
User
Beiträge: 40
Registriert: Mittwoch 20. August 2008, 17:04
Kontaktdaten:

Beitragvon scrawl » Mittwoch 20. August 2008, 19:33

Danke, funktioniert :D
Super Support hier

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder