Wertübergabe zwischen zwei Threeds

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
da3m0n

Hi,
Ich brauche eine Uhr die langsam hoch zählt (Zeit die ein Lied spielt), bis zu einem bestimmten Zeitpunkt wo halt das lied auf hört.
Ich habe erst einmal angefangen einen Zähler zu bauen der bis zehn zählt und dann fertig ist.
Jetzt möchte ich einfügen, dass wenn ich auf pause drücke das zählen anzuhalten.
Meine idee war es die uhr in einem eigenen Thread laufen zu lassen und in dem anderen thread ab zu fragen ob Pause gedrückt wird.
Um zu gucken ob das so funktioniert habe ich ersteinmal gesagt das er pause ausgeben soll wenn die taste gedrückt wird, jetzt scheint der andere threed die wertänderung aber nicht zu übernehmen.
Ich hoffe ihr versteht was ich meine, hier einmal der code zur verdeutlichung:

Code: Alles auswählen

import sys
from Tkinter import *
from time import *
from thread import *
i = 0
paus = 0

def Uhr():
    paus = 0 
    for i in range(0,10,1):
        if paus == 1:
            print "pause"
        lb["text"] = i
        sleep(1)

def ende():
    sys.exit(0)

def play():
    start_new_thread(Uhr,())

def pause():
    paus = 1
    
hauptfenster = Tk()
lb = Label(hauptfenster, text = "0")
lb.pack()
bw = Button (hauptfenster,text = "play", command = play)
bw.pack()
bp = Button (hauptfenster,text = "Pause", command = pause)
bp.pack()
b = Button(hauptfenster,text = "Ende", command = ende)
b.pack()
hauptfenster.mainloop()
Muss ich den wert irgentwie an den Threed übergeben?!?
Währe nett wenn ihr mir helfen könntet.

mfg da3m0n

ps: gibt es einen Befehl mit dem ich einen einzelnen Threed beenden kann ?

Edit (Leonidas): Code in Python-Tags gesetzt.
BlackJack

Dein Problem ist, das die `paus` in den Funktionen andere sind als das `paus` im Modul. Wenn Du in einer Funktion einen Wert an einen Namen bindest, dann erzeugst Du damit eine *lokale* Variable die nur innerhalb der Funktion sichtbar ist.

Du brauchst entweder das Schlüsselwort ``global`` um in den Funktionen zu deklarieren das die Variable auf Modulebene benutzt werden soll, oder Du solltest Klassen benutzen. Letzteres ist eindeutig besserer Stil, weil globale Variablen *böse* sind!

Noch zwei Anmerkungen: Wenn man alles mit `*` importiert müllt man sich den Namensraum zu, das kann zu netten Problemen führen. Und das Modul `threading` bietet ein paar Funktionen auf "höherem Niveau" als das `thread` Modul.
Gast

Danke

Mit global funktioniert es schon einmal, ich versuchs jetzt mal mit classen
(nebenbei muss ich dann für den vergleich der classe def _cmp_ nehmen?).

Danke für die zwei hinweise, ich habe aber noch ein paar fragen dazu:

Bei so wenigen modulen wie ich benutze lohnt es sich warscheinlich jedes einzeln zu laden, aber wie seiht das aus wenn ich nachher bei größeren Programmen wesentlich mehr module brauche, ist das dann immer noch sinnvoll ?

Welche Funktion auf "höherem Niveau" meinst du, die für mein programm sinnvoll ist?

Und zu guter letzt, gibt es einen Befehl zum beenden eines einzelnen threeds ?
(Bitte nicht aufregen das ich die suchfunktion noch nicht benutzt habe, aber ich dachte so gehts vieleicht einfacher und schneller wenn ich das an meine anderen Fragen dran hänge)

thx noch mal für die Hilfe

gruß da3m0n
BlackJack

Anonymous hat geschrieben:Danke

Mit global funktioniert es schon einmal, ich versuchs jetzt mal mit classen
(nebenbei muss ich dann für den vergleich der classe def _cmp_ nehmen?).
Welchen Vergleich?
Danke für die zwei hinweise, ich habe aber noch ein paar fragen dazu:

Bei so wenigen modulen wie ich benutze lohnt es sich warscheinlich jedes einzeln zu laden, aber wie seiht das aus wenn ich nachher bei größeren Programmen wesentlich mehr module brauche, ist das dann immer noch sinnvoll ?
Ja klar. Je mehr Module man mit `*` importiert, um so grösser werden doch die Probleme die dadurch entstehen können. Ausserdem wirst Du nie besonders viele Module importieren. Wenn ein Programm grösser wird, dann teilt man es ja selbst in Module auf.
Welche Funktion auf "höherem Niveau" meinst du, die für mein programm sinnvoll ist?
Na zum Beispiel das bei den `threading` Threads der Haupt-Thread am Ende automatisch darauf wartet das alle gestarteten Threads beendet sind. Und speziell für Deinen Fall könnte das `Event` Objekt interessant sein.
Und zu guter letzt, gibt es einen Befehl zum beenden eines einzelnen threeds ?
Nein.
BlackJack

Hier ist ein kleines Beispiel mit dem `threading` Modul:

Code: Alles auswählen

from time import sleep
from threading import Thread, Event


class NoiseMaker(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.running = Event()
        self.stop_request = False
    
    def run(self):
        print 'run'
        self.stop_request = False
        self.running.set()
        while not self.stop_request:
            self.running.wait()
            print 'dudeldidum'
            sleep(1)
        print 'stopped'
    
    def toggle_pause(self):
        print 'toggle pause'
        if self.running.isSet():
            self.running.clear()
        else:
            self.running.set()

    def stop(self):
        self.stop_request = True


noise_maker = NoiseMaker()

for method_name in ('start', 'toggle_pause', 'toggle_pause', 'stop'):
    getattr(noise_maker, method_name)()
    sleep(3)
da3m0n

hi
ich weiß das das komisch ist, aber ich habe in der schule bisher nur prozedurales Programmieren gelernt und noch nicht so viel mit oop zutun gehabt, deshalb schreibe ich nicht objekt orientiert, auch wenns zu python nicht passt. ^^ Nur damit ihr euch nicht wundern.

Ich habe jetzt noch eine Frage zur sprache, ich will an eine prozedur die durch einen button aufgerufen wird eine Liste übergeben.

Code: Alles auswählen

bw = Button (hauptfenster,text = "play", command = play(Playlist))

Das klappt auch, nur wenn ich das programm jetzt starte wird die Funktion aufgerufen ohne das darauf gewartet wird das der Button gedrückt wird?!?

Habe ich eine falsche sorte von Button ausgwählt oder ein Fehler bei der Übergabe gemacht ???

gruß da3m0n

ps: danke BlackJack für das Programm, aber ich muss erst gucken das ich das Programm zum laufen bekomme, dann gucke ich mir mal oop genauer an und versuche dein Programm zu verstehen.
snakeseven
User
Beiträge: 408
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Code: Alles auswählen

bw = Button (hauptfenster,text = "play", command = play(Playlist))

Ich weiss, der Thread ist alt, aber falls sich einer hierhin verirrt:
Es muss 'command = play' heißen. Wenn du der Funktion play() in der Button Initialisierung einen Parameter übergibst, dann wird sie offensichtlich aufgerufen und ausgeführt. Hatte dasselbe Problem.
Antworten