Merci.... werde mri da sspäter mal genauer ansehen
Noch eine Frage (weiss ich habe viele ^^)
Ich habe ein frame welches beim start des Backups geladen wird.
Ich setzte in das (der die???) TextCtrl während des Backups weitere Zeilen rein und aktualisiere die Gauge.
Nur wenn jemand auf die Idee kommt das Fenster zu wechseln oder das Fenster zu verschieben / vergrössern bleibt der Inhalt für immer weiss
Sehr unpraktisch bei langen Backups...
vorher...
nachher ...
Frame bleibt bei Fensterwechsel weiß
- DatenMetzgerX
- User
- Beiträge: 398
- Registriert: Freitag 28. April 2006, 06:28
- Wohnort: Zürich Seebach (CH)
- DatenMetzgerX
- User
- Beiträge: 398
- Registriert: Freitag 28. April 2006, 06:28
- Wohnort: Zürich Seebach (CH)
Code: Alles auswählen
def Copy(strDatei,strDateiroh, strZiel, Log, frame, counter=0):
#Nur os.sep + Ordner /Dateiname bleibt zurueck
strDatei = string.replace(strDatei,strDateiroh, '')
counter+=1
#frame.progress.Update(counter)
frame.progress.SetValue(counter)
if not os.path.isdir(strDateiroh + strDatei): #ueperpruefen ob es ein Verzeichnis ist
#Versuche Datei zu Kopieren, Wenn es nicht funktioniert ins Log File schreiben
try:
#print strDateiroh + strDatei
frame.SetText(strDateiroh + strDatei)
shutil.copy2(strDateiroh + strDatei, strZiel + strDatei)
#if os.system('copy "' + strDateiroh + strDatei + '" "' + strZiel + strDatei + '"') !=0:
# Log.write("\n\nDatei %s konnte nicht kopiert werden" %(strDateiroh + strDatei))
except:
try:
shutil.copy(strDateiroh + strDatei, strZiel + strDatei)
except:
Log.write("\n\nDatei %s konnte nicht gesichert werden"%(strDateiroh + strDatei))
#Bei Verzeichnis
else:
try:
ToCreate = (strZiel + strDatei) #Welches Verzeichnis angelegt werden muss
if not os.path.exists(ToCreate): #Wenn es nicht existiert neu anlegen
os.mkdir(ToCreate)
listDir = os.listdir(strDateiroh +os.sep + strDatei) #Inhalt des Verzeichnisses ausgeben
for element in listDir: #Fuer jede Datei / Element selbstaufruf
counter=Copy(strDateiroh + strDatei + os.sep + element, strDateiroh + strDatei, strZiel + strDatei, Log, frame, counter) #Selbst aufruf fuer Unterverzeichnise
except:
Log.write("\nOrdner %s konnte samt Unterverzeichnisen / Dateien nicht\ngesichert werden" %(strDatei))
return counter
Code: Alles auswählen
class Frame(wx.Frame):
def __init__(self, Files, parent="None", id=-1, title="Backup"):
wx.Frame.__init__(self, parent, id, title)
self.panel =wx.Panel(self)
Sizer = wx.FlexGridSizer(2, 0)
intFiles=0
for File in Files:
intFiles+=CountFiles(File)
#self.progress = wx.ProgressDialog("Backup", "", intFiles, None, wx.PD_AUTO_HIDE | wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME)
#__init__(self, parent, id, pos, size, style, validator, name)
self.progress=wx.Gauge(self.panel, id)
self.progress.SetRange(intFiles)
self.text = wx.TextCtrl(self.panel, -1, "", style=wx.TE_MULTILINE | wx.TE_READONLY)
Sizer.AddGrowableRow(0)
Sizer.AddGrowableRow(1)
Sizer.Add(self.progress, 0, wx.EXPAND | wx.ALL, 10)
Sizer.Add(self.text, 0, wx.EXPAND | wx.BOTTOM | wx.RIGHT | wx.LEFT, 10)
self.progress.SetMinSize((300,30))
self.text.SetMinSize((600,300))
self.panel.SetSizer(Sizer)
Sizer.Fit(self)
Sizer.SetSizeHints(self)
self.Show()
def SetText(self, text):
self.text.WriteText('\n' + text)
Code: Alles auswählen
elif intModus == 0 and strProg != 'subversion':
Log = open(strZiel + os.sep + "log.txt", "w")
Log.close
#wxPython Applikation starten
#__init__(self, parent, id, pos, size, style, name)
app = wx.PySimpleApp()
#Frame setzen
frame = BackupFunctions.Frame(Files, None, -1, "Backup")
#frame als oberstes Fenster setzen
#Kein frame.Show(), frame soll nicht angezeigt werden
app.SetTopWindow(frame)
#Dateien Sichern
for File in Files:
BackupFunctions.Copy(File,File, strZiel, Log, frame)
#Fenster schliessen
frame.Destroy()
app.MainLoop() habe ich nicht gemacht weil ich keinen Input des Benutzer möchte
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Ich habe aus deiner Frage ein neues Thema gemacht.
mfg
Gerold
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.
- DatenMetzgerX
- User
- Beiträge: 398
- Registriert: Freitag 28. April 2006, 06:28
- Wohnort: Zürich Seebach (CH)
Merciii....
Aber glaube habe die Lösung auf mein Problem... Threats auch wenn ich die nicht mag ^^
Aber glaube habe die Lösung auf mein Problem... Threats auch wenn ich die nicht mag ^^
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Du hast sicher recht. Das dürfte die einfachste Lösung sein..DatenMetzgerX hat geschrieben:Threats auch wenn ich die nicht mag ^^
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.
Evtl. reicht es auch, periodisch aufzurufen
Code: Alles auswählen
frame.Update()
- DatenMetzgerX
- User
- Beiträge: 398
- Registriert: Freitag 28. April 2006, 06:28
- Wohnort: Zürich Seebach (CH)
Habe mich mal ein wenig mit Threads herumgeschlagen ...
Was ich nicht geschafft habe ist app.MainLoop() in einem eigenen Thread laufen zu lassen
Das Fenster bleibt einfach weiss....
Das Andere Problem ist...
Eigentlich wollte ich das Frame automatisch nach dem Backup schliessen, aber wie. Über frame.Destroy() freut sich das app.MainLoop() nicht.
Deshalbt versuchte ich auch den Loop in einen eigenen Thread zu bringen dann häte ich nämlich prüfen können
Und dann hätte ich das MainLoop weg, vieleicht ein wenig brutal aber was solls, geht ja eh nicht
Jemand eine Idee
Edit:// gibts so was wie ein Statusdialog, den ich einblenden könnte während die Files gezählt werden?
Was ich nicht geschafft habe ist app.MainLoop() in einem eigenen Thread laufen zu lassen
Code: Alles auswählen
class guiThread(threading.Thread):
def __init__(self, app):
self.app = app
threading.Thread.__init__(self)
def run(self):
self.app.MainLoop()
Das Andere Problem ist...
Eigentlich wollte ich das Frame automatisch nach dem Backup schliessen, aber wie. Über frame.Destroy() freut sich das app.MainLoop() nicht.
Deshalbt versuchte ich auch den Loop in einen eigenen Thread zu bringen dann häte ich nämlich prüfen können
Code: Alles auswählen
while corethread.isAlive() or guiThread.isAlive():
if guiThread.isAlive():
guiThread.abort() #Weiss den exit /cancel Befehl gerade nicht...
if corethread.isAlive():
corethread.abort()
Jemand eine Idee
Edit:// gibts so was wie ein Statusdialog, den ich einblenden könnte während die Files gezählt werden?
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hi DatenMetzgerX!DatenMetzgerX hat geschrieben:Was ich nicht geschafft habe ist app.MainLoop() in einem eigenen Thread laufen zu lassen
Das ist sicher die falsche Weise so etwas anzugehen.
**app.mainloop()** kümmert sich um die Anzeige von Fenstern und das Abarbeiten von Events. **app** ist also ein eigener Thread.
Lass den dafür vorgesehenen Thread, also **app**, um die Anzeige kümmern und lagere die Arbeit in einen eigenen Thread aus. Allerdings musst du den arbeitenden Thread komplett unabhängig von der GUI machen. Wenn es eine neue Statusmeldung gibt, dann kann der arbeitende Thread eine Meldung an den GUI-Thread schicken. Der GUI-Thread kümmert sich dann darum, dass eine entsprechende Meldung angezeigt wird.
http://wiki.wxpython.org/index.cgi/LongRunningTasks
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.
- DatenMetzgerX
- User
- Beiträge: 398
- Registriert: Freitag 28. April 2006, 06:28
- Wohnort: Zürich Seebach (CH)
Das mit den Threads habe ich zum Teil hinbekommen. Nur wenn der Benutzer nun die Gui beendet. Wie kill ich den anderen Thread???
thread.stop(), thread.kill() und thread.cancel() ging nicht. Einen Befehl habe ich mit Googlen auch noch nicht herausgebracht
Das ganze ist z.T ein wenig ein drucheinander, weil ich am Anfang noch zu wenig mit Funktionen und Klassengearbeitet habe
Aber wie ist der Befehl um einen Thread zu killen.
thread.stop(), thread.kill() und thread.cancel() ging nicht. Einen Befehl habe ich mit Googlen auch noch nicht herausgebracht
Code: Alles auswählen
#Main
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = BackupFunctions.Frame(None, -1, "Backup")
app.SetTopWindow(frame)
Appli = CopyThread(app,frame)
frame.Bind(wx.EVT_CLOSE, Appli.abort)
Appli.start()
app.MainLoop()
Code: Alles auswählen
class CopyThread(threading.Thread):
def __init__(self, app, frame):
threading.Thread.__init__(self)
self.app = app
self.frame = frame
def run (self):
Main()
app.ExitMainLoop()
frame.Destroy()
def abort(self, event):
self.stop()
Aber wie ist der Befehl um einen Thread zu killen.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hier ein Beispiel. Nur unter Linux getestet.
mfg
Gerold
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import wx
import threading
import time
# Define notification event for thread completion
EVT_NEWMESSAGE_ID = wx.NewId()
EVT_STOP_ID = wx.NewId()
def EVT_NEWMESSAGE(win, func):
"""
Define NewMessage Event.
"""
win.Connect(-1, -1, EVT_NEWMESSAGE_ID, func)
def EVT_STOP(win, func):
"""
Define NewMessage Event.
"""
win.Connect(-1, -1, EVT_STOP_ID, func)
class NewMessageEvent(wx.PyEvent):
"""
Simple event
"""
def __init__(self, message):
"""
Init Event.
"""
wx.PyEvent.__init__(self)
self.SetEventType(EVT_NEWMESSAGE_ID)
self.message = message
class StopEvent(wx.PyEvent):
"""
Simple event
"""
def __init__(self):
"""
Init Event.
"""
wx.PyEvent.__init__(self)
self.SetEventType(EVT_STOP_ID)
class MyFrame(wx.Frame):
"""
Hauptframe
"""
def __init__(
self, parent = None, title = "Hauptframe", size = (400, 300)
):
# Frame initialisieren
wx.Frame.__init__(self, parent, -1, title)
# Ein Panel als Grundlage
panel = wx.Panel(self)
# Ein vertikaler Boxsizer zum Anordnen
vb = wx.BoxSizer(wx.VERTICAL)
panel.SetSizer(vb)
# Ein Textfeld für die Ausgabe der Statusmeldungen (read only)
self.messages = wx.TextCtrl(
panel, -1,
style = wx.TE_AUTO_SCROLL | wx.TE_LINEWRAP |
wx.TE_MULTILINE | wx.TE_READONLY
)
vb.Add(self.messages, 1, wx.ALL | wx.EXPAND, 5)
# Buttonleiste
hb = wx.BoxSizer(wx.HORIZONTAL)
vb.Add(hb, 0, wx.EXPAND)
# Start
start_btn = wx.Button(panel, -1, "Start")
hb.Add(start_btn, 1, wx.ALIGN_CENTER_HORIZONTAL| wx.ALL, 5)
start_btn.Bind(wx.EVT_BUTTON, self.start_thread)
# Stopp
stopp_btn = wx.Button(panel, -1, "Stopp")
hb.Add(stopp_btn, 1, wx.ALIGN_CENTER_HORIZONTAL| wx.ALL, 5)
stopp_btn.Bind(wx.EVT_BUTTON, self.stop_thread)
# Thread-Variablen vorbereiten
self.myworkerthread = None
self.thread_started = False
# NewMessage-Event binden
EVT_NEWMESSAGE(self, self.add_message)
# Stop-Event binden
EVT_STOP(self, self.stop_me)
def add_message(self, event = None, message = None):
"""
Fügt an den Text eine neue Zeile mit der neuen Nachricht an.
"""
if event:
message = str(event.message)
if len(self.messages.GetValue()) > 0:
message = "\n" + message
self.messages.AppendText(message)
self.messages.ScrollLines(10)
def start_thread(self, event = None):
"""
Startet den Thread
"""
# Prüfen ob der Thread schon läuft
if self.thread_started:
self.add_message(message = u"Der Thread läuft bereits...")
return
# Thread initialisieren
self.myworkerthread = MyWorkerThread(self)
# Thread starten
self.myworkerthread.start()
# Variable setzen und Nachricht ausgeben
self.thread_started = True
self.add_message(message = u"Der Thread wurde soeben gestartet...")
def stop_thread(self, event = None):
"""
Stoppt den Thread
"""
if self.myworkerthread:
self.myworkerthread.stop()
self.thread_started = False
self.add_message(message = "Der Thread wurde soeben unterbrochen...")
else:
self.add_message(message = "Kein Thread aktiv...")
def stop_me(self, event = None):
"""
Fragt ob beendet werden soll und beendet bei Ja.
"""
retval = wx.MessageBox(
u"Möchten Sie jetzt beenden?",
"Beenden",
wx.YES_NO | wx.NO_DEFAULT | wx.CENTER ,
self
)
if retval == wx.YES:
self.Close()
class MyWorkerThread(threading.Thread):
"""
Diese Klasse soll Arbeit erledigen, aber nichts anzeigen.
"""
def __init__(self, notify_window):
"""
Initialisiert die Klasse und
übernimmt das Objekt, an das später die Events geschickt werden.
"""
threading.Thread.__init__(self)
self._notify_window = notify_window
self.stop_event = threading.Event()
def run(self):
"""
Thread-Hauptprozedur
"""
while True:
# Wenn das threading.Event (stop_event) gesetzt wurde --> abbrechen.
if self.stop_event.isSet():
# Thread stoppen
break
# Event an den Frame schicken
wx.PostEvent(
self._notify_window, NewMessageEvent(time.strftime("%H:%M:%S"))
)
time.sleep(2)
# Event zum Stoppen an Frame schicken
wx.PostEvent(self._notify_window, StopEvent())
def stop(self):
"""
Versucht den Thread zu unterbrechen. Dazu wird das
threading.Event (stop_event) gesetzt. Der Thread muss sich immer
selber abbrechen. Deshalb der Umweg über ein threading.Event.
"""
self.stop_event.set()
def main():
"""
Hauptprozedur
"""
app = wx.PySimpleApp()
frame = MyFrame()
frame.Show()
frame.Center()
app.MainLoop()
if __name__ == "__main__":
main()
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.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
So finde ich es fast noch ein bischen einfacher. Ohne die beiden Funktionen EVT_NEWMESSAGE und EVT_STOP.
mfg
Gerold
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import wx
import threading
import time
# NewMessageEvent
EVT_NEWMESSAGE_ID = wx.NewId()
class NewMessageEvent(wx.PyEvent):
"""
Simple event
"""
def __init__(self, message):
"""
Init Event.
"""
wx.PyEvent.__init__(self)
self.SetEventType(EVT_NEWMESSAGE_ID)
self.message = message
# StopEvent
EVT_STOP_ID = wx.NewId()
class StopEvent(wx.PyEvent):
"""
Simple event
"""
def __init__(self):
"""
Init Event.
"""
wx.PyEvent.__init__(self)
self.SetEventType(EVT_STOP_ID)
class MyFrame(wx.Frame):
"""
Hauptframe
"""
def __init__(
self, parent = None, title = "Hauptframe", size = (400, 300)
):
# Frame initialisieren
wx.Frame.__init__(self, parent, -1, title)
# Ein Panel als Grundlage
panel = wx.Panel(self)
# Ein vertikaler Boxsizer zum Anordnen
vb = wx.BoxSizer(wx.VERTICAL)
panel.SetSizer(vb)
# Ein Textfeld für die Ausgabe der Statusmeldungen (read only)
self.messages = wx.TextCtrl(
panel, -1,
style = wx.TE_AUTO_SCROLL | wx.TE_LINEWRAP |
wx.TE_MULTILINE | wx.TE_READONLY
)
vb.Add(self.messages, 1, wx.ALL | wx.EXPAND, 5)
# Buttonleiste
hb = wx.BoxSizer(wx.HORIZONTAL)
vb.Add(hb, 0, wx.EXPAND)
# Start
start_btn = wx.Button(panel, -1, "Start")
hb.Add(start_btn, 1, wx.ALIGN_CENTER_HORIZONTAL| wx.ALL, 5)
start_btn.Bind(wx.EVT_BUTTON, self.start_thread)
# Stopp
stopp_btn = wx.Button(panel, -1, "Stopp")
hb.Add(stopp_btn, 1, wx.ALIGN_CENTER_HORIZONTAL| wx.ALL, 5)
stopp_btn.Bind(wx.EVT_BUTTON, self.stop_thread)
# Thread-Variablen vorbereiten
self.myworkerthread = None
self.thread_started = False
# NewMessage-Event und Stop-Event binden
self.Connect(-1, -1, EVT_NEWMESSAGE_ID, self.add_message)
self.Connect(-1, -1, EVT_STOP_ID, self.stop_me)
def add_message(self, event = None, message = None):
"""
Fügt an den Text eine neue Zeile mit der neuen Nachricht an.
"""
if event:
message = str(event.message)
if len(self.messages.GetValue()) > 0:
message = "\n" + message
self.messages.AppendText(message)
self.messages.ScrollLines(10)
def start_thread(self, event = None):
"""
Startet den Thread
"""
# Prüfen ob der Thread schon läuft
if self.thread_started:
self.add_message(message = u"Der Thread läuft bereits...")
return
# Thread initialisieren
self.myworkerthread = MyWorkerThread(self)
# Thread starten
self.myworkerthread.start()
# Variable setzen und Nachricht ausgeben
self.thread_started = True
self.add_message(message = u"Der Thread wurde soeben gestartet...")
def stop_thread(self, event = None):
"""
Stoppt den Thread
"""
if self.myworkerthread:
self.myworkerthread.stop()
self.thread_started = False
self.add_message(message = "Der Thread wurde soeben unterbrochen...")
else:
self.add_message(message = "Kein Thread aktiv...")
def stop_me(self, event = None):
"""
Fragt ob beendet werden soll und beendet bei Ja.
"""
retval = wx.MessageBox(
u"Möchten Sie jetzt beenden?",
"Beenden",
wx.YES_NO | wx.NO_DEFAULT | wx.CENTER ,
self
)
if retval == wx.YES:
self.Close()
class MyWorkerThread(threading.Thread):
"""
Diese Klasse soll Arbeit erledigen, aber nichts anzeigen.
"""
def __init__(self, notify_window):
"""
Initialisiert die Klasse und
übernimmt das Objekt, an das später die Events geschickt werden.
"""
threading.Thread.__init__(self)
self._notify_window = notify_window
self.stop_event = threading.Event()
def run(self):
"""
Thread-Hauptprozedur
"""
while True:
# Wenn das threading.Event (stop_event) gesetzt wurde --> abbrechen.
if self.stop_event.isSet():
# Thread stoppen
break
# Event an den Frame schicken
wx.PostEvent(
self._notify_window, NewMessageEvent(time.strftime("%H:%M:%S"))
)
time.sleep(2)
# Event zum Stoppen an Frame schicken
wx.PostEvent(self._notify_window, StopEvent())
def stop(self):
"""
Versucht den Thread zu unterbrechen. Dazu wird das
threading.Event (stop_event) gesetzt. Der Thread muss sich immer
selber abbrechen. Deshalb der Umweg über ein threading.Event.
"""
self.stop_event.set()
def main():
"""
Hauptprozedur
"""
app = wx.PySimpleApp()
frame = MyFrame()
frame.Show()
frame.Center()
app.MainLoop()
if __name__ == "__main__":
main()
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.