快速简单:trayicon 与 python?

发布于 2024-11-16 03:05:23 字数 178 浏览 9 评论 0 原文

我只需要一个关于如何轻松地将 python 图标放在系统托盘上的快速示例。这意味着:我运行程序,没有显示窗口,只有一个托盘图标(我有一个 png 文件)显示在系统托盘中,当我右键单击它时,会出现一个带有一些选项的菜单(当我单击在一个选项上,运行一个函数)。 这可能吗?我根本不需要任何窗口...

示例/代码片段非常感谢! :D

I'd just need a quick example on how to easily put an icon with python on my systray. This means: I run the program, no window shows up, just a tray icon (I've got a png file) shows up in the systray and when I right-click on it a menu appears with some options (and when I click on an option, a function is run).
Is that possible? I don't need any window at all...

Examples / code snippets are REALLY appreciated! :D

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

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

发布评论

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

评论(9

像你 2024-11-23 03:05:23

对于 Windows 和侏儒

来吧! wxPython 是炸弹。改编自我的 Feed Notifier 应用程序的源代码。

import wx

TRAY_TOOLTIP = 'System Tray Demo'
TRAY_ICON = 'icon.png'


def create_menu_item(menu, label, func):
    item = wx.MenuItem(menu, -1, label)
    menu.Bind(wx.EVT_MENU, func, id=item.GetId())
    menu.AppendItem(item)
    return item


class TaskBarIcon(wx.TaskBarIcon):
    def __init__(self):
        super(TaskBarIcon, self).__init__()
        self.set_icon(TRAY_ICON)
        self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)

    def CreatePopupMenu(self):
        menu = wx.Menu()
        create_menu_item(menu, 'Say Hello', self.on_hello)
        menu.AppendSeparator()
        create_menu_item(menu, 'Exit', self.on_exit)
        return menu

    def set_icon(self, path):
        icon = wx.IconFromBitmap(wx.Bitmap(path))
        self.SetIcon(icon, TRAY_TOOLTIP)

    def on_left_down(self, event):
        print 'Tray icon was left-clicked.'

    def on_hello(self, event):
        print 'Hello, world!'

    def on_exit(self, event):
        wx.CallAfter(self.Destroy)


def main():
    app = wx.PySimpleApp()
    TaskBarIcon()
    app.MainLoop()


if __name__ == '__main__':
    main()

For Windows & Gnome

Here ya go! wxPython is the bomb. Adapted from the source of my Feed Notifier application.

import wx

TRAY_TOOLTIP = 'System Tray Demo'
TRAY_ICON = 'icon.png'


def create_menu_item(menu, label, func):
    item = wx.MenuItem(menu, -1, label)
    menu.Bind(wx.EVT_MENU, func, id=item.GetId())
    menu.AppendItem(item)
    return item


class TaskBarIcon(wx.TaskBarIcon):
    def __init__(self):
        super(TaskBarIcon, self).__init__()
        self.set_icon(TRAY_ICON)
        self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)

    def CreatePopupMenu(self):
        menu = wx.Menu()
        create_menu_item(menu, 'Say Hello', self.on_hello)
        menu.AppendSeparator()
        create_menu_item(menu, 'Exit', self.on_exit)
        return menu

    def set_icon(self, path):
        icon = wx.IconFromBitmap(wx.Bitmap(path))
        self.SetIcon(icon, TRAY_TOOLTIP)

    def on_left_down(self, event):
        print 'Tray icon was left-clicked.'

    def on_hello(self, event):
        print 'Hello, world!'

    def on_exit(self, event):
        wx.CallAfter(self.Destroy)


def main():
    app = wx.PySimpleApp()
    TaskBarIcon()
    app.MainLoop()


if __name__ == '__main__':
    main()
三生一梦 2024-11-23 03:05:23

2018版

import wx.adv
import wx
TRAY_TOOLTIP = 'Name' 
TRAY_ICON = 'icon.png' 


def create_menu_item(menu, label, func):
    item = wx.MenuItem(menu, -1, label)
    menu.Bind(wx.EVT_MENU, func, id=item.GetId())
    menu.Append(item)
    return item


class TaskBarIcon(wx.adv.TaskBarIcon):
    def __init__(self, frame):
        self.frame = frame
        super(TaskBarIcon, self).__init__()
        self.set_icon(TRAY_ICON)
        self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)

    def CreatePopupMenu(self):
        menu = wx.Menu()
        create_menu_item(menu, 'Site', self.on_hello)
        menu.AppendSeparator()
        create_menu_item(menu, 'Exit', self.on_exit)
        return menu

    def set_icon(self, path):
        icon = wx.Icon(path)
        self.SetIcon(icon, TRAY_TOOLTIP)

    def on_left_down(self, event):      
        print ('Tray icon was left-clicked.')

    def on_hello(self, event):
        print ('Hello, world!')

    def on_exit(self, event):
        wx.CallAfter(self.Destroy)
        self.frame.Close()

class App(wx.App):
    def OnInit(self):
        frame=wx.Frame(None)
        self.SetTopWindow(frame)
        TaskBarIcon(frame)
        return True

def main():
    app = App(False)
    app.MainLoop()


if __name__ == '__main__':
    main()

2018 version

import wx.adv
import wx
TRAY_TOOLTIP = 'Name' 
TRAY_ICON = 'icon.png' 


def create_menu_item(menu, label, func):
    item = wx.MenuItem(menu, -1, label)
    menu.Bind(wx.EVT_MENU, func, id=item.GetId())
    menu.Append(item)
    return item


class TaskBarIcon(wx.adv.TaskBarIcon):
    def __init__(self, frame):
        self.frame = frame
        super(TaskBarIcon, self).__init__()
        self.set_icon(TRAY_ICON)
        self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)

    def CreatePopupMenu(self):
        menu = wx.Menu()
        create_menu_item(menu, 'Site', self.on_hello)
        menu.AppendSeparator()
        create_menu_item(menu, 'Exit', self.on_exit)
        return menu

    def set_icon(self, path):
        icon = wx.Icon(path)
        self.SetIcon(icon, TRAY_TOOLTIP)

    def on_left_down(self, event):      
        print ('Tray icon was left-clicked.')

    def on_hello(self, event):
        print ('Hello, world!')

    def on_exit(self, event):
        wx.CallAfter(self.Destroy)
        self.frame.Close()

class App(wx.App):
    def OnInit(self):
        frame=wx.Frame(None)
        self.SetTopWindow(frame)
        TaskBarIcon(frame)
        return True

def main():
    app = App(False)
    app.MainLoop()


if __name__ == '__main__':
    main()
沫雨熙 2024-11-23 03:05:23

wx.PySimpleApp 已弃用,以下是如何使用 wx.App 代替

我花了一些时间才弄清楚这一点,所以我想我会分享。 wx.PySimpleApp 在 wxPython 2.9 及更高版本中已弃用。这是 FogleBird 的原始脚本,使用 wx.App 代替。

import wx

TRAY_TOOLTIP = 'System Tray Demo'
TRAY_ICON = 'icon.png'

def create_menu_item(menu, label, func):
    item = wx.MenuItem(menu, -1, label)
    menu.Bind(wx.EVT_MENU, func, id=item.GetId())
    menu.AppendItem(item)
    return item

class TaskBarIcon(wx.TaskBarIcon):
    def __init__(self, frame):
        self.frame = frame
        super(TaskBarIcon, self).__init__()
        self.set_icon(TRAY_ICON)
        self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)

    def CreatePopupMenu(self):
        menu = wx.Menu()
        create_menu_item(menu, 'Say Hello', self.on_hello)
        menu.AppendSeparator()
        create_menu_item(menu, 'Exit', self.on_exit)
        return menu

    def set_icon(self, path):
        icon = wx.IconFromBitmap(wx.Bitmap(path))
        self.SetIcon(icon, TRAY_TOOLTIP)

    def on_left_down(self, event):
        print 'Tray icon was left-clicked.'

    def on_hello(self, event):
        print 'Hello, world!'

    def on_exit(self, event):
        wx.CallAfter(self.Destroy)
        self.frame.Close()

class App(wx.App):
    def OnInit(self):
        frame=wx.Frame(None)
        self.SetTopWindow(frame)
        TaskBarIcon(frame)
        return True

def main():
    app = App(False)
    app.MainLoop()


if __name__ == '__main__':
    main()

wx.PySimpleApp deprecated, here's how to use wx.App instead

Took me while to figure this out so I thought I'd share. wx.PySimpleApp is deprecated in wxPython 2.9 and beyond. Here's FogleBird's original script using wx.App instead.

import wx

TRAY_TOOLTIP = 'System Tray Demo'
TRAY_ICON = 'icon.png'

def create_menu_item(menu, label, func):
    item = wx.MenuItem(menu, -1, label)
    menu.Bind(wx.EVT_MENU, func, id=item.GetId())
    menu.AppendItem(item)
    return item

class TaskBarIcon(wx.TaskBarIcon):
    def __init__(self, frame):
        self.frame = frame
        super(TaskBarIcon, self).__init__()
        self.set_icon(TRAY_ICON)
        self.Bind(wx.EVT_TASKBAR_LEFT_DOWN, self.on_left_down)

    def CreatePopupMenu(self):
        menu = wx.Menu()
        create_menu_item(menu, 'Say Hello', self.on_hello)
        menu.AppendSeparator()
        create_menu_item(menu, 'Exit', self.on_exit)
        return menu

    def set_icon(self, path):
        icon = wx.IconFromBitmap(wx.Bitmap(path))
        self.SetIcon(icon, TRAY_TOOLTIP)

    def on_left_down(self, event):
        print 'Tray icon was left-clicked.'

    def on_hello(self, event):
        print 'Hello, world!'

    def on_exit(self, event):
        wx.CallAfter(self.Destroy)
        self.frame.Close()

class App(wx.App):
    def OnInit(self):
        frame=wx.Frame(None)
        self.SetTopWindow(frame)
        TaskBarIcon(frame)
        return True

def main():
    app = App(False)
    app.MainLoop()


if __name__ == '__main__':
    main()
甜心小果奶 2024-11-23 03:05:23

如果你能保证windows并且不想引入wx的重度依赖,你可以使用pywin32 扩展

另请参阅此问题

If you can guarantee windows and you do not want to introduce the heavy dependencies of wx, you can do this with the pywin32 extensions.

Also see this question.

预谋 2024-11-23 03:05:23

对于 Ubuntu

class TrayIcon:
    def init():


iconPath = {"Windows":os.path.expandvars("%PROGRAMFILES%/MyProgram/icon.png"),
                  "Linux":"/usr/share/icons/myprogramicon.png"}        
    if platform.system()=="Linux":
        import gtk
        import appindicator # Ubuntu apt-get install python-appindicator 

    # Create an application indicator
    try:
        gtk.gdk.threads_init()
        gtk.threads_enter()
        icon = iconPath[platform.system()]
        indicator = appindicator.Indicator("example-simple-client", "indicator-messages", appindicator.CATEGORY_APPLICATION_STATUS)
        indicator.set_icon(icon)
        indicator.set_status (appindicator.STATUS_ACTIVE)
        indicator.set_attention_icon ("indicator-messages-new")
        menu = gtk.Menu()

        menuTitle = "Quit"   
        menu_items = gtk.MenuItem(menuTitle)
        menu.append(menu_items)
        menu_items.connect("activate", TrayIcon.QuitApp, menuTitle)
        menu_items.show()

        menuTitle = "About My Program"
        menu_items = gtk.MenuItem(menuTitle)
        menu.append(menu_items)
        menu_items.connect("activate", TrayIcon.AboutApp, menuTitle)
        menu_items.show()   

        indicator.set_menu(menu)    
    except:
        pass

    # Run the app indicator on the main thread.
    try:

        t = threading.Thread(target=gtk.main)
        t.daemon = True # this means it'll die when the program dies.
        t.start()
        #gtk.main()

    except:
        pass
    finally:
        gtk.threads_leave()     

@staticmethod
def AboutApp(a1,a2):
    gtk.threads_enter()
    dialog = gtk.Dialog("About",
                        None,
                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                        (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
    label = gtk.Label("My Program v0.0.1, (C)opyright ME 2015. All rights reserved.")
    dialog.vbox.pack_start(label)
    label.show()
    label2 = gtk.Label("example.com\n\nFor more support contact [email protected]")
    label2.show()
    dialog.action_area.pack_end(label2)
    response = dialog.run()
    dialog.destroy()
    gtk.threads_leave()

@staticmethod
def QuitApp(a1, a2):
    sys.exit(0)

跨平台,

请参阅 PyQt:在系统托盘应用程序中显示菜单< /a>

For Ubuntu

class TrayIcon:
    def init():


iconPath = {"Windows":os.path.expandvars("%PROGRAMFILES%/MyProgram/icon.png"),
                  "Linux":"/usr/share/icons/myprogramicon.png"}        
    if platform.system()=="Linux":
        import gtk
        import appindicator # Ubuntu apt-get install python-appindicator 

    # Create an application indicator
    try:
        gtk.gdk.threads_init()
        gtk.threads_enter()
        icon = iconPath[platform.system()]
        indicator = appindicator.Indicator("example-simple-client", "indicator-messages", appindicator.CATEGORY_APPLICATION_STATUS)
        indicator.set_icon(icon)
        indicator.set_status (appindicator.STATUS_ACTIVE)
        indicator.set_attention_icon ("indicator-messages-new")
        menu = gtk.Menu()

        menuTitle = "Quit"   
        menu_items = gtk.MenuItem(menuTitle)
        menu.append(menu_items)
        menu_items.connect("activate", TrayIcon.QuitApp, menuTitle)
        menu_items.show()

        menuTitle = "About My Program"
        menu_items = gtk.MenuItem(menuTitle)
        menu.append(menu_items)
        menu_items.connect("activate", TrayIcon.AboutApp, menuTitle)
        menu_items.show()   

        indicator.set_menu(menu)    
    except:
        pass

    # Run the app indicator on the main thread.
    try:

        t = threading.Thread(target=gtk.main)
        t.daemon = True # this means it'll die when the program dies.
        t.start()
        #gtk.main()

    except:
        pass
    finally:
        gtk.threads_leave()     

@staticmethod
def AboutApp(a1,a2):
    gtk.threads_enter()
    dialog = gtk.Dialog("About",
                        None,
                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                        (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
    label = gtk.Label("My Program v0.0.1, (C)opyright ME 2015. All rights reserved.")
    dialog.vbox.pack_start(label)
    label.show()
    label2 = gtk.Label("example.com\n\nFor more support contact [email protected]")
    label2.show()
    dialog.action_area.pack_end(label2)
    response = dialog.run()
    dialog.destroy()
    gtk.threads_leave()

@staticmethod
def QuitApp(a1, a2):
    sys.exit(0)

Cross-Platform

See PyQt: Show menu in a system tray application

半窗疏影 2024-11-23 03:05:23

有一个名为 pystray 的包(名字不好,大声说出来),但它的作用就像一个魅力,并且比 wx 或 Qt 更轻量。这些是链接:

https://pystray.readthedocs.io/en/latest/index .html
https://pypi.org/project/pystray/

There is a package called pystray (bad name, just say it out loud) but works like a charm and is more lightweight than wx or Qt. These are the links:

https://pystray.readthedocs.io/en/latest/index.html
https://pypi.org/project/pystray/

桃扇骨 2024-11-23 03:05:23

是的。 wiki.wxpython.org 上有一个跨平台示例,我已在 macOS High Sierra (10.13.3)、Windows 7 和 gnome 3/centos7 上使用 python 2.7(minconda 安装)进行了测试。它在这里(忽略页面标题):
https://wiki.wxpython.org/Custom%20Mac%20OsX% 20Dock%20Bar%20Icon

python 3.6需要小mod:

  • 你必须导入wx.adv
  • wx.TaskBarIcon 变为 wx.adv.TaskBarIcon
  • wx.IconFromBitmap 变为 wx.Icon

Gnome 3 需要安装 TopIcons Plus。

由于您不想显示窗口(“没有窗口显示,只是一个托盘图标”),只需注释掉以下行(尽管您仍然想保留 wx.Frame 父级)

frame.Show(True)

:使用您自己的 .png 图标,删除 WXPdemo 图像和嵌入图像内容并替换

icon = self.MakeIcon(WXPdemo.GetImage())

为,例如

icon = wx.Icon('icon.png')

根据我的经验,这将为进一步调整或扩展提供良好的开端。

Yes. There is a cross-platform example on wiki.wxpython.org that I've tested with python 2.7 (minconda install) on macOS High Sierra (10.13.3), Windows 7, and gnome 3/centos7. It is here (ignore the page title):
https://wiki.wxpython.org/Custom%20Mac%20OsX%20Dock%20Bar%20Icon

Small mods are needed for python 3.6:

  • you must import wx.adv
  • wx.TaskBarIcon becomes wx.adv.TaskBarIcon
  • wx.IconFromBitmap becomes wx.Icon

Gnome 3 required installation of TopIcons Plus.

Since you don't want to have the window display (" no window shows up, just a tray icon"), simply comment out the following line (though you still want to keep the wx.Frame parent):

frame.Show(True)

And since you want to use your own .png icon, remove the WXPdemo image and embeddedimage stuff and replace

icon = self.MakeIcon(WXPdemo.GetImage())

with, for example

icon = wx.Icon('icon.png')

In my experience, this will provide a good start for adapting or extending further.

宛菡 2024-11-23 03:05:23

如果您尝试在后台运行基于 python 的程序,则另一种选择是可以将其作为服务运行。看看这个活跃状态配方,它非常有用。我相信选项之一是使用 py2exe 或 pyinstall 将应用程序转换为 exe。

http://code.activestate.com/recipes/551780/

An alternative if you are trying to run a python based program in the background you can run it as a service. Check out this active state recipe its pretty useful. I believe one of the options is to convert your application to exe with py2exe or pyinstall.

http://code.activestate.com/recipes/551780/

小红帽 2024-11-23 03:05:23

有关示例,请参阅此线程 -> wx 问题。

wxPython“经典”-> ; [新API] wxPython“凤凰”(Py3)

For an example, refer to this thread -> wx question.

wxPython "classic" -> [new API] wxPython 'Phoenix' (Py3)

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