私は、pynotify通知システムを使用してユーザーにいくつかの警告を表示し、アラートに配置されたボタンから関連するアプリケーションを起動できるようにする簡単なUnixデスクトップアプリケーションを作成しようとしています。私は実際に通知部を配置しようとするまで(それが活性化されると、LS /をトリガーする「アクション」ボタンで通知ポップアップを示して)これは正常に動作コールバックと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()
:ここ
は、関連する単純化されたコードです(私は定期的にサーバーをポーリングして、通知を表示する必要があります)。
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のmainloopを呼び出すか、action_callback関数がトリガされないようにしています。任意の助けを事前に
おかげで;)
gtk.mainはブロッキング呼び出しですが、関数内で再帰的に呼び出すことはお勧めできません。タイムアウト機能としてself.mainを追加するのではなく、サーバーをポーリングするコードを追加するのはなぜですか?残念ながら私はpynotifyやpythonについては全く知らない): –
ポーリングコードを独自の関数に入れても問題は解決しない。なぜなら、すべてのサーバーポーリングの後に通知の内容を呼び出す必要があり、それは分離できないからであるgtkのmainloop呼び出しから。私が必要と思われるのは、gtk.main()が起動されているものと同じ関数でセットアップしないと、コールバックを動作させる方法です。私はgtk.main()を呼び出す場所がここに影響を与える理由を理解していません。 – gentledevil