【问题标题】:How to gracefully terminate a GLib main loop from Python [duplicate]如何从 Python 优雅地终止 GLib 主循环 [重复]
【发布时间】:2019-06-20 10:43:45
【问题描述】:

我编写了一个简单的 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()

【问题讨论】:

  • GLib.MainLoop.quit() 到底在什么方面不起作用?
  • @LEEE 它没有摆脱回溯转储。我认为循环可能会拦截Ctrl-C 键,而不是脚本(这会触发atexit 调用)。
  • 尝试处理SIGINT 使用GLib.unix_signal_add() 来处理GLib 主循环中的信号:programcreek.com/python/example/82885/… (如果这对你有用,把它写成一个正确的答案;我不能现在被打扰了。)
  • @atexit.register 没有摆脱回溯转储。我建议看看this question

标签: python glib


【解决方案1】:

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

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)

【讨论】:

    猜你喜欢
    • 2014-08-17
    • 1970-01-01
    • 2015-12-05
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 2013-03-24
    • 1970-01-01
    相关资源
    最近更新 更多