当前位置: 首页 > 知识库问答 >
问题:

如何将系统托盘添加到我的tkinter应用程序中并避免使用大量pywin32代码(仅在windows上)?

浦修文
2023-03-14

我找到了三种制作系统托盘的方法:

  1. Tkinter:如何制作系统托盘应用程序?这个答案有点抽象,尤其是我们没有学习tcl。
  2. 如何为Windows构建SystemTray应用程序?被接受的答案使用了很多pywin32代码,看起来有点乏味。
  3. 另一个回答提到了infi.systraypystray。我发现他们需要使用一些额外的线程来通过查找文档来创建系统托盘。但是参考"所有Tcl命令都需要来自同一个线程",我认为在其他线程中调用. deconify()不是一个好的做法。

有人能给我举一个不使用额外线程的使用winico或其他东西的简单例子吗?

共有1个答案

史劲
2023-03-14

具有Winico的解决方案:

GIF图像示例:https://imgur.com/a/vulO6Mo

你应该先下载。

下载:32位,64位(有点难找到,我终于在谷歌深处找到了。只需在网站上下载pkg,并将其重命名为Winico就可以了。)

下载后,需要将其移动到your PythonPath/tcl

如何使用它制作带有Winico系统托盘?

一个简单的例子:

import tkinter as tk
from tkinter import messagebox

class App(tk.Tk):
    def __init__(self):
        super(App, self).__init__()
        self.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.trayMenu = None

    def on_closing(self):
        if not self.trayMenu: # when system tray is not exists.
            selection = messagebox.askyesnocancel("Tips", "Quit directly?\nYes : Quit.\nNo:Minimize to system tray.")  # "Yes" will return True, "Cancel" will return None, "No" will return False.
            if selection: # when select yes, quit the app directly.
                self.destroy()
            elif selection == False: # Minimize to system tray.
                # make a system tray
                self.withdraw()
                # use bulitin tk.Menu

                # The work about "Winico"
                self.tk.call('package', 'require', 'Winico') # use the tcl "winico", make sure the folder of "winico" is in the same path.
                icon = self.tk.call('winico', 'createfrom', '2.ico') # this is the icon on the system tray.
                self.tk.call('winico', 'taskbar', 'add', icon, # set the icon
                            '-callback', (self.register(self.menu_func), '%m', '%x', '%y'), # refer to winico documentation.
                            '-pos', 0,
                            '-text', u'jizhihaoSAMA’s Tool') # the hover text of the system tray.

                # About menu
                self.trayMenu = tk.Menu(self, tearoff=False)
                self.trayMenu.add_command(label="Show my app", command=self.deiconify)

                # You could also add a cascade menu
                cascadeMenu = tk.Menu(self, tearoff=False)
                cascadeMenu.add_command(label="Casacde one", command=lambda :print("You could define it by yourself"))
                cascadeMenu.add_command(label="Cascade two")
                self.trayMenu.add_cascade(label="Other", menu=cascadeMenu)

                self.trayMenu.add_separator() # you could add a separator

                self.trayMenu.add_command(label="Quit", command=self.destroy)

                # you could also add_command or add_checkbutton for what you want
            else: # This is cancel operation
                pass
        else:
            self.withdraw() # when system tray exists, hide the window directly.

    def menu_func(self, event, x, y):
        if event == 'WM_RBUTTONDOWN': # Mouse event, Right click on the tray.Mostly we will show it.
            self.trayMenu.tk_popup(x, y) # pop it up on this postion
        if event == 'WM_LBUTTONDOWN': # Mouse event, Left click on the tray,Mostly we will show the menu.
            self.deiconify() # show it.
        # All the Mouse event:

        # WM_MOUSEMOVE
        # WM_LBUTTONDOWN
        # WM_LBUTTONUP
        # WM_LBUTTONDBLCLK
        # WM_RBUTTONDOWN
        # WM_RBUTTONUP
        # WM_RBUTTONDBLCLK
        # WM_MBUTTONDOWN
        # WM_MBUTTONUP
        # WM_MBUTTONDBLCLK

app = App()
app.mainloop()

当我想使用Pyinstaller打包它时,我应该怎么做?

在等级库文件中:

a = Analysis(['script.py'],
             pathex=['xxxx'],
             binaries=[],
             datas=[('Winico', 'winico')], # You need to revise this
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)

或者只是做:

pyinstaller -F --add-data "Winico;winico" script.py

参考一篇中文博客,我给博客作者发电子邮件,并从他那里得到一些帮助。

不确定它是否可以在Linux或Unix上工作。

 类似资料:
  • 问题内容: 我有一个小控制面板,只是我做的一个小应用程序。我想最小化/使用系统图标上下控制面板,以及电池寿命,日期,网络等。 有人可以给我一个提示,链接到教程或阅读的东西吗? 问题答案: 从Java 6开始,and 类支持此功能。在Javadocs中有一个非常广泛的示例: 您也可以查看本文或此技术提示。

  • 我有windows 8.1操作系统。我已经安装了cordova、android sdk、java sdk和apache Ant。我可以创建一个cordova应用程序,但当我尝试使用这个命令“**cordova platform add Android”。我有这个错误:错误:运行“Android”失败。确保您安装了最新的Android SDK,并且“Android”命令(在工具/文件夹中)被添加到您

  • 我想在我的应用程序中添加带有,但一旦我将插件添加到我的应用程序中。yaml,我的应用程序不再运行。下面是错误 失败:生成失败,出现异常。 > 错误:任务执行失败:app:transformDexArchiveWithExternalLibsDexMergerForDebug'。 通用域名格式。Android建设者德兴。DexArchiveMergerException:合并dex存档时出错:/Us

  • 我在Android上尝试了以下内容: 从Firebase控制台发送通知:只有当应用程序位于后台时,我才能在系统托盘中看到通知。 将post请求发送到(如本文所述),同时使用和Paylods:同样,我只能在应用程序位于后台时在系统托盘中看到通知。 该文件提到: 我用的是Android和Cordova/Ionic。

  • 我们正在使用spring Cloud对微服务(基于Spring Boot)进行外部化配置。 根据我对Spring Cloud的理解,要启用从配置服务器加载刷新/更新值的bean,我们需要在Spring Cloud客户机中做两件事: null 如何避免在所有这些类上添加注释。是否有任何捷径或spring cloud特性来绕过这种情况。

  • 如何添加图像并将其设置为我的应用程序背景 我知道你把你想要的图片粘贴到了drawable文件夹中。这是代码本身的问题,还是我应该创建一个RelativeLayout?或者仅仅是提供的代码中的一行更改? 这是我的代码,没有任何改动。