Fragen über Fragen

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
ello
User
Beiträge: 14
Registriert: Montag 18. Juli 2005, 16:35
Wohnort: Eberswalde
Kontaktdaten:

Hallo allerseits,

entschuldigt bitte den nicht aussagekräftigen Titel. Da mir im Moment das Know How für eine bestimmte Fragestellung fehlt, ist mir jetzt einfach nichts gescheiteres/dümmeres eingefallen. :wink: Ich werde ihn (wenn möglich) ändern sobald mir ein besserer eingefallen ist.

Ok, nachdem ich nun schon eine ganze Weile mitlese hab ich mir vorgenommen in einem Projekt mal selbst mit Python aktiv zu werden. Das Ergebnis soll ein GTK-Frontend zu MPlayer und einigen Encodertools (oggenc,mencoder,lame) werden.

Nun hab ich ausgehend vom "Hello World" von pygtk.org angefangen nach und nach ein bisschen Funktion in die ganze Sache zu bringen. (mit mäßigem Erfolg)

Lange Rede kurzer Sinn, hier erstmal der Code:

Code: Alles auswählen

#!/usr/bin/python
# -*- encoding: latin-1 -*-
# vim: sw=4 ts=4 fdm=indent et

import subprocess, sys, gtk

gtk_check = gtk.check_version(2, 4, 0)
if gtk_check:
    print gtk_check
    sys.exit()

playshell = subprocess.Popen("/bin/sh", shell=False, stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)

class MainWin(gtk.Window):
    counter = 1
    def __init__(self, parent=None):
        gtk.Window.__init__(self)
        try:
            self.set_screen(parent.get_screen())
        except AttributeError:
            self.connect('destroy', lambda *w: gtk.main_quit())

        self.set_title('MRekorder')
        self.set_border_width(3)
        self.set_resizable(False)
        self.set_icon_from_file('icons/icon32.png')
        self.set_geometry_hints(min_width=200,
                                min_height=350,
                                max_width=200,
                                max_height=350)
        frame1 = gtk.Frame()
        frame1.set_label('Abspielen')
        vbox1 = gtk.VBox(False, 2)
        vbox2 = gtk.VBox(True, 2)
        playbtn = gtk.Button("_Play")
        playbtn.connect("clicked", self.on_play_clicked)
        hbox1 = gtk.HBox()
        prevbtn = gtk.Button("<< Pre_v")
        prevbtn.connect("clicked", self.on_prevbtn_clicked)
        stopbtn = gtk.Button("_Stop")
        stopbtn.connect("clicked", self.on_stop_clicked)
        nextbtn = gtk.Button("_Next >>")
        nextbtn.connect("clicked", self.on_next_clicked)
        hbox1.add(prevbtn)
        hbox1.add(stopbtn)
        hbox1.add(nextbtn)
        vbox2.add(playbtn)
        vbox2.add(hbox1)
        frame1.add(vbox2)

        frame2 = gtk.Frame()
        frame2.set_label('Info')

        frame3 = gtk.Frame()
        frame3.set_label('Aufnehmen')
        self.recbtn = gtk.ToggleButton("_Rec")
        self.recbtn.connect("clicked", self.on_rec_clicked)
        frame3.add(self.recbtn)

        vbox1.pack_start(frame1, expand = False, fill = True, padding = 0)
        vbox1.pack_start(frame2, expand = True, fill = True, padding = 0)
        vbox1.pack_end(frame3, expand = False, fill = True, padding = 0)

        self.add(vbox1)
        self.show_all()

    # Die Buttons sollen ja schliesslich auch etwas bezwecken ^^
    def on_prevbtn_clicked(self, widget):
        playshell.stdin.write("pt_step -1\n")

    def on_stop_clicked(self, widget):
        playshell.stdin.write("quit\n")

    def on_play_clicked(self, widget):
        audioout = "oss"
        to_listen = "/mnt/mugge/interpreten/jbo/jbo*"
        mplay = "mplayer -slave -quiet -ao %s %s" % (audioout, to_listen)
        playshell.stdin.write(mplay+"\n")


    def on_next_clicked(self, widget):
        playshell.stdin.write("pt_step +1\n")

    def on_rec_clicked(self, widget):
        status = self.recbtn.get_active()
        if status == True:
            outputpath = "$HOME/record"
            mrec = "sox -t ossdsp -w -s -r 44100 -c 2 /dev/dsp -t raw - | lame -x -m s - "\
                    +outputpath+"/mitschnitt-$(date +'%m''%d'_'%H'-'%M').mp3"
            self.mrec_proc = str(subprocess.Popen(mrec, shell=True).pid)
        else:
            mrec_kill = "killall sox"
            subprocess.Popen(mrec_kill, shell=True)

def main():
    MainWin()
    gtk.main()

if __name__ == '__main__':
    main()
Zuletzt geändert: 18.12.2005 01:23:28

Nun hab ich dazu folgende Probleme:
1. Beim Klick auf Play z.B. geht der Prozess ja in den Hintergrund und sollte per return den stdin, stdout und stderror zurückgeben. (Oder?)
Wie kann ich jetzt die Befehle für Stop, Prev und Next an stdin von mplay schicken?

2. Im Moment teilen sich die 3 Bereiche text, buttons und Status das Fenster zu gleichen Teilen, was ja nun alles andere als Ansehnlich und Zweckmäßig ist. Wie kann ich festlegen, dass die Statusleiste und die Buttons eine feste Höhe haben?

Wäre echt super, wenn ihr mir in dem Fall mal aus der Sackgasse helfen könntet. Je mehr ich jetzt versuche diese Probleme zu lösen desto mehr Fragen kommen mir in den Sinn.

Danke schonmal!

Gruß
ello
Zuletzt geändert von ello am Sonntag 18. Dezember 2005, 01:25, insgesamt 1-mal geändert.
[i]Losing my passport was the least of my worries,
losing a notebook was a catastrophe[/i]
[b]--Bruce Chatwin[/b]
ello
User
Beiträge: 14
Registriert: Montag 18. Juli 2005, 16:35
Wohnort: Eberswalde
Kontaktdaten:

Ich hab's jetzt zumindest geschafft, dass sich die 3 Teile den Platz nicht einteilen. Den Code oben hab ich aktualisiert. Aber zu dem Problem stdin/stdout/stderror hab ich immernoch keine Lösung gefunden.

Code: Alles auswählen

print mplayrun
Gibt mir zwar die Ausgaben vom Mplayer, aber wie kann ich an stdin vom Mplayer senden?
[i]Losing my passport was the least of my worries,
losing a notebook was a catastrophe[/i]
[b]--Bruce Chatwin[/b]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Puh! Erstmal würde ich dir vorschlagen dein Programm zu strukturieren. Das GTK+ keine Objektoreintierung erzwingt bedeutet nicht, dass man sie nicht sinnvoll nutzen kann:

Code: Alles auswählen

#!/usr/bin/python
# -*- encoding: latin-1 -*-

import os
import gtk

audioout = "esd"
input = "rtsp://213.200.75.253/farm/*/encoder/sunshinelive/livestream2.rm"
outputpath = "$HOME/record"
mplay = "mplayer -slave -really-quiet -ao %s %s" % (audioout, input)
mrec = "sox -t ossdsp -w -s -r 44100 -c 2 /dev/dsp -t raw - | lame -x -m s - "\
        +outputpath+"/mitschnitt-$(date +'%m''%d'_'%H'-'%M').mp3"

class FrontWin(object):
    def __init__(self):
        # Fenstereinstellungen Player
        self.mainwindow = gtk.Window()
        self.mainwindow.set_title("gMRekorder")
        self.mainwindow.set_default_size(450, 300)
        self.mainwindow.set_geometry_hints(None, 350, 250)
        #self.mainwindow.set_icon_from_file("icons/icon32.png")
        self.mainwindow.connect('delete-event', gtk.main_quit)
        
        # Die Buttons
        self.prevbtn = gtk.Button("<< Pre_v")
        self.prevbtn.connect("clicked", self.on_prevbtn_clicked)

        self.stopbtn = gtk.Button("_Stop")
        self.stopbtn.connect("clicked", self.on_stop_clicked)

        self.recbtn = gtk.Button("_Rec")
        self.recbtn.connect("clicked", self.on_rec_clicked)

        self.playbtn = gtk.Button("_Play")
        self.playbtn.connect("clicked", self.on_play_clicked)

        self.nextbtn = gtk.Button("_Next >>")
        self.nextbtn.connect("clicked", self.on_next_clicked)

        self.playertab = gtk.Frame("Player Einstellungen")
        self.recordertab = gtk.Frame("Rekorder Einstellungen")
        self.consoletab = gtk.Frame("Console")
        self.abouttab = gtk.Frame("über gMRekorder")

        self.tabs = gtk.Notebook()
        self.tabs.append_page(self.playertab)
        self.tabs.set_tab_label_text(self.playertab, "Player")
        self.tabs.append_page(self.recordertab)
        self.tabs.set_tab_label_text(self.recordertab, "Recorder")
        self.tabs.append_page(self.consoletab)
        self.tabs.set_tab_label_text(self.consoletab, "Console")
        self.tabs.append_page(self.abouttab)
        self.tabs.set_tab_label_text(self.abouttab, "About")

        self.buttons = gtk.HButtonBox()
        self.buttons.add(self.prevbtn)
        self.buttons.add(self.stopbtn)
        self.buttons.add(self.recbtn)
        self.buttons.add(self.playbtn)
        self.buttons.add(self.nextbtn)

        self.status = gtk.Statusbar()
        self.status.set_has_resize_grip(True)
        self.status.push(1, "gMRekorder")

        vbox = gtk.VBox(spacing=3)
        vbox.set_homogeneous(0)
        vbox.pack_start(self.tabs, 1, 1, 0)
        vbox.pack_start(self.buttons, 0, 1, 0)
        vbox.pack_end(self.status, 0, 1, 0)

        self.mainwindow.add(vbox)
        self.mainwindow.show_all()
    
    def on_prevbtn_clicked(self, widget):
        print "pt_step -1"
    
    def on_stop_clicked(self, widget):
        print "quit"
    
    def on_rec_clicked(self, widget):
        mrecrun = os.popen3(mrec)
        return mrecrun
    
    def on_play_clicked(self, widget):
        mplayrun = os.popen3(mplay)
        return mplayrun
    
    def on_next_clicked(self, widget):
        print "pt_step +1"

def main():
    fw = FrontWin()
    gtk.main()

if __name__ == '__main__':
    main()
Zum lesen/schreiben von stdin, stdout und stderr empfehle ich dir das Modul subprocess, schau es dir mal an, das macht vieles doch etwas klarer.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ello
User
Beiträge: 14
Registriert: Montag 18. Juli 2005, 16:35
Wohnort: Eberswalde
Kontaktdaten:

Leonidas hat geschrieben:Puh! Erstmal würde ich dir vorschlagen dein Programm zu strukturieren. Das GTK+ keine Objektoreintierung erzwingt bedeutet nicht, dass man sie nicht sinnvoll nutzen kann:
Ja, ich hab gestern abend erst angefangen mich in Klassen und Funktionen einzulesen, da mir das alles sehr unsauber vor kam.
Leonidas hat geschrieben:Zum lesen/schreiben von stdin, stdout und stderr empfehle ich dir das Modul subprocess, schau es dir mal an, das macht vieles doch etwas klarer.
Danke für den Tip und die Arbeit die du auf dich genommen hast! Das Modul scheint ne Lösung zu sein. Werd mich gleich mal damit auseinander setzen.
[i]Losing my passport was the least of my worries,
losing a notebook was a catastrophe[/i]
[b]--Bruce Chatwin[/b]
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Das mit den feste-Höhe-Buttons würde mich auch schwer interessieren.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Button Höhe und Weite:

Code: Alles auswählen

self.button=gtk.Button("Hannes")
self.w=200
self.b=300
self.button.set_size_request(self.w,self.b)
self.button.show()
Gruß
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wobei man sich das Binden an ``self`` natürlich sparen kann. Man kann sich eigentlich das Binden an so nichtssagende Namen wie ``b`` und ``w`` eigentlich auch generell sparen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Mach kein Stress :D
Für alle:
self.b=Breite
self.w=Höhe
:P
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dauerbaustelle hat geschrieben:Mach kein Stress :D
Es geht eben um den Sinn von den Dingen die du machst. Und die Werte an so blöde Namen zu binden ist sinnlos. Zweitens ist es auch semantisch quatsch, weil du die Dimensionen des Buttons an das Objekt welches das Fenster repräsentiert bindest. Du hast also etwa Fenster.breite = 300, aber willst eigentlich Button.breite haben.

Das macht einen Unterschied.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten