如何从Python优雅地终止GLib主循环

时间:2019-06-20 10:43:45

标签: python glib

我编写了一个简单的Python脚本,以根据某个DBus信号(即,使PulseAudio接收器静音的守护程序)发送桌面通知。它可以工作,但是用Ctrl-C终止脚本会导致以下回溯:

Traceback (most recent call last):
  File "./notify.py", line 32, in <module>
    loop.run()
  File "/usr/lib/python3.7/site-packages/gi/overrides/GLib.py", line 495, in run
    super(MainLoop, self).run()
  File "/usr/lib/python3.7/contextlib.py", line 119, in __exit__
    next(self.gen)
  File "/usr/lib/python3.7/site-packages/gi/_ossighelper.py", line 251, in register_sigint_fallback
    signal.default_int_handler(signal.SIGINT, None)
KeyboardInterrupt

我尝试向atexit注册一个清理函数来调用GLib.MainLoop().quit(),但这似乎没有用。我知道我可以用try: ... except: ...块捕获异常,但是有更好的方法来处理此问题吗?

脚本代码如下:

import atexit

import gi
gi.require_version('Notify', '0.7')
from gi.repository import Notify
from pydbus import SessionBus

def handle_muted(interface, changed_props, invalidated_props):
    if changed_props["Muted"]:
        n = Notify.Notification.new("muted")
        n.set_urgency(Notify.Urgency(0))
        n.show()

@atexit.register
def cleanup():
    Notify.uninit()
    props.onPropertiesChanged = None
    loop.quit()

bus = SessionBus()
proxy = bus.get("org.mypadaemon")
props = proxy["org.freedesktop.DBus.Properties"]

if __name__ == '__main__':
    from gi.repository import GLib

    Notify.init("My PA Daemon")
    props.onPropertiesChanged = handle_muted

    loop = GLib.MainLoop()
    loop.run()

1 个答案:

答案 0 :(得分:0)

定义自定义信号处理程序有效:

import signal

def sigint_handler(sig, frame):
    if sig == signal.SIGINT:
        loop.quit()
    else:
        raise ValueError("Undefined handler for '{}'".format(sig))

并在if __name__ == '__main__'块中:

signal.signal(signal.SIGINT, sigint_handler)