- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试制作一个简单的 Unix 桌面应用程序,它使用 pynotify 通知系统向用户显示一些警报,并允许他们通过放置在警报上的按钮启动相关应用程序。
这里是相关的简化代码:
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 函数。
在此先感谢您的帮助;)
最佳答案
这里的问题是 pynotify 有一个错误,在未引用的对象上有回调。在您的第一个代码段中,当 main()
函数退出时, n
未被引用(假设在 cPython 中进行引用计数)。不幸的是,这意味着通知对象被销毁,并且不会调用操作(尽管您的通知守护程序仍会显示通知)。
解决方法是保留对该通知的引用。最简单的做法是获取第一个代码段并将 n = pynotify.Notification
更改为 self.last_notification = n = pynotify.Notication
。
如果您有多个通知,您需要将它们放入列表或集合中,但是您需要确保它们被删除,无论是在触发操作的情况下还是在超时时到期。
关于python - 回调和 gtk 主循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8727937/
我参加了一些类(class)并阅读了 YAGNI 的用途。但是,作为一个整体,这个原则从来没有让我满意。它引入了一个逻辑悖论。 作为一个假设,您正在设计一个打算向前扩展的框架。 YAGNI(可能还有
我是一名优秀的程序员,十分优秀!