停止进程pygtk

时间:2014-07-17 14:25:18

标签: python subprocess 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()

我可以从stop和delete_event发送中断来终止进程吗?我应该使用线程吗?

1 个答案:

答案 0 :(得分: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()

我们只保存对我们在Popen中创建的clicked_play对象的引用,然后使用该句柄使用SIGTERM实例方法向进程发送terminateclick_stop。然后我们致电wait(除非timidity未在SIGTERM关闭,否则应立即结束)以获得已终止的流程(因此它不会留下僵尸)。

我还在try的调用周围添加了except / gtk.main(),以便在您发出Ctrl + C和{{1}时调用clicked_stop如果接收到该信号,则执行相同的处理程序。