停止一个pygtk进程
我正在尝试用pygtk制作一个简单的应用程序,用来播放和停止一个midi文件。
这是我目前的进展:
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()
我可以从停止和删除事件中发送中断来结束这个进程吗?我应该使用线程吗?
1 个回答
3
你可以这样处理接收到的 SIGTERM
信号、按下 Ctrl+C 或者点击停止按钮的情况:
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()
我们在 clicked_play
函数中保存了一个我们创建的 Popen
对象的引用,然后在 click_stop
函数中用这个引用来发送 SIGTERM
信号给这个进程,方法是调用 terminate
。接着,我们调用 wait
(这个调用应该很快完成,除非 timidity
在接收到 SIGTERM
时没有正常关闭),这样可以处理掉被终止的进程,避免留下“僵尸进程”。
我还在调用 gtk.main()
的地方加了一个 try
/except
,这样如果你按下 Ctrl+C,clicked_stop
就会被调用。同时,如果接收到 SIGTERM
信号,也会调用一个处理函数来做同样的事情。