I am trying to make a simple application to play and stop a midi file using pygtk.
Here's what I have so far :
import pygtk
pygtk.require('2.0')
import gtk
import subprocess
class Teacher:
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_size_request(400, 200)
window.set_title("Music Teacher")
window.connect("delete_event",
lambda w,e: gtk.main_quit())
table = gtk.Table(4, 4, True)
window.add(table)
play = gtk.Button("Play")
play.connect("clicked", self.clicked_play)
play.show()
stop = gtk.Button("Stop")
stop.show()
table.attach(play, 0, 1, 0, 1)
table.attach(stop, 0, 1, 1, 2)
window.show_all()
def clicked_play(self, widget):
subprocess.Popen(["timidity", "~/somefile.mid"])
def main(self):
gtk.main()
return 0
Teacher().main()
Is there I can send interrupt from stop and delete_event to kill the process? Should I be using threads?
You can handle getting a SIGTERM
, a Ctrl+C, or the stop button being pushed like this:
import pygtk
pygtk.require('2.0')
import gtk
import subprocess
import signal
class Teacher:
def __init__(self):
self.proc = None # Initialize the handle to our subprocess
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_size_request(400, 200)
window.set_title("Music Teacher")
window.connect("delete_event",
lambda w,e: gtk.main_quit())
table = gtk.Table(4, 4, True)
window.add(table)
play = gtk.Button("Play")
play.connect("clicked", self.clicked_play)
play.show()
stop = gtk.Button("Stop")
stop.connect("clicked", self.clicked_stop)
stop.show()
table.attach(play, 0, 1, 0, 1)
table.attach(stop, 0, 1, 1, 2)
window.show_all()
def clicked_play(self, widget):
self.proc = subprocess.Popen(["timidity", "~/somefile.mid"])
def clicked_stop(self, widget=None):
if self.proc:
self.proc.terminate()
self.proc.wait()
def handle_sigterm(self, *args):
self.clicked_stop()
sys.exit()
def main(self):
signal.signal(signal.SIGTERM, self.handle_sigterm)
try:
gtk.main()
except KeyboardInterrupt:
self.clicked_stop()
raise
return 0
Teacher().main()
We just save a reference to the Popen
object we created in clicked_play
, and then use that handle to send a SIGTERM
to the process using the terminate
instance method in click_stop
. We then call wait
(which should finish instantly, unless timidity
doesn't close on SIGTERM
) to reap the terminated process (so it won't leave a zombie behind).
I also added a try
/ except
around the call to gtk.main()
so that clicked_stop
will be called if you issue a Ctrl+C, and a SIGTERM
handler that does the same, should that signal be received.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.