Probleme mit gobject.timeout_add()

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
Buzztardo
User
Beiträge: 2
Registriert: Donnerstag 28. Januar 2010, 22:02

Hallo erstmal,

ich versuche Gerade eine Digitaluhr in PyGtk zu implementieren.
Die einzelnen Zahlen habe ich als Gif`s vorliegen. Jede Sekunde gleicht die Funktion changeClock() die Uhrzeit mit einer externen Klasse ab und sollte dann auch die Zeitanzeige ändern.

Nur irgendwas mache ich bei der Anwendung von gobkect.timeout falsch und der Intervall wird einfach nicht wiederholt.

Hier mal der Code von der Klasse:

Code: Alles auswählen

import pygtk
pygtk.require("2.0")
import gtk,os, gobject
import filechooser
import player 
from clock import Clock

        
class Mainframe():
    
    isplaying = False
       
    def __init__(self):

        self.mainloop = gobject.MainLoop()

        
        ## Erzeugen des Window-Objectes und verbinden der Signalslots
        self.builder = gtk.Builder()
        self.builder.add_from_file("GUI.glade")
        
        self.builder.connect_signals({ "on_window1_destroy" : self.delete_event,
            "on_Cancel_clicked" : self.delete_event,
            "on_open_clicked" : self.openFile,
            "on_play_clicked" : self.play})
        self.window = self.builder.get_object("window1")
        # Wenn der Bildwechsler anläuft sehe ich nichts vom Fenster
        self.window.show()
        
        ## Erzeugen der Bildobjekte um sie ändern zu können         
        self.h1 = self.builder.get_object("H1")
        self.h2 = self.builder.get_object("H2")
        self.m1 = self.builder.get_object("M1")
        self.m2 = self.builder.get_object("M2")
        self.s1 = self.builder.get_object("S1")
        self.s2 = self.builder.get_object("S2")
        
        ## Hier wird die Schleifenfunktion zum mainloop hinzugefügt
        ##  ..sollte zumindest

        gobject.timeout_add(1000, self.changeClock) 
  

    def delete_event(self, widget):
        self.player.stop()
        print "shut Player down"
        return False
        
        
    def openFile(self, widget):
        self.chooser = filechooser.FileChooser()
        self.somefile = self.chooser.getFilename()
        
     
    def play(self, widget):
        if self.isplaying == False:
            self.isplaying = True
            self.player.play_uri(self.somefile)  
        else:
            self.player.stop()
            self.isplaying = False

    def changeClock(self):
      
        self.clock = Clock()
        self.clockrunner = [     ("%H", 0) ,  ("%H", 1) , 
                                            ("%M", 0) , ("%M", 1) , 
                                            ("%S", 0) ,  ("%S", 1)           ]
                            
        self.clocksave = [ 2 , 2 , 2 , 2 , 2 , 2]
    
        for i in range (len(self.clockrunner)):
            print self.clockrunner[i]
            self.clocksave[i] = self.clock.getTime_formated(self.clockrunner[i][0] , self.clockrunner[i][1]  )
            print self.clocksave
            
        pictures = ["0.gif","1.gif","2.gif","3.gif","4.gif","5.gif","6.gif","7.gif","8.gif","9.gif",]
        picture_objects = [self.h1, self.h2, self.m1, self.m2, self.s1, self.s2]
            
        for i in range ( len(picture_objects) ):
            picture_objects[i].set_from_file(pictures[int(self.clocksave[i])]) 



def main():
    frame = Mainframe()
    gtk.main()
    return 0

if __name__ == '__main__': main()
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Die Callback-Funktion muss einen wahren Wert zurückgeben, damit sie erneut aufgerufen wird.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Einige Verbesserungsvorschläge hätte ich für dich auch noch:

- "Mainframe" sollte von "object" erben.
- "isplaying" gehört zu einem Exemplar und nicht zur Klasse. Verschiebe also Zeile 12 in die __init__-Methode
- Wenn du Namen durchnummerierst, dann machst du etwas falsch. Warum stehen h1, h2, m1, m2, s1 und s2 nicht in einem Tupel? In Zeile 79 machst du eh eine liste daraus.
- Statt "if self.isplaying == False:" benutze besser "if not self.isplaying:"

Code: Alles auswählen

    def play(self, widget):
        if not self.is_playing:
            self.player.play_uri(self.somefile) 
        else:
            self.player.stop()

        self.is_playing = not self.isplaying
- Warum wird in Zeile 66 "clock" an das Exemplar gebunden? Es ist einfach nur ein lokaler Name. Selbiges bei "clockrunner" und "clocksave".
- Zeilen 67 bis 69 sind wirklich sehr dubios...
- Zeile 71 kann man auch als "self.clocksave = [2] * 6" schreiben. Sie ist aber vollkommen überflüssig. Du musst vorher keinen Speicher reservieren. Lege eine leere Liste an und füge Elemente hinzu oder benutze eine List Comprehension.
- Zeilen 71 bis 76 lassen sicheinfach ersetzen duch:

Code: Alles auswählen

clocksave = [clock.getTime_formated(*runner) for runner in clockrunner)]
- In Python kann man direkt über Elemente iterieren, mach sollte nicht den Umweg über Indizes nehmen. Wenn man die doch mal braucht, dann kann man die enumerate-Funktion benutzen:

Code: Alles auswählen

for runner in clockrunner:
    print runner
- "pictures" aus Zeile 78 solltest du als Konstante auslagern. Da zu erwarten ist, dass sich die Namen der Bilder nicht ändern, kannst du die Liste aber auch dynamisch erzeugen.
- Zeilen 78 bis 81 mal zusammengefasst:

Code: Alles auswählen

for picture_object in picture_objects:
    picture_object.set_from_file("%d.gif" % int(clocksave[i]))
    #oder picture_object.set_from_file("%s.gif" % clocksave[i]) ?
Wie schon ober erwähnt, solltest du picture_objects als Attribut des Exemplars speichern, damit du dir die durchnummerierten Namen sparst.
- Zeile 89 kannst du auch einsparen
- Ein Blick in PEP 8, besonders bezüglich Funktions- und Methoden-Namen, bietet sich auch noch an
- Englische Namen und deutsche Kommentare vermischt sehen etwas wirr aus. Am besten ist, wenn du dich für eine Sprache entscheidest.

Bis dann,
Sebastian
Das Leben ist wie ein Tennisball.
Buzztardo
User
Beiträge: 2
Registriert: Donnerstag 28. Januar 2010, 22:02

Ohh danke das ging ja schnell!

@Trundle: Das wars! ich habe einfach ein

Code: Alles auswählen

 return True 
angehängt jetzt geht es. :)

@EyDu: Danke für die vielen Tips und Verbesserungsvorschläge, werde sie gleich umsetzen.

Also danke nochmal

greetz B.
Antworten