我正在尝试使用pynotify编写程序,这是用于libnotify的Python绑定。我想在某个时刻提出关键通知,并在信息发生变化时每隔几秒更新一次,直到用户点击它为止。这一切都有效,除了处理用户解雇时发生的事情。
要更新通知,我需要在Notification.show
之后致电Notification.update
。这很好,但这意味着我需要跟踪用户是否已经解除了通知,否则它会再次弹出。
这应该是我能想到的两种方法:
Notification.show
。第二种方法应该是可行的。我找到的示例代码(似乎没有任何适当的pynotify文档)让我调用Notification.connect
将"closed"
信号连接到回调。我试图这样做,但回调从未被解雇。
我用Google搜索并调试了很长时间但无法取得任何进展。最后我发现了一些带有pynotify的示例脚本。其中一个将处理程序附加到"closed"
信号:test-xy-stress.py
其内容如下:
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gobject
import gtk
import gtk.gdk
import pynotify
import sys
import random
exposed_signal_id = 0
count = 0
def handle_closed(n):
print "Closing."
def emit_notification(x, y):
n = pynotify.Notification("X, Y Test",
"This notification should point to %d, %d." % (x, y))
n.set_hint("x", x)
n.set_hint("y", y)
n.connect('closed', handle_closed)
n.show()
def popup_random_bubble():
display = gtk.gdk.display_get_default()
screen = display.get_default_screen()
screen_x2 = screen.get_width() - 1
screen_y2 = screen.get_height() - 1
x = random.randint(0, screen_x2)
y = random.randint(0, screen_y2)
emit_notification(x, y)
return True
if __name__ == '__main__':
if not pynotify.init("XY Stress"):
sys.exit(1)
gobject.timeout_add(1000, popup_random_bubble)
gtk.main()
我跑了这个,发现这里的回调也不会发生。
这可能只是我的系统,还是pynotify或libnotify中有错误?如果现在这个问题无法解决,那么上面的选项1是什么呢?有什么方法可以做到这一点吗?
我似乎有libnotify 0.4.5和pynotify 0.1.1。
答案 0 :(得分:2)
我一直在寻找同样的事情。我发现有人使用gobject.MainLoop而不是gtk.main来帮助:linuxquestions.org。
我发现这对我有用:
#!/usr/bin/python
import pynotify
import gobject
def OnClicked(notification, signal_text):
print '1: ' + str(notification)
print '2: ' + str(signal_text)
notification.close()
global loop
loop.quit()
def OnClosed(notification):
print 'Ignoring fire'
notification.close()
global loop
loop.quit()
def Main():
pynotify.init('ProgramName')
global loop
loop = gobject.MainLoop()
notify = pynotify.Notification('Fire!', 'I\'m just kidding...')
# optionalm, just changes notification color
notify.set_urgency(pynotify.URGENCY_CRITICAL)
# optional, it will expire eventually
notify.set_timeout(pynotify.EXPIRES_NEVER)
notify.add_action('You Clicked The Button', 'Remove Fire', OnClicked)
notify.connect("closed",OnClosed)
notify.show()
loop.run()
if __name__ == '__main__':
Main()
答案 1 :(得分:0)
尝试以下方法:
添加:
from time import sleep
并在您的emit_notification结束时:
sleep(2)
n.close()
(与OP讨论后更新:) 这应该会激活你的回调!这样,如果您的DBus-Server执行了它应该执行的操作,您可以与dbus-monitor一起进行测试。 (来自OP的想法。)
这仍然不是你真正想要的,但暂时至少解释了你对未发出信号的困惑。
你可能应该研究的是动作属性。我找到了一些有趣的东西here。您似乎可以直接在通知中与用户进行互动。
因为pynotify只是DBus通信的包装器,所以您也可以尝试一种解决方法:
from dbus import SessionBus, Interface
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
notify_busname = 'org.freedesktop.Notifications'
notify_obj_path ='/org/freedesktop/Notifications'
lbus = SessionBus()
notify_server = lbus.get_object(notify_busname, notify_obj_path)
并在你的处理程序定义之后:
notify_server.connect_to_signal(None, handle_closed)
我还为测试目的更改了函数的签名以适合DBus信号:
def handle_closed(*arg, **kwargs):