Hallo Zusammen...
Ich habe wiedermal ein Problem ^^
Bis jetzt erstelle ich ein archiv mit WinRar (cmd Version), was allerdings ein cmd Fenster aufruft, welches auch nicht geschlossen werden kann.
Ich möchte das die Ausgabe nicht in die CMD erfolgt sondern in Ein TextCtrl.
Zusätzlich sollte es möglich sein die CMD irgend wie "abzuschiessen". Was benötigt wird, falls der Benutzer die Anwendung abbrechen möchte...
Gibts so was???
mfG
DM
cmd in Appi mit GUI
- DatenMetzgerX
- User
- Beiträge: 398
- Registriert: Freitag 28. April 2006, 06:28
- Wohnort: Zürich Seebach (CH)
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Guck dir mal das Modul subprocess ([wiki]Neue_Features#Subprocess[/wiki]) an, damit kannst du den inhalt des CMDs auslesen und das CMD gar nicht erst öffnen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
- 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:Bis jetzt erstelle ich ein archiv mit WinRar (cmd Version), was allerdings ein cmd Fenster aufruft, welches auch nicht geschlossen werden kann.
[...]
Zusätzlich sollte es möglich sein die CMD irgend wie "abzuschiessen". Was benötigt wird, falls der Benutzer die Anwendung abbrechen möchte...
Ich rate dir von RAR ab. Warum? Wir haben erst vor Kurzem die Kompression unserer Server-Datensicherungen von RAR auf GZip umgestellt. Der Unterschied? Die Kompression ist nicht mehr ganz so gut, dafür dauert die Sicherung nicht mehr so lange.
Hier ein Vergleich:
Unser Testobjekt -- eine MSSQL-Datenbanksicherung in der Größe von 40 GB.
- Winzip: ca. 31min (kein direktes Spanning), Spanning auf 650MB-Teile ca. 10min
- ARJ: keine Dateien über 1GB -> untauglich
- WinRAR: Packzeit über 2,5 Std. -> untauglich
- GZip: ca. 26min
Ich empfehle dir das Python-Modul "tarfile" http://www.python.org/doc/current/lib/tar-examples.html da es auch mit "GZip" gepackte archive erstellen und lesen kann. Außerdem bestimmst du jedes File, das in das Tarfile gepackt wird und kannst diesen Vorgang **jederzeit** selber unterbrechen. Du musst also kein Signal an irgend ein DOS-Programm schicken.
mfg
Gerold
Edit: Komma am Ende eines Links weggenommen.
Zuletzt geändert von gerold am Samstag 27. Mai 2006, 15:00, insgesamt 2-mal geändert.
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 wär doch was )
Nimm bei deinem Link am schluss noch das Komma weg, könnte einige irritieren
Noch eine frage zu subprocess. Ist es möglich aus stdout Zeile für Zeile zu lesen. Macht keinen Sinn wenn ich 6h warte und nie sehe wie weit er ist und am schluss sehe ich für 1-2s noch die Meldungen ^^
Nimm bei deinem Link am schluss noch das Komma weg, könnte einige irritieren
Noch eine frage zu subprocess. Ist es möglich aus stdout Zeile für Zeile zu lesen. Macht keinen Sinn wenn ich 6h warte und nie sehe wie weit er ist und am schluss sehe ich für 1-2s noch die Meldungen ^^
- DatenMetzgerX
- User
- Beiträge: 398
- Registriert: Freitag 28. April 2006, 06:28
- Wohnort: Zürich Seebach (CH)
Das Problem ist.... Das ganze Backup muss auch subversion unterstützen. Und da gibt es einen CMD-Befehl. Und das sollte auch in die GUI, und darum brauche ich das andere....
Und die GZ archive werden einfach extrem gross
Und die GZ archive werden einfach extrem gross
- 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:... Und das sollte auch in die GUI, und darum brauche ich das andere....
Und die GZ archive werden einfach extrem gross
Ich will dich nicht davon abhalten, RAR zu benutzen...
Hier wieder ein kleines Beispiel. Allerdings mit UNIX-Pfaden. Die Pfade musst du selber an Windows anpassen, da ich gerade KDE kompiliere und nicht zwischendurch mal Windows booten kann.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
import wx
import threading
import time
import os
# 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"
):
# 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
)
font = self.messages.GetFont()
font.SetFamily(wx.FONTFAMILY_SCRIPT)
self.messages.SetFont(font)
vb.Add(self.messages, 1, wx.ALL | wx.EXPAND, 5)
# Buttonleiste
hb = wx.BoxSizer(wx.HORIZONTAL)
vb.Add(hb, 0, wx.EXPAND)
# Start
self.start_btn = wx.Button(panel, -1, "Start")
hb.Add(self.start_btn, 1, wx.ALIGN_CENTER_HORIZONTAL| wx.ALL, 5)
self.start_btn.Bind(wx.EVT_BUTTON, self.start_thread)
self.start_btn.SetDefault()
# 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_signal_empfangen)
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
# Log-Feld leeren und Button deaktivieren
self.messages.Clear()
self.start_btn.Enable(False)
# 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_signal_empfangen(self, event = None):
"""
Zeigt an, dass er fertig ist.
"""
self.thread_started = False
self.add_message(message = "Fertig...")
wx.MessageBox(u"Fertig!", "Fertig", wx.OK | wx.CENTER, self)
self.start_btn.Enable(True)
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
def run(self):
"""
Thread-Hauptprozedur
"""
out = os.popen("rar a -idp hallo.rar /bin", "r", 0)
for line in out:
# Event an den Frame schicken
wx.PostEvent(
self._notify_window, NewMessageEvent(line.strip())
)
# Event zum Stoppen an Frame schicken
wx.PostEvent(self._notify_window, StopEvent())
def main():
"""
Hauptprozedur
"""
app = wx.PySimpleApp()
frame = MyFrame()
frame.SetSize((600, 500))
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:
PS: Die Anzeigedaten kommen vom WinRAR nicht zeilenweise. Da ist ein Cache dazwischen. Den kannst du nicht umgehen. Also gar nicht erst fragen. Bringt nichts.
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)
Ich glaube ich verstehe das ganze so einigermassen....
Nur, jetzt beendet ja der MyWorkerThread die GUI.
Wenn die GUI geschlossen wird, sollte ja nicht noch der MyWorkerThread laufen, der soll auch beendet werden.
Momentan habe ich das ganz hässlich gelöst...
Vor jedem Durchgang wo ich etwas kopiere / Archiviere... prüfe ich ob Appli.UserExit auf 1 ist oder nicht.
Problem z.B bei WinRar archiven, das ich subprocess nicht so schnell beenden kann, besser gesagt gar nicht...
Mir ist gerade aufgefallen das ich jetzt 2 Sachen aus 2 verschiedenen Treads frage
Nur, jetzt beendet ja der MyWorkerThread die GUI.
Code: Alles auswählen
frame.Bind(wx.EVT_CLOSE, lambda event: backupf.abort(app, frame,Appli))
Momentan habe ich das ganz hässlich gelöst...
Code: Alles auswählen
Appli.UserExit=1
frame.SetError("Anwendung wird beendet")
while Appli.isAlive():
time.sleep(1)
frame.Destroy()
Problem z.B bei WinRar archiven, das ich subprocess nicht so schnell beenden kann, besser gesagt gar nicht...
Mir ist gerade aufgefallen das ich jetzt 2 Sachen aus 2 verschiedenen Treads frage