Konsole umleiten in wxFenster
-
- User
- Beiträge: 435
- Registriert: Montag 20. Februar 2006, 18:11
- Wohnort: Menden / Sauerland
- Kontaktdaten:
Ich habe hier jetzt 3 Sachen im Forum gelesen, wie man die Ausgabe einer Konsole umleiten kann und bin verwirrt Mein Problem ist, ich möchte zum Beispiel das Programm "cdda2wav" von einem wxFenster ausführen und die Ausgaben, des Programms ( einige davon ) auf mein Fenster packen. Das Konsolen Programm gibt einen Prozentwert aus, wie weit es gerade ist, und auch diesen Wert brauche ich in meinem Fenster. Aber wie funktioniert so was genau? Die 3 anderen Threads haben mich nen bischen verwirrt
-
- User
- Beiträge: 435
- Registriert: Montag 20. Februar 2006, 18:11
- Wohnort: Menden / Sauerland
- Kontaktdaten:
Ich habe das mal so, wie in einem Beispiel, in dem Forum ausprobiert:
Das externe Programm wird auch gestartet, allerdings wartet mein Programm bis das externe sich beendet hat und ins Listfeld wird auch nicht geschrieben, außer alles Leerzeichen
Wieso bekomme ich denn nichts zurück? wenn ich den "dir" einsetze, also mal das externe Programm tausche, zeigt mir der Befehl "dir" auch etwas in meinem Listfeld an.
Weiß jemand rat?
Code: Alles auswählen
def transcode(self, event): # wxGlade: MainWin.<event_handler>
process = subprocess.Popen('bin\\devdump', shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.wait()
proc_output_stdout = process.stdout.read()
self.list_box_1.Append (proc_output_stdout)
event.Skip()
Wieso bekomme ich denn nichts zurück? wenn ich den "dir" einsetze, also mal das externe Programm tausche, zeigt mir der Befehl "dir" auch etwas in meinem Listfeld an.
Weiß jemand rat?
Kurze Frage: Hast du auch hier mal nachgeschaut ?
-
- User
- Beiträge: 435
- Registriert: Montag 20. Februar 2006, 18:11
- Wohnort: Menden / Sauerland
- Kontaktdaten:
Danke, hatte ich noch nicht gesehen und probiere es gerade mal aus. Also bis jetzt funtzt es noch nicht. Die Ausgaben kommen nur in der Konsole und nicht in mein Textfeld, obwohl ich es genau so gemacht habe, wie in dem Beispiel. Mein komplettes Form freezt. Liegt warscheinlich daran, das ich den Timer noch nicht untergebracht habe.
-
- User
- Beiträge: 435
- Registriert: Montag 20. Februar 2006, 18:11
- Wohnort: Menden / Sauerland
- Kontaktdaten:
Also ich bin ratlos. Wenn ich es so mache ( wie auch im Beispiel ), freezt mein Fenster und ich bekomme nichts in mein Textfeld.
Was mache ich denn da bloß falsch?
EDIT:
Es muß irgendwas auch am Timer liegen, den mein Event wird gar nicht erst angesprungen
EDIT:
Timer funtzt doch, aber line bleibt leer, daher beendet sich der Timer ja
mein Stream bleibt einfach leer
Code: Alles auswählen
# -*- coding: iso-8859-15 -*-
# generated by wxGlade 0.6.3 on Wed Aug 06 12:09:01 2008
import wx
import subprocess
# begin wxGlade: dependencies
# end wxGlade
# begin wxGlade: extracode
# end wxGlade
class MainWin(wx.Frame):
def __init__(self, *args, **kwds):
# begin wxGlade: MainWin.__init__
kwds["style"] = wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.process = None
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
self.panel_1 = wx.Panel(self, -1)
self.text_ctrl_1 = wx.TextCtrl(self.panel_1, -1, "")
self.static_line_1 = wx.StaticLine(self.panel_1, -1)
self.btn_transcode = wx.Button(self.panel_1, -1, "Umwandeln")
self.__set_properties()
self.__do_layout()
self.Bind(wx.EVT_BUTTON, self.transcode, self.btn_transcode)
# end wxGlade
def __set_properties(self):
# begin wxGlade: MainWin.__set_properties
self.SetTitle("CD2MP3")
self.text_ctrl_1.SetMinSize((400, 150))
# end wxGlade
def __do_layout(self):
# begin wxGlade: MainWin.__do_layout
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_2 = wx.BoxSizer(wx.VERTICAL)
sizer_3 = wx.BoxSizer(wx.VERTICAL)
sizer_3.Add(self.text_ctrl_1, 0, wx.ALL, 5)
sizer_3.Add(self.static_line_1, 0, wx.ALL|wx.EXPAND, 5)
sizer_3.Add(self.btn_transcode, 0, wx.ALL, 5)
sizer_2.Add(sizer_3, 0, wx.EXPAND, 0)
self.panel_1.SetSizer(sizer_2)
sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
sizer_1.Fit(self)
self.Layout()
self.Centre()
# end wxGlade
def transcode(self, event): # wxGlade: MainWin.<event_handler>
self.timer.Start(10)
self.process = subprocess.Popen('bin//cdda2wav.exe -L 0', stdout=subprocess.PIPE)
event.Skip()
def OnTimer(self, event):
out = self.process.stdout
line = out.readline()
if line:
self.text_ctrl_1.AppendText(line)
else:
self.timer.Stop()
# end of class MainWin
EDIT:
Es muß irgendwas auch am Timer liegen, den mein Event wird gar nicht erst angesprungen
EDIT:
Timer funtzt doch, aber line bleibt leer, daher beendet sich der Timer ja
mein Stream bleibt einfach leer
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo The Hit-Man!
Suche in der wxPython-Demo nach "Process". Schau dir dort das Beispiel an. Dort wird genau das gemacht was du machen möchtest.
Es gibt noch andere Möglichkeiten. Z.B. könntest du das aufzurufende Programm über einen zweiten Thread starten und immer wenn etwas vom zweiten Thread kommt, dann kannst du es im Hauptthread in einem Fenster anzeigen.
Oder du arbeitest mit einem Timer. Aber die Timer-Lösung ist mir persönlich am unliebsten.
Aber was ein wirklicher Stopper für dein Vorhaben sein kann -- wenn das aufgerufene Programm die Ausgabe cached. Und das ist ziemlich oft der Fall. Dann bekommst du die Ausgabe des Programmes immer nur in größeren Blöcken. -- Leider. Aber das merkst du sofort, wenn du dein Konsolenprogramm über die wxPython-Demo testest.
mfg
Gerold
Suche in der wxPython-Demo nach "Process". Schau dir dort das Beispiel an. Dort wird genau das gemacht was du machen möchtest.
Es gibt noch andere Möglichkeiten. Z.B. könntest du das aufzurufende Programm über einen zweiten Thread starten und immer wenn etwas vom zweiten Thread kommt, dann kannst du es im Hauptthread in einem Fenster anzeigen.
Oder du arbeitest mit einem Timer. Aber die Timer-Lösung ist mir persönlich am unliebsten.
Aber was ein wirklicher Stopper für dein Vorhaben sein kann -- wenn das aufgerufene Programm die Ausgabe cached. Und das ist ziemlich oft der Fall. Dann bekommst du die Ausgabe des Programmes immer nur in größeren Blöcken. -- Leider. Aber das merkst du sofort, wenn du dein Konsolenprogramm über die wxPython-Demo testest.
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: 435
- Registriert: Montag 20. Februar 2006, 18:11
- Wohnort: Menden / Sauerland
- Kontaktdaten:
Verstehe ich nicht so ganz. Woher sollte mein Textfeld denn dann wissen, welche Sachen es annehmen sollte?wx leitet automatisch die stdout Ausgabe in Textfenster um, wenn welche zur Verfügung stehen.
Dazu musst du dein App Objekt mit True als erstem Argument instanzieren.
Ich finde leider nur dieses hier http://www.wxwidgets.org/downloads/demos.htm und da finde ich nichts mit Process.Suche in der wxPython-Demo nach "Process". Schau dir dort das Beispiel an. Dort wird genau das gemacht was du machen möchtest.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo The Hit-Man!
Ich meinte diese Demo hier:
- http://downloads.sourceforge.net/wxpyth ... .8.8.1.exe (für Windows)
- http://downloads.sourceforge.net/wxpyth ... .1.tar.bz2 (Quellcode)
Zu finden in der Download-Seite von wxPython: http://wxpython.org/download.php (suche dort nach "Demo")
Die wxPython-Demo ist so ziemlich die beste Beispielsammlung für die Arbeit mit wxPython. Wenn ich mal kurz nicht weiß, mit welchem Widget ich etwas anzeigen soll, dann schaue ich mir die wxPython-Demo an. Die wxPython-Demo solltest du fast auswendig können. Denn dann weißt du welche Bausteine du für deine Programme zur Verfügung hast.
mfg
Gerold
Das ist keine Lösung für dich. Vergiss es.The Hit-Man hat geschrieben:Verstehe ich nicht so ganz. Woher sollte mein Textfeld denn dann wissen, welche Sachen es annehmen sollte?wx leitet automatisch die stdout Ausgabe in Textfenster um, wenn welche zur Verfügung stehen.
Dazu musst du dein App Objekt mit True als erstem Argument instanzieren.
Bitte nicht wxWidgets mit wxPython verwechseln.The Hit-Man hat geschrieben:Ich finde leider nur dieses hier http://www.wxwidgets.org/downloads/demos.htm und da finde ich nichts mit Process.Suche in der wxPython-Demo nach "Process". Schau dir dort das Beispiel an. Dort wird genau das gemacht was du machen möchtest.
Ich meinte diese Demo hier:
- http://downloads.sourceforge.net/wxpyth ... .8.8.1.exe (für Windows)
- http://downloads.sourceforge.net/wxpyth ... .1.tar.bz2 (Quellcode)
Zu finden in der Download-Seite von wxPython: http://wxpython.org/download.php (suche dort nach "Demo")
Die wxPython-Demo ist so ziemlich die beste Beispielsammlung für die Arbeit mit wxPython. Wenn ich mal kurz nicht weiß, mit welchem Widget ich etwas anzeigen soll, dann schaue ich mir die wxPython-Demo an. Die wxPython-Demo solltest du fast auswendig können. Denn dann weißt du welche Bausteine du für deine Programme zur Verfügung hast.
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: 435
- Registriert: Montag 20. Februar 2006, 18:11
- Wohnort: Menden / Sauerland
- Kontaktdaten:
Habe ich gemacht Da war ja auch nen Demo bei, in dem ich meinen eigenen externen Befehl testen konnte. Hatte mal "cdda2wav -L 0" eingetragen. Das lief auch an, allerdings zeigte mir das Ausgabefenster nichts an der Task von dem externen Programm lief aber.Suche in der wxPython-Demo nach "Process". Schau dir dort das Beispiel an. Dort wird genau das gemacht was du machen möchtest.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Hit-Man!The Hit-Man hat geschrieben:Hatte mal "cdda2wav -L 0" eingetragen.
Probiere es mal mit dem zusätzlichen Parameter ``--gui``.
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: 435
- Registriert: Montag 20. Februar 2006, 18:11
- Wohnort: Menden / Sauerland
- Kontaktdaten:
Leider genau das gleiche. Das Augabefenster bleibt leider leer
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Hit-Man!The Hit-Man hat geschrieben:Leider genau das gleiche. Das Augabefenster bleibt leider leer
Ändere die Funktion "OnSendText" mal so ab:
Code: Alles auswählen
def OnSendText(self, evt):
text = self.inp.GetValue()
self.inp.SetValue('')
self.log.write('OnSendText: "%s"\n' % text)
self.process.GetOutputStream().write(text + '\n')
self.process.GetErrorStream().write(text + '\n')
self.inp.SetFocus()
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: 435
- Registriert: Montag 20. Februar 2006, 18:11
- Wohnort: Menden / Sauerland
- Kontaktdaten:
ne, leider auch nichts Es soll doch so laufen. Oben in der Komandozeile gebe ich meinen Befehl ein. Diesen starte ich dann mit Execute. Dann sollten doch die Ausgaben im Ausgabenfenster erscheinen? Da kommt aber leider nichts. Wenn ich cdda2wav in der Konsole starte, kommt alles wie es sein sollte, aber nicht in dem Ausgabefenster. KAnn mir nicht vorstellen, das das nicht gehen sollte, da ja extra der --gui Parameter in dem Programm existiert.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Hit-Man!The Hit-Man hat geschrieben:ne, leider auch nichts
Gut, dann die Thread-Methode:
Code: Alles auswählen
##!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import os
import wx
import threading
import subprocess
wx.SetDefaultPyEncoding("iso-8859-15")
class WorkerThread(threading.Thread):
def __init__(self, statuslog_function):
threading.Thread.__init__(self)
self.statuslog_function = statuslog_function
def run(self):
args = ["dir", os.path.expandvars("$WINDIR")]
process = subprocess.Popen(
args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT
)
for line in process.stdout:
self.statuslog_function(line)
class MyFrame(wx.Frame):
def __init__(
self, parent = None, title = "Example", size = wx.Size(550, 420)
):
wx.Frame.__init__(self, parent, -1, title, size = size)
panel = wx.Panel(self)
vbox_main = wx.BoxSizer(wx.VERTICAL)
panel.SetSizer(vbox_main)
self.textctrl = wx.TextCtrl(panel, style = wx.TE_MULTILINE)
vbox_main.Add(self.textctrl, 1, wx.EXPAND | wx.ALL, 5)
btn_start = wx.Button(panel, label = u"Start")
vbox_main.Add(btn_start, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
btn_start.Bind(wx.EVT_BUTTON, self.start_thread)
def statuslog_function(self, logentry):
wx.CallAfter(self.textctrl.AppendText, logentry)
def start_thread(self, event = None):
self.workerthread = WorkerThread(self.statuslog_function)
self.workerthread.start()
def main():
"""Testing"""
app = wx.PySimpleApp()
f = MyFrame()
f.Center()
f.Show()
app.MainLoop()
if __name__ == "__main__":
main()
Code: Alles auswählen
args = ["<pfad zu cdda2wav>", "-L", "0", "--gui"]
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: 435
- Registriert: Montag 20. Februar 2006, 18:11
- Wohnort: Menden / Sauerland
- Kontaktdaten:
Erst mal Danke, das Du dich um mich kümmerst. Habe aber leider schlechte Nachrichten, auch das geht leider nicht. Das Feld bleibt einfach leer, aber cdda2wav startet. Das wars aber auch schon. Immer noch keine Ausgabe im Fenster
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Hit-Man!The Hit-Man hat geschrieben:auch das geht leider nicht
Aber mit "DIR" funktioniert die Ausgabe?
Erwartet CDDA2WAV irgendetwas an STDIN? Mit welchen Parametern hast du CDDA2WAV genau gestartet?
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: 435
- Registriert: Montag 20. Februar 2006, 18:11
- Wohnort: Menden / Sauerland
- Kontaktdaten:
ja, mit "dir" geht es. Aber vermutlich nur, wenn dir auch abgearbeitet ist. Das wäre ja das gleiche, wenn ich "dir >> ausgabe.txt" nehmen würde.
Hätte nicht gedacht, das ich damit so verzweifle. K3B setzt ja auch auf cdrecord usw. auf. Die müssen das doch ganz genau so gemacht haben, wie ich es jetzt versuchen möchte.
Eigentlich kannste cdda2wav.exe direkt in der Konsole starten, ohne Parametern und es erwartet auch keine Tasteneingabe oder so. Habe so das gefühl, so lange das Programm noch nicht fertig ist, wird auch keine Ausgabe auf das Fenster erfolgenErwartet CDDA2WAV irgendetwas an STDIN? Mit welchen Parametern hast du CDDA2WAV genau gestartet?
Hätte nicht gedacht, das ich damit so verzweifle. K3B setzt ja auch auf cdrecord usw. auf. Die müssen das doch ganz genau so gemacht haben, wie ich es jetzt versuchen möchte.
Was mir gerade beim Nachvollziehen aufgefallen ist ... Ich habe mal "emerge -av amarok" eingegeben und ebenfalls keine Rückmeldung erhalten, nur daß der Thread sich gleich wieder beendet hat (unteres Fenster). Dann ist mir eingefallen, daß der User, mit dem ich die Demo ausgeführt habe keine Berechtigung hat, emerge auszuführen. Überprüfe also sicherheitshalber auch noch mal die Ausführungsrechte, auch wenn es wahrscheinlich nicht daran liegt.
-
- User
- Beiträge: 435
- Registriert: Montag 20. Februar 2006, 18:11
- Wohnort: Menden / Sauerland
- Kontaktdaten:
naja, bin unter Windows 2k ( Admin ). Ich kann das Programm ja locker aus der Konsole starten.