Python 中的跨平台桌面通知程序

发布于 2024-08-21 05:14:50 字数 737 浏览 12 评论 0 原文

我正在寻找类似 Growl 的、类似 Windows 气球提示的 Python 通知库。想象一下编写如下代码:

>>> import desktopnotifier as dn
>>> dn.notify('Title', 'Long description goes here')

.. 并且会在 Mac、Windows 和 Linux 上通过相应的工具提示进行通知。这样的图书馆存在吗?如果没有,我该如何自己写一篇呢?

  • Mac 是否带有默认通知程序? Growl 是我应该单独安装的东西吗?
  • 在 Windows 上,我认为这可能需要 pywin32
  • 在 Linux 上,假设是 GNOME,是否有一个 GNOME API(使用 gnome-python)可以做到这一点?
  • 我可以在所有平台上将通知设置为“粘性”(即永远不会淡出)吗?

更新:我的偏好是依赖 PyQT4 和 wxPython 等庞大的 GUI 框架来完成这样的简单任务。

I am looking for Growl-like, Windows balloon-tip-like notifications library in Python. Imagine writing code like:

>>> import desktopnotifier as dn
>>> dn.notify('Title', 'Long description goes here')

.. and that would notify with corresponding tooltips on Mac, Windows and Linux. Does such a library exist? If not, how would I go about writing one myself?

  • Does Mac come with a default notifier? Is Growl something that I should install separately?
  • On Windows, I assume this may require pywin32?
  • On Linux, assuming GNOME, is there a GNOME API (using gnome-python) that does this?
  • Can I make notifications 'sticky' (i.e., don't fade out ever) on all platforms?

Update: My preference is to not depend on gigantic GUI frameworks like PyQT4 and wxPython for a simple task such as this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

不必你懂 2024-08-28 05:14:50

这是我几年前使用 wxPython 编写的桌面通知程序 - 它在 Windows 和 Linux 上的行为相同,并且也应该在 OSX 上运行。它包含一个线程事件循环,可用于为包含可单击的图标和消息的通知窗口设置动画。它可能需要进行一些调整才能根据您自己的目的进行定制,但基础工作已经完成。

Here's a desktop notifier I wrote a few years ago using wxPython - it behaves identically across Windows and Linux and should also run on OSX. It contains a threaded event loop that can be used to animate a notification window containing an icon and message that can be clicked on. It probably needs a couple of tweaks to customize it for your own purpose but the ground work is done.

神也荒唐 2024-08-28 05:14:50

在 Pycon 2010 上,有一个有关跨平台 Python 开发的演示
还有一个关于它的 html 页面,其中包含一些跨平台通知的建议。不过,我在网上找不到了,但我保存了一份本地副本,这是通知部分:

有时您的应用程序想要通知用户
关于某事:有可用的软件更新、新的即时消息
已收到,300页打印作业终于完成等等

  • 为了使通知易于跨平台移植,请勿
    他们互动。例如Ubuntu不支持通知
    需要用户交互。

  • 以下是最重要的库:

    o Linux:pynotify

    o Mac OS X:咆哮,这不是标准的,通常是
    已安装。

    o Windows:一个好的 wxPython 解决方案是 Andrea 的 ToasterBox
    Gavana,模仿 Firefox 或 Thunderbird 通知的外观。

  • 对于 Phatch,我们开发了一个库来统一这三者
    一个 API 中的系统: phatch/lib/通知.py.

链接的 python 文件非常有趣,我认为您应该能够几乎按原样使用链接的 python 文件。代码也非常清晰,因此您很快就会明白它的作用。

基本方法是它检测哪些通知系统可用,几乎无论平台如何,并尝试按一定顺序使用它们,但如果需要,则退回到更简单的系统。这样,如果用户安装了 Growl,那么无论平台如何,它都会使用它。

您可以对其进行调整,以提供对上述三个通知系统之外的其他通知系统的支持。

At Pycon 2010 there was a presentation on cross-platform Python development.
There was a html page about it as well, containing some advice for cross-platform notification. However, I don't find it online anymore, but I saved a local copy, and this is the part on notifications:

There are occasions in which your application wants to notify the user
about something: software updates are available, a new instant message
have been received, the 300 page print job has finally finished, etc.

  • To keep notifications easy to port cross-platform, don't make
    them interactive. For example Ubuntu does not support notifications
    that require user interaction.

  • These are the most important libraries:

    o Linux: pynotify.

    o Mac OS X: Growl, which is not standard, is usually
    installed.

    o Windows: a good wxPython solution is ToasterBox of Andrea
    Gavana, which mimics the look of Firefox or Thunderbird notifications.

  • For Phatch we developed a library that unifies these three
    systems in one API: phatch/lib/notify.py.

The linked python file is very interesting, and I think you should be able to use the linked python file almost as is. The code is also very clear, so you'll quickly see what it does.

The basic approach is it detects what notification systems are available, almost regardless of the platform, and tries to use them in a certain order but falls back to more simple systems if necessary. This way, if the user has e.g. Growl installed it'll use it, regardless of the platform.

You could adapt it to provide support for other notification systems than the three mentioned above.

围归者 2024-08-28 05:14:50
  • 如何编写它

    检查keyring如何处理跨平台问题(它是一个Python库,可插入各种自动检测的钥匙串后端进行存储)

  • Growl 未与 OSX 捆绑在一起,您必须单独安装它,OSX 不附带任何内置功能- 通知系统。

  • 对于 Unix,您可能想要像已经提到的那样连接到 DBus(作为后备,请注意 dbus 也可能在 OSX 中可用),但是 KDE 和 Gnome 都有类似 Growl 的库。分别是用于 KDE 的 KNotification 和用于 Gnome 的 libnotify。

  • 对于 Windows,请查看 Snarl,如果不可用,则退回到通知气泡(使用类似于 ToasterBox)

永远不要考虑让通知粘性。它很愚蠢,它麻木不仁,而且非常烦人。另外,由于像您这样的人,大多数通知系统都无法使用它。

最后,即使没有任何这些的 Python 库,您也可以使用 ctypes 来访问它们。

  • How to go about writing it

    Check how keyring handles the cross-platform issues (it's a python library which plugs into various autodetected keychain backends for storage)

  • Growl isn't bundled with OSX you have to install it separately, OSX doesn't come with any built-in notification system.

  • For unixes, you might want to hook into DBus as already mentioned (as a fallback, note that dbus might also be available in OSX), but both KDE and Gnome have Growl-like libraries. Respectively, KNotification for KDE and libnotify for Gnome.

  • For windows, check out Snarl, fall back to notification bubbles if not available (using something along the lines of ToasterBox)

Do not ever even think of making notifications sticky. It's stupid, it's insensitive and it's freaking annoying. Also, due to people like you it's been made not available in most notification systems.

Finally, even if there is no Python lib for any of these, you can probably use ctypes to access them.

漫雪独思 2024-08-28 05:14:50

如果您不关心大小,请尝试 PyQt4

这是这项工作的课程:
http://doc.trolltech.com/4.5/qsystemtrayicon.html

try PyQt4, if you don't care about the size.

here is the class for this job:
http://doc.trolltech.com/4.5/qsystemtrayicon.html

花辞树 2024-08-28 05:14:50

听起来你需要 Growl for Windows

Sounds like you need Growl for Windows

白况 2024-08-28 05:14:50

这是对我有用的简单方法。 Toast 停留 2 秒然后消失。是的,OP 不想要“巨大的”PyQt4,但这可能对其他人有用。

import sys, time
from PyQt4 import QtCore, QtGui
import uiToast

window = None   # global

# Usage: Toast('Message')
class Toast(QtGui.QMainWindow):
    def __init__(self, msg):
        global window               # some space outside the local stack
        window = self               # save pointer till killed to avoid GC
        QtGui.QWidget.__init__(self)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.ui = uiToast.Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.display.setText(msg)

        self.toastThread = ToastThread()    # start thread to remove display
        self.connect(self.toastThread, QtCore.SIGNAL("finished()"), self.toastDone)
        self.toastThread.start()
        self.show()

    def toastDone(self):
        global window
        window = None               # kill pointer to window object to close it and GC

class ToastThread(QtCore.QThread):
    def __init__(self):
        QtCore.QThread.__init__(self)

    def run(self):
        time.sleep(2.0)             # wait and die

pyuic4 创建的精简文件“uiToast.py”是:

from PyQt4 import QtCore, QtGui
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.resize(547, 96)
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 170, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
        MainWindow.setPalette(palette)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.display = QtGui.QTextBrowser(self.centralwidget)
        self.display.setGeometry(QtCore.QRect(0, 0, 551, 101))
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(255, 170, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
        self.display.setPalette(palette)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.display.setFont(font)
        MainWindow.setCentralWidget(self.centralwidget)

Here is something simple that works for me. The Toast stays up for 2 secs and disappears. Yes, OP didn't want 'gigantic' PyQt4, but this may be useful to others.

import sys, time
from PyQt4 import QtCore, QtGui
import uiToast

window = None   # global

# Usage: Toast('Message')
class Toast(QtGui.QMainWindow):
    def __init__(self, msg):
        global window               # some space outside the local stack
        window = self               # save pointer till killed to avoid GC
        QtGui.QWidget.__init__(self)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.ui = uiToast.Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.display.setText(msg)

        self.toastThread = ToastThread()    # start thread to remove display
        self.connect(self.toastThread, QtCore.SIGNAL("finished()"), self.toastDone)
        self.toastThread.start()
        self.show()

    def toastDone(self):
        global window
        window = None               # kill pointer to window object to close it and GC

class ToastThread(QtCore.QThread):
    def __init__(self):
        QtCore.QThread.__init__(self)

    def run(self):
        time.sleep(2.0)             # wait and die

The trimmed down file 'uiToast.py' created by pyuic4 is:

from PyQt4 import QtCore, QtGui
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.resize(547, 96)
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 170, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
        MainWindow.setPalette(palette)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.display = QtGui.QTextBrowser(self.centralwidget)
        self.display.setGeometry(QtCore.QRect(0, 0, 551, 101))
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(255, 170, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
        self.display.setPalette(palette)
        font = QtGui.QFont()
        font.setPointSize(12)
        self.display.setFont(font)
        MainWindow.setCentralWidget(self.centralwidget)
帝王念 2024-08-28 05:14:50

为了获得良好的跨平台支持,我会查看 PyQt。它会给你的图书馆增加一些分量,但他们已经很好地解决了大部分问题。

For good cross-platform support, I would look at PyQt. It will add some heft to your library, but they've done a good job working out most of the kinks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文