pynotify通知システムを使用してユーザーにアラートを表示し、アラートに配置されたボタンから関連するアプリケーションを起動できるようにする単純なUnixデスクトップアプリケーションを作成しようとしています。
関連する簡略化されたコードは次のとおりです。
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()
しかしもちろん、これは適切な解決策ではなく、「最大再帰深度を超えた」PythonRuntimeErrorがすぐに発生します。ただし、gtk.main()呼び出しの場所を変更することには問題があることを示しています。
メインループに関するGtkとPygtkのドキュメントを調べてみましたが、最終的には解決策が見つかりませんでした。
だから私の質問は:何をするのが適切で、その背後にある論理は何ですか?
TL; DR:通知を表示する同じ関数にgtk.main()を配置しないと、必要なときにaction_callback関数がトリガーされません。この関数はgtkmainloopに配置する必要があるため、gtk mainloopがそれ自体を呼び出すか、action_callback関数がトリガーされないままになります。
助けてくれてありがとう;)