Hi
Ich habe folgendes Problem:
Ich hab zwei .py Dateien. In der einen die Klasse Main und in der anderen die Klasse Thread. Die Klasse Thread importiere ich mit 'from Thread import Thread' in die Klasse Main.
In Main habe ich einen Button der in Thread eine Funktion startet. Durch zb: self.test=Thread(self)
self.test.start()
Nun möchte ich dass wenn meine Funktion in der Klasse Thread durchlaufen ist die Eigenschaft des Buttons Label, der in meiner KlasseMain steht, ändern.
Ist es nicht möglich aus der Klasse Thread eine Funktion in der Klasse Main aufzurufen???? Wenn ich sowas wie oben in die Klasse Thread schreibe kennt er immer meine Klasse Main nicht. Arrrr.
Wahrscheinlch hab ich das mit Ober und Unterklassen noch nicht ganz verstanden
Hoffe es kann mir jemand Helfen. Danke!
Funktion in ÜberKlasse aufrufen
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo HarryPython!
2.) Warum teilst du dein Programm in mehrere Dateien auf? Funktioniert eines der Module auch ohne das andere Modul? Wenn nicht, dann verkompliziert eine Aufteilung dein Programm unnötig.
Unter wxPython wird diese Trennung z.B. mit wxPython-Events umgangen. Z.B. über die Funktion ``wx.CallAfter()``
mfg
Gerold
1.) Das sind sehr unglücklich gewählte Namen. Sie sagen nichts aus.HarryPython hat geschrieben:Ich hab zwei .py Dateien. In der einen die Klasse Main und in der anderen die Klasse Thread.
2.) Warum teilst du dein Programm in mehrere Dateien auf? Funktioniert eines der Module auch ohne das andere Modul? Wenn nicht, dann verkompliziert eine Aufteilung dein Programm unnötig.
Du hast uns nicht gesagt, mit welchem Toolkit du deinen Button erstellt hast. Für Tkinter, wxPython und Co. gibt es eigene Unterforen.HarryPython hat geschrieben:In Main habe ich einen Button der in Thread eine Funktion startet. Durch zb:Nun möchte ich dass wenn meine Funktion in der Klasse Thread durchlaufen ist die Eigenschaft des Buttons Label, der in meiner KlasseMain steht, ändern.Code: Alles auswählen
self.test=Thread(self) self.test.start()
Nein, von einem Thread aus, **direkt** eine Funktion in einem anderen Thread (auch das Hauptprogramm läuft in einem Thread) aufzurufen, geht nicht.HarryPython hat geschrieben:Ist es nicht möglich aus der Klasse Thread eine Funktion in der Klasse Main aufzurufen???? Wenn ich sowas wie oben in die Klasse Thread schreibe kennt er immer meine Klasse Main nicht.
Unter wxPython wird diese Trennung z.B. mit wxPython-Events umgangen. Z.B. über die Funktion ``wx.CallAfter()``
mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
-
- User
- Beiträge: 60
- Registriert: Freitag 8. Juni 2007, 07:39
Hi Gerold.
Erstmal Danke für die schnelle Antwort. Echt klasse dieses Forum. Hatte nur ein Paar Probleme mit dem Anmelden. Als ich all meine Daten eingegeben hab kam eine Fehlermeldung danach konnte ich mich nicht nochmal anmelden, da die E-Mail Adresse schon regestriert ist. Mit der 3.Mail hat es dann geklappt. Vielleicht weißt du ja bereits wovon ich rede. Aber jetzt ist er drin. Jupi.
zum Thema:
Hab sie nur hier Main und Thread genannt zum leichteren Verständniss.
Warum aufteilen ist eine gute Frage. Als ich noch nicht wußte wie man Threads erstellt hab ich so mein Problem gelöst.
Ich arbeite mit wx.
mfg Harry
Erstmal Danke für die schnelle Antwort. Echt klasse dieses Forum. Hatte nur ein Paar Probleme mit dem Anmelden. Als ich all meine Daten eingegeben hab kam eine Fehlermeldung danach konnte ich mich nicht nochmal anmelden, da die E-Mail Adresse schon regestriert ist. Mit der 3.Mail hat es dann geklappt. Vielleicht weißt du ja bereits wovon ich rede. Aber jetzt ist er drin. Jupi.
zum Thema:
Hab sie nur hier Main und Thread genannt zum leichteren Verständniss.
Warum aufteilen ist eine gute Frage. Als ich noch nicht wußte wie man Threads erstellt hab ich so mein Problem gelöst.
Ich arbeite mit wx.
Aber ich starte ja auch aus Main mit start() meine Funktion run() in Thread. Oder ist das die einziege Ausnahme?Nein, von einem Thread aus, **direkt** eine Funktion in einem anderen Thread (auch das Hauptprogramm läuft in einem Thread) aufzurufen, geht nicht.
mfg Harry
Du startest mit `start()` einen neuen Thread und *der* ruft dann die `run()`-Methode auf. Das ist in der Tat eine Ausnahme weil die `start()`-Methode etwas sehr "magisches" tut: einen neuen Thread starten und sofort zum Aufrufer zurückkehren.
-
- User
- Beiträge: 60
- Registriert: Freitag 8. Juni 2007, 07:39
Hilfe!!!!
Sitze jetzt seit drei Tagen an dem Problem und dreh langsam durch.
Ich hab die beiden Klassen zusammengefügt.
Hab es auch schon geschafft aus meinem Thread eine Funktion in Main aufzurufen. Irgendwelche print Anweisungen in dieser Funktion klappen aber sobald ich sage er soll das Label von meinem Button ändern ignoriert er das einfach. Gibt nicht mal ein Fehler.
wx.CallAfter liefert eine Fehlermeldung "NoneType Objekt not callable" führt dann aber dennoch die Funktion aus aber auch nur so als würde ich sie direkt aufrufen.
Ich möchte doch nur bei meinem Button in der Klasse Main das Label wieder auf "Start" setzen wenn der Tread zuende ist!!!!!!!!!!!!!!!!!
Damit der User sieht er kann den Thread wieder starten.
HILFE wo sind die Programmierer????
Sitze jetzt seit drei Tagen an dem Problem und dreh langsam durch.
Ich hab die beiden Klassen zusammengefügt.
Hab es auch schon geschafft aus meinem Thread eine Funktion in Main aufzurufen. Irgendwelche print Anweisungen in dieser Funktion klappen aber sobald ich sage er soll das Label von meinem Button ändern ignoriert er das einfach. Gibt nicht mal ein Fehler.
wx.CallAfter liefert eine Fehlermeldung "NoneType Objekt not callable" führt dann aber dennoch die Funktion aus aber auch nur so als würde ich sie direkt aufrufen.
Ich möchte doch nur bei meinem Button in der Klasse Main das Label wieder auf "Start" setzen wenn der Tread zuende ist!!!!!!!!!!!!!!!!!
Damit der User sieht er kann den Thread wieder starten.
HILFE wo sind die Programmierer????
- Sr4l
- User
- Beiträge: 1091
- Registriert: Donnerstag 28. Dezember 2006, 20:02
- Wohnort: Kassel
- Kontaktdaten:
Du könntest mal dein Code posten bei: http://paste.pocoo.org/ und uns den Link sagen.
dann kann ich den Wikieintrag mit einem sehr großen Beispiel empfehlen [wiki]Threading Beispiel1[/wiki] wobei ich es etwas zu lang finde,
Das war der kürzeste Code zum Modul Thread den ich auf meiner Festplatte noch gefunden habe, ich bitte um Verzeihung der nicht PEP8 konformen Schreibweise
Wegen deinem Button Problem: Wenn keine Fehlermeldung kommt gibt es keine Fehler, ohne Code schwierig zusagen was da nicht geht.
dann kann ich den Wikieintrag mit einem sehr großen Beispiel empfehlen [wiki]Threading Beispiel1[/wiki] wobei ich es etwas zu lang finde,
Code: Alles auswählen
#! /usr/bin/env python
#-*- coding: latin-1 -*-
#
import socket,time,thread
def Server(byte,host,port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Socket defenieren
sock.bind((host, port)) #server auf localhost, Port 12345 laufen lassen
sock.listen(1) #Server maximal 1 Client akzeptieren lassen
conn, addr = sock.accept()
while True:
#print addr," ",data
print "<<<: %s"%(conn.recv(byte))
conn.close()
def Run():
host = "localhost" #Hostname
port = 12345 #Verbindungs Port
byte = 1024 #Byte Groesse
#
thread.start_new_thread(Server, (byte,host,port)) #Lässt Server() im Hintergrundlaufen
while True:
print "Der Server blockt mich nicht dank dem Thread."
time.sleep(2) #Nur damit wir keine 100% CPU Auslastung haben
Run()
Wegen deinem Button Problem: Wenn keine Fehlermeldung kommt gibt es keine Fehler, ohne Code schwierig zusagen was da nicht geht.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo HarryPython!HarryPython hat geschrieben:Ich möchte doch nur bei meinem Button in der Klasse Main das Label wieder auf "Start" setzen wenn der Tread zuende ist!
Nicht so kompliziert, aber mit weniger Möglichkeiten:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import wx
import thread
import time
wx.SetDefaultPyEncoding("iso-8859-15")
class MyFrame(wx.Frame):
def __init__(
self, parent = None, id = -1, title = "Example", size = wx.Size(200, 150)
):
wx.Frame.__init__(self, parent, id, title, size = size)
self.panel = wx.Panel(self)
vbox_main = wx.BoxSizer(wx.VERTICAL)
self.panel.SetSizer(vbox_main)
vbox_main.AddStretchSpacer()
self.btn_start = wx.Button(self.panel, label = "Start")
vbox_main.Add(self.btn_start, 0, wx.ALL | wx.ALIGN_CENTER)
self.btn_start.Bind(wx.EVT_BUTTON, self.start_worker)
vbox_main.AddStretchSpacer()
self.panel.Layout()
def start_worker(self, event = None):
self.btn_start.SetLabel("working...")
self.btn_start.Disable()
self.panel.Layout()
wx.SafeYield()
thread.start_new_thread(self.worker, ())
def worker(self):
for i in xrange(5):
print "Ich arbeite..."
time.sleep(1)
# Fertig
wx.CallAfter(self.btn_start.SetLabel, "Start")
wx.CallAfter(self.btn_start.Enable)
wx.CallAfter(self.panel.Layout)
wx.SafeYield()
def main():
"""Testing"""
app = wx.PySimpleApp()
f = MyFrame()
f.Center()
f.Show()
app.MainLoop()
if __name__ == "__main__":
main()
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import wx
import time
import threading
wx.SetDefaultPyEncoding("iso-8859-15")
class MyWorker(threading.Thread):
def __init__(self, finished_function = None):
threading.Thread.__init__(self)
self.canceled = threading.Event()
self.finished_function = finished_function
def run(self):
for i in xrange(10):
if self.canceled.isSet():
print "Gestoppt..."
break
print "Ich arbeite..."
time.sleep(1)
if self.finished_function:
self.finished_function()
def stop(self):
self.canceled.set()
class MyFrame(wx.Frame):
def __init__(
self, parent = None, id = -1, title = "Example", size = wx.Size(200, 150)
):
wx.Frame.__init__(self, parent, id, title, size = size)
self.worker = None
self.panel = wx.Panel(self)
vbox_main = wx.BoxSizer(wx.VERTICAL)
self.panel.SetSizer(vbox_main)
vbox_main.AddStretchSpacer()
self.btn_start = wx.Button(self.panel, label = "Start")
vbox_main.Add(self.btn_start, 0, wx.ALL | wx.ALIGN_CENTER)
self.btn_start.Bind(wx.EVT_BUTTON, self.start_worker)
self.btn_cancel = wx.Button(self.panel, label = "Abbruch")
self.btn_cancel.Disable()
vbox_main.Add(self.btn_cancel, 0, wx.ALL | wx.ALIGN_CENTER)
self.btn_cancel.Bind(wx.EVT_BUTTON, self.cancel_worker)
vbox_main.AddStretchSpacer()
self.panel.Layout()
def start_worker(self, event = None):
self.btn_start.SetLabel("working...")
self.btn_start.Disable()
self.btn_cancel.Enable()
self.panel.Layout()
wx.SafeYield()
self.worker = MyWorker(self.worker_finished)
self.worker.start()
def cancel_worker(self, event = None):
self.worker.stop()
def worker_finished(self):
wx.CallAfter(self.btn_start.SetLabel, "Start")
wx.CallAfter(self.btn_start.Enable)
wx.CallAfter(self.btn_cancel.Disable)
wx.CallAfter(self.panel.Layout)
wx.SafeYield()
def main():
"""Testing"""
app = wx.PySimpleApp()
f = MyFrame()
f.Center()
f.Show()
app.MainLoop()
if __name__ == "__main__":
main()
Gerold
PS: Schon spät... wenig Kommentare!
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
-
- User
- Beiträge: 60
- Registriert: Freitag 8. Juni 2007, 07:39
Ahhhhhhhhhhhhhhhhhhhhhhhhhh.
Genau das hab ich gesucht!!!!!!!!!!!!!
Danke Meister Gerold!!!!!!!!!!!!!!
Die ganze Funktion an den Thread übergeben. Na klar.
Cool. Danke nochmal. Jetzt kann ich weiter machen.
mfg Padawan HarryPython
Genau das hab ich gesucht!!!!!!!!!!!!!
Danke Meister Gerold!!!!!!!!!!!!!!
Die ganze Funktion an den Thread übergeben. Na klar.
Cool. Danke nochmal. Jetzt kann ich weiter machen.
mfg Padawan HarryPython