我想做一個簡單的Unix桌面應用程序,它使用pynotify通知系統向用戶顯示一些警報,並允許他們從放置在警報上的按鈕啓動相關應用程序。回調和gtk主循環
下面是相關簡化代碼:
import subprocess, pynotify, gobject, gtk
class Notifier():
def __init__(self):
pynotify.init('Notifications')
n = pynotify.Notification("Some stuff")
n.add_action("action", "Action", self.action_callback)
n.show()
gtk.main()
def action_callback(self, n, action):
subprocess.Popen(['ls', '/'])
if __name__ == '__main__':
Notifier()
這工作正常(它顯示了一個「動作」按鈕,觸發LS /啓動時通知彈出),直到我真正嘗試把通知部分成一個循環(我需要定期輪詢服務器以獲取通知然後顯示)。
我已經試過這樣:
import subprocess, pynotify, gobject, gtk
class Notifier():
def __init__(self):
pynotify.init('Notifications')
gobject.timeout_add(0, self.main)
gtk.main()
def action_callback(self, n, action):
subprocess.Popen(['ls', '/'])
def main(self):
n = pynotify.Notification("Some stuff")
n.add_action("action", "Action", self.action_callback)
n.show()
gobject.timeout_add(10000, self.main)
if __name__ == '__main__':
Notifier()
但由於某種原因在「操作」按鈕,單擊時「action_callback」功能不叫了。
看來這是我使用Gtk主循環的一個問題。做這樣的事情,使功能實際上被觸發:
import subprocess, pynotify, gobject, gtk
class Notifier():
def __init__(self):
pynotify.init('Notifications')
self.main()
def action_callback(self, n, action):
subprocess.Popen(['ls', '/'])
def main(self):
n = pynotify.Notification("Some stuff")
n.add_action("action", "Action", self.action_callback)
n.show()
gobject.timeout_add(10000, self.main)
gtk.main()
if __name__ == '__main__':
Notifier()
但當然,這是沒有妥善的解決辦法,我很快得到一個「最大遞歸深度超標」的Python RuntimeError。但是它表明更改gtk.main()調用的地方有一個問題。
我試着看看有關主循環的Gtk和Pygtk文檔,但最終沒有找到解決方案。
所以我的問題是:什麼是正確的做法,它背後的邏輯是什麼?
TL; DR:如果我沒有將gtk.main()放在顯示通知的相同函數中,則action_callback函數在它應該時不觸發。由於這個函數需要放在gtk主循環中,所以我被困在了調用自身的gtk主循環或action_callback函數未被觸發的地方。
預先感謝任何幫助;)
gtk.main是一個阻塞調用,在函數中遞歸調用它並不是一個好主意!爲了不添加self.main作爲超時函數,爲什麼不添加代碼來輪詢服務器?不幸的是,我不知道關於pynotify或python):... – 2012-01-04 17:13:46
把輪詢代碼放在它自己的函數中並不能解決問題,因爲通知的東西需要在每個服務器輪詢後立即調用,並且它不能分開來自gtk主循環調用。我想我需要的是一種在未啓動gtk.main()的同一功能中設置回調的方法。我甚至不明白爲什麼從我稱之爲gtk.main()的地方產生影響。 – gentledevil 2012-01-05 16:16:12