精华内容
下载资源
问答
  • python程序最小化到托盘
    2020-12-18 09:36:09

    #!/usr/bin/env python

    #coding=gb2312

    import os

    import sys

    import win32api

    import win32con

    import win32gui_struct

    import screenshot

    try:

    import winxpgui as win32gui

    except ImportError:

    import win32gui

    class SysTrayIcon(object):

    '''TODO'''

    QUIT = 'QUIT'

    SPECIAL_ACTIONS = [QUIT]

    FIRST_ID = 1023

    def __init__(self,

    icon,

    hover_text,

    menu_options,

    on_quit=None,

    default_menu_index=None,

    window_class_name=None,):

    self.icon = icon

    self.hover_text = hover_text

    self.on_quit = on_quit

    menu_options = menu_options + (('退出', None, self.QUIT),)

    self._next_action_id = self.FIRST_ID

    self.menu_actions_by_id = set()

    self.menu_options = self._add_ids_to_menu_options(list(menu_options))

    self.menu_actions_by_id = dict(self.menu_actions_by_id)

    del self._next_action_id

    self.default_menu_index = (default_menu_index or 0)

    self.window_class_name = window_class_name or "SysTrayIconPy"

    message_map = {win32gui.RegisterWindowMessage("TaskbarCreated"): self.restart,

    win32con.WM_DESTROY: self.destroy,

    win32con.WM_COMMAND: self.command,

    win32con.WM_USER+20 : self.notify,}

    # Register the Window class.

    window_class = win32gui.WNDCLASS()

    hinst = window_class.hInstance = win32gui.GetModuleHandle(None)

    window_class.lpszClassName = self.window_class_name

    window_class.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW;

    window_class.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW)

    window_class.hbrBackground = win32con.COLOR_WINDOW

    window_class.lpfnWndProc = message_map # could also specify a wndproc.

    classAtom = win32gui.RegisterClass(window_class)

    # Create the Window.

    style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU

    self.hwnd = win32gui.CreateWindow(classAtom,

    self.window_class_name,

    style,

    0,

    0,

    win32con.CW_USEDEFAULT,

    win32con.CW_USEDEFAULT,

    0,

    0,

    hinst,

    None)

    win32gui.UpdateWindow(self.hwnd)

    self.notify_id = None

    self.refresh_icon()

    win32gui.PumpMessages()

    def _add_ids_to_menu_options(self, menu_options):

    result = []

    for menu_option in menu_options:

    option_text, option_icon, option_action = menu_option

    if callable(option_action) or option_action in self.SPECIAL_ACTIONS:

    self.menu_actions_by_id.add((self._next_action_id, option_action))

    result.append(menu_option + (self._next_action_id,))

    elif non_string_iterable(option_action):

    result.append((option_text,

    option_icon,

    self._add_ids_to_menu_options(option_action),

    self._next_action_id))

    else:

    print 'Unknown item', option_text, option_icon, option_action

    self._next_action_id += 1

    return result

    def refresh_icon(self):

    # Try and find a custom icon

    hinst = win32gui.GetModuleHandle(None)

    if os.path.isfile(self.icon):

    icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE

    hicon = win32gui.LoadImage(hinst,

    self.icon,

    win32con.IMAGE_ICON,

    0,

    0,

    icon_flags)

    else:

    print "Can't find icon file - using default."

    hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)

    if self.notify_id: message = win32gui.NIM_MODIFY

    else: message = win32gui.NIM_ADD

    self.notify_id = (self.hwnd,

    0,

    win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,

    win32con.WM_USER+20,

    hicon,

    self.hover_text)

    win32gui.Shell_NotifyIcon(message, self.notify_id)

    def restart(self, hwnd, msg, wparam, lparam):

    self.refresh_icon()

    def destroy(self, hwnd, msg, wparam, lparam):

    if self.on_quit: self.on_quit(self)

    nid = (self.hwnd, 0)

    win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)

    win32gui.PostQuitMessage(0) # Terminate the app.

    def notify(self, hwnd, msg, wparam, lparam):

    if lparam==win32con.WM_LBUTTONDBLCLK:

    self.execute_menu_option(self.default_menu_index + self.FIRST_ID)

    elif lparam==win32con.WM_RBUTTONUP:

    self.show_menu()

    elif lparam==win32con.WM_LBUTTONUP:

    pass

    return True

    def show_menu(self):

    menu = win32gui.CreatePopupMenu()

    self.create_menu(menu, self.menu_options)

    #win32gui.SetMenuDefaultItem(menu, 1000, 0)

    pos = win32gui.GetCursorPos()

    # See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp

    win32gui.SetForegroundWindow(self.hwnd)

    win32gui.TrackPopupMenu(menu,

    win32con.TPM_LEFTALIGN,

    pos[0],

    pos[1],

    0,

    self.hwnd,

    None)

    win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0)

    def create_menu(self, menu, menu_options):

    for option_text, option_icon, option_action, option_id in menu_options[::-1]:

    if option_icon:

    option_icon = self.prep_menu_icon(option_icon)

    if option_id in self.menu_actions_by_id:

    item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,

    hbmpItem=option_icon,

    wID=option_id)

    win32gui.InsertMenuItem(menu, 0, 1, item)

    else:

    submenu = win32gui.CreatePopupMenu()

    self.create_menu(submenu, option_action)

    item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,

    hbmpItem=option_icon,

    hSubMenu=submenu)

    win32gui.InsertMenuItem(menu, 0, 1, item)

    def prep_menu_icon(self, icon):

    # First load the icon.

    ico_x = win32api.GetSystemMetrics(win32con.SM_CXSMICON)

    ico_y = win32api.GetSystemMetrics(win32con.SM_CYSMICON)

    hicon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, ico_x, ico_y, win32con.LR_LOADFROMFILE)

    hdcBitmap = win32gui.CreateCompatibleDC(0)

    hdcScreen = win32gui.GetDC(0)

    hbm = win32gui.CreateCompatibleBitmap(hdcScreen, ico_x, ico_y)

    hbmOld = win32gui.SelectObject(hdcBitmap, hbm)

    # Fill the background.

    brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU)

    win32gui.FillRect(hdcBitmap, (0, 0, 16, 16), brush)

    # unclear if brush needs to be feed. Best clue I can find is:

    # "GetSysColorBrush returns a cached brush instead of allocating a new

    # one." - implies no DeleteObject

    # draw the icon

    win32gui.DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL)

    win32gui.SelectObject(hdcBitmap, hbmOld)

    win32gui.DeleteDC(hdcBitmap)

    return hbm

    def command(self, hwnd, msg, wparam, lparam):

    id = win32gui.LOWORD(wparam)

    self.execute_menu_option(id)

    def execute_menu_option(self, id):

    menu_action = self.menu_actions_by_id[id]

    if menu_action == self.QUIT:

    win32gui.DestroyWindow(self.hwnd)

    else:

    menu_action(self)

    def non_string_iterable(obj):

    try:

    iter(obj)

    except TypeError:

    return False

    else:

    return not isinstance(obj, basestring)

    # Minimal self test. You'll need a bunch of ICO files in the current working

    # directory in order for this to work...

    if __name__ == '__main__':

    import itertools, glob

    icons = 'screenshot_tray.ico'

    hover_text = "多功能抓图工具"

    menu_options = (('抓取全屏', icons, screenshot.capture_fullscreen),

    ('抓取当前窗口', icons, screenshot.capture_current_windows),

    ('抓取所选区域', icons, screenshot.capture_choose_windows)

    )

    def bye(sysTrayIcon): print('退出')

    SysTrayIcon(icons, hover_text, menu_options, on_quit=bye)

    #提供快捷键操作

    screenshot.screenshot_main()

    更多相关内容
  • 本文讲解如何装python的开发的命令行程序最小化到托盘的方法,并提供菜单操作功能。上个月使用python实现了一个多功能抓图工具,见《Python:一个多功能的抓图工具开发(附源码)》,此程序为一个命令行程序,windows下...

    本文讲解如何装python的开发的命令行程序最小化到托盘的方法,并提供菜单操作功能。

    上个月使用python实现了一个多功能抓图工具,见《Python:一个多功能的抓图工具开发(附源码)》,此程序为一个命令行程序,windows下运行时会弹出一个cmd窗口,里面什么内容也没有,用户使用时直接按下快捷键进行操作。一直想着优化一下,今天想到是否以通过最小化到托盘,并提供菜单操作和快捷键操作两种方式,这样看起来就有点软件的样子了。

    Google了一下,发现了一个方法,具体内容见本文附录部分。

    直接上实现后的代码:

    1、screenshot.py (此模块提供截图的各种方法,被主程序screen_tray.py引用)

    #!/usr/bin/env python

    #coding=gb2312

    #此模块主要提供抓图功能,支持以下三种抓图方式:

    #1、抓取全屏,快捷键CTRL+F1

    #2、抓取当前窗口,快捷键CTRL+F2

    #3、抓取所选区域,快捷键CTRL+F3

    #抓到之后,会自动弹出保存对话框,选择路径保存即可

    #*******************************************

    #更新记录

    #0.1 2012-03-10 create by dyx1024

    #********************************************

    import pyhk

    import wx

    import os

    import sys

    from PIL import ImageGrab

    import ctypes

    import win32gui

    import ctypes.wintypes

    import screen_tray

    def capture_fullscreen(SysTrayIcon):

    '''

    Function:全屏抓图

    Input:NONE

    Output: NONE

    author: socrates

    blog:http://blog.csdn.net/dyx1024

    date:2012-03-10

    '''

    #抓图

    pic = ImageGrab.grab()

    #保存图片

    save_pic(pic)

    def capture_current_windows(SysTrayIcon):

    '''

    Function:抓取当前窗口

    Input:NONE

    Output: NONE

    author: socrates

    blog:http://blog.csdn.net/dyx1024

    date:2012-03-10

    '''

    #窗口结构

    class RECT(ctypes.Structure):

    _fields_ = [('left', ctypes.c_long),

    ('top', ctypes.c_long),

    ('right', ctypes.c_long),

    ('bottom', ctypes.c_long)]

    def __str__(self):

    return str((self.left, self.top, self.right, self.bottom))

    rect = RECT()

    #获取当前窗口句柄

    HWND = win32gui.GetForegroundWindow()

    #取当前窗口坐标

    ctypes.windll.user32.GetWindowRect(HWND,ctypes.byref(rect))

    #调整坐标

    rangle = (rect.left+2,rect.top+2,rect.right-2,rect.bottom-2)

    #抓图

    pic = ImageGrab.grab(rangle)

    #保存

    save_pic(pic)

    def capture_choose_windows(SysTrayIcon):

    '''

    Function:抓取选择的区域,没有自己写这个,借用QQ抓图功能

    Input:NONE

    Output: NONE

    author: socrates

    blog:http://blog.csdn.net/dyx1024

    date:2012-03-10

    '''

    try:

    #加载QQ抓图使用的dll

    dll_handle = ctypes.cdll.LoadLibrary('CameraDll.dll')

    except Exception:

    try:

    #如果dll加载失败,则换种方法使用,直接运行,如果还失败,退出

    os.system("Rundll32.exe CameraDll.dll, CameraSubArea")

    except Exception:

    return

    else:

    try:

    #加载dll成功,则调用抓图函数,注:没有分析清楚这个函数带的参数个数

    #及类型,所以此语句执行后会报参数缺少4个字节,但不影响抓图功能,所

    #以直接忽略了些异常

    dll_handle.CameraSubArea(0)

    except Exception:

    return

    def save_pic(pic, filename = '未命令图片.png'):

    '''

    Function:使用文件对框,保存图片

    Input:NONE

    Output: NONE

    author: socrates

    blog:http://blog.csdn.net/dyx1024

    date:2012-03-10

    '''

    app = wx.PySimpleApp()

    wildcard = "PNG(*.png)|*.png"

    dialog = wx.FileDialog(None, "Select a place", os.getcwd(),

    filename, wildcard, wx.SAVE)

    if dialog.ShowModal() == wx.ID_OK:

    pic.save(dialog.GetPath().encode('gb2312'))

    else:

    pass

    dialog.Destroy()

    def screenshot_main():

    '''

    Function:主函数,注册快捷键

    Input:NONE

    Output: NONE

    author: socrates

    blog:http://blog.csdn.net/dyx1024

    date:2012-03-10

    '''

    #创建hotkey句柄

    hot_handle = pyhk.pyhk()

    #注册抓取全屏快捷键CTRL+F1

    hot_handle.addHotkey(['Ctrl', 'F1'], capture_fullscreen)

    #注册抓取当前窗口快捷键CTRL+F2

    hot_handle.addHotkey(['Ctrl', 'F2'], capture_current_windows)

    #注册抓取所选区域快捷键CTRL+F3

    hot_handle.addHotkey(['Ctrl', 'F3'], capture_choose_windows)

    #开始运行

    hot_handle.start()

    2、screen_tray.py (此模块为主程序,提供托盘及菜单功能,在各菜单项中调用1中的各函数,最后再调用1中的注册快键键函数,来提供快捷键操作)

    #!/usr/bin/env python

    #coding=gb2312

    import os

    import sys

    import win32api

    import win32con

    import win32gui_struct

    import screenshot

    try:

    import winxpgui as win32gui

    except ImportError:

    import win32gui

    class SysTrayIcon(object):

    '''TODO'''

    QUIT = 'QUIT'

    SPECIAL_ACTIONS = [QUIT]

    FIRST_ID = 1023

    def __init__(self,

    icon,

    hover_text,

    menu_options,

    on_quit=None,

    default_menu_index=None,

    window_class_name=None,):

    self.icon = icon

    self.hover_text = hover_text

    self.on_quit = on_quit

    menu_options = menu_options + (('退出', None, self.QUIT),)

    self._next_action_id = self.FIRST_ID

    self.menu_actions_by_id = set()

    self.menu_options = self._add_ids_to_menu_options(list(menu_options))

    self.menu_actions_by_id = dict(self.menu_actions_by_id)

    del self._next_action_id

    self.default_menu_index = (default_menu_index or 0)

    self.window_class_name = window_class_name or "SysTrayIconPy"

    message_map = {win32gui.RegisterWindowMessage("TaskbarCreated"): self.restart,

    win32con.WM_DESTROY: self.destroy,

    win32con.WM_COMMAND: self.command,

    win32con.WM_USER+20 : self.notify,}

    # Register the Window class.

    window_class = win32gui.WNDCLASS()

    hinst = window_class.hInstance = win32gui.GetModuleHandle(None)

    window_class.lpszClassName = self.window_class_name

    window_class.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW;

    window_class.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW)

    window_class.hbrBackground = win32con.COLOR_WINDOW

    window_class.lpfnWndProc = message_map # could also specify a wndproc.

    classAtom = win32gui.RegisterClass(window_class)

    # Create the Window.

    style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU

    self.hwnd = win32gui.CreateWindow(classAtom,

    self.window_class_name,

    style,

    0,

    0,

    win32con.CW_USEDEFAULT,

    win32con.CW_USEDEFAULT,

    0,

    0,

    hinst,

    None)

    win32gui.UpdateWindow(self.hwnd)

    self.notify_id = None

    self.refresh_icon()

    win32gui.PumpMessages()

    def _add_ids_to_menu_options(self, menu_options):

    result = []

    for menu_option in menu_options:

    option_text, option_icon, option_action = menu_option

    if callable(option_action) or option_action in self.SPECIAL_ACTIONS:

    self.menu_actions_by_id.add((self._next_action_id, option_action))

    result.append(menu_option + (self._next_action_id,))

    elif non_string_iterable(option_action):

    result.append((option_text,

    option_icon,

    self._add_ids_to_menu_options(option_action),

    self._next_action_id))

    else:

    print 'Unknown item', option_text, option_icon, option_action

    self._next_action_id += 1

    return result

    def refresh_icon(self):

    # Try and find a custom icon

    hinst = win32gui.GetModuleHandle(None)

    if os.path.isfile(self.icon):

    icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE

    hicon = win32gui.LoadImage(hinst,

    self.icon,

    win32con.IMAGE_ICON,

    0,

    0,

    icon_flags)

    else:

    print "Can't find icon file - using default."

    hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)

    if self.notify_id: message = win32gui.NIM_MODIFY

    else: message = win32gui.NIM_ADD

    self.notify_id = (self.hwnd,

    0,

    win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,

    win32con.WM_USER+20,

    hicon,

    self.hover_text)

    win32gui.Shell_NotifyIcon(message, self.notify_id)

    def restart(self, hwnd, msg, wparam, lparam):

    self.refresh_icon()

    def destroy(self, hwnd, msg, wparam, lparam):

    if self.on_quit: self.on_quit(self)

    nid = (self.hwnd, 0)

    win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)

    win32gui.PostQuitMessage(0) # Terminate the app.

    def notify(self, hwnd, msg, wparam, lparam):

    if lparam==win32con.WM_LBUTTONDBLCLK:

    self.execute_menu_option(self.default_menu_index + self.FIRST_ID)

    elif lparam==win32con.WM_RBUTTONUP:

    self.show_menu()

    elif lparam==win32con.WM_LBUTTONUP:

    pass

    return True

    def show_menu(self):

    menu = win32gui.CreatePopupMenu()

    self.create_menu(menu, self.menu_options)

    #win32gui.SetMenuDefaultItem(menu, 1000, 0)

    pos = win32gui.GetCursorPos()

    # See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp

    win32gui.SetForegroundWindow(self.hwnd)

    win32gui.TrackPopupMenu(menu,

    win32con.TPM_LEFTALIGN,

    pos[0],

    pos[1],

    0,

    self.hwnd,

    None)

    win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0)

    def create_menu(self, menu, menu_options):

    for option_text, option_icon, option_action, option_id in menu_options[::-1]:

    if option_icon:

    option_icon = self.prep_menu_icon(option_icon)

    if option_id in self.menu_actions_by_id:

    item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,

    hbmpItem=option_icon,

    wID=option_id)

    win32gui.InsertMenuItem(menu, 0, 1, item)

    else:

    submenu = win32gui.CreatePopupMenu()

    self.create_menu(submenu, option_action)

    item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,

    hbmpItem=option_icon,

    hSubMenu=submenu)

    win32gui.InsertMenuItem(menu, 0, 1, item)

    def prep_menu_icon(self, icon):

    # First load the icon.

    ico_x = win32api.GetSystemMetrics(win32con.SM_CXSMICON)

    ico_y = win32api.GetSystemMetrics(win32con.SM_CYSMICON)

    hicon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, ico_x, ico_y, win32con.LR_LOADFROMFILE)

    hdcBitmap = win32gui.CreateCompatibleDC(0)

    hdcScreen = win32gui.GetDC(0)

    hbm = win32gui.CreateCompatibleBitmap(hdcScreen, ico_x, ico_y)

    hbmOld = win32gui.SelectObject(hdcBitmap, hbm)

    # Fill the background.

    brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU)

    win32gui.FillRect(hdcBitmap, (0, 0, 16, 16), brush)

    # unclear if brush needs to be feed. Best clue I can find is:

    # "GetSysColorBrush returns a cached brush instead of allocating a new

    # one." - implies no DeleteObject

    # draw the icon

    win32gui.DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL)

    win32gui.SelectObject(hdcBitmap, hbmOld)

    win32gui.DeleteDC(hdcBitmap)

    return hbm

    def command(self, hwnd, msg, wparam, lparam):

    id = win32gui.LOWORD(wparam)

    self.execute_menu_option(id)

    def execute_menu_option(self, id):

    menu_action = self.menu_actions_by_id[id]

    if menu_action == self.QUIT:

    win32gui.DestroyWindow(self.hwnd)

    else:

    menu_action(self)

    def non_string_iterable(obj):

    try:

    iter(obj)

    except TypeError:

    return False

    else:

    return not isinstance(obj, basestring)

    # Minimal self test. You'll need a bunch of ICO files in the current working

    # directory in order for this to work...

    if __name__ == '__main__':

    import itertools, glob

    icons = 'screenshot_tray.ico'

    hover_text = "多功能抓图工具"

    menu_options = (('抓取全屏', icons, screenshot.capture_fullscreen),

    ('抓取当前窗口', icons, screenshot.capture_current_windows),

    ('抓取所选区域', icons, screenshot.capture_choose_windows)

    )

    def bye(sysTrayIcon): print '退出'

    SysTrayIcon(icons, hover_text, menu_options, on_quit=bye)

    #提供快捷键操作

    screenshot.screenshot_main()3、执行screen_tray.py,托盘出现菜单项,各功能运行正常,快捷键功能正常,如下图。

    4、附:

    附内容:

    #!/usr/bin/env python

    # Module : SysTrayIcon.py

    # Synopsis : Windows System tray icon.

    # Programmer : Simon Brunning - simon@brunningonline.net

    # Date : 11 April 2005

    # Notes : Based on (i.e. ripped off from) Mark Hammond's

    # win32gui_taskbar.py and win32gui_menu.py demos from PyWin32

    '''TODO

    For now, the demo at the bottom shows how to use it...'''

    import os

    import sys

    import win32api

    import win32con

    import win32gui_struct

    try:

    import winxpgui as win32gui

    except ImportError:

    import win32gui

    class SysTrayIcon(object):

    '''TODO'''

    QUIT = 'QUIT'

    SPECIAL_ACTIONS = [QUIT]

    FIRST_ID = 1023

    def __init__(self,

    icon,

    hover_text,

    menu_options,

    on_quit=None,

    default_menu_index=None,

    window_class_name=None,):

    self.icon = icon

    self.hover_text = hover_text

    self.on_quit = on_quit

    menu_options = menu_options + (('Quit', None, self.QUIT),)

    self._next_action_id = self.FIRST_ID

    self.menu_actions_by_id = set()

    self.menu_options = self._add_ids_to_menu_options(list(menu_options))

    self.menu_actions_by_id = dict(self.menu_actions_by_id)

    del self._next_action_id

    self.default_menu_index = (default_menu_index or 0)

    self.window_class_name = window_class_name or "SysTrayIconPy"

    message_map = {win32gui.RegisterWindowMessage("TaskbarCreated"): self.restart,

    win32con.WM_DESTROY: self.destroy,

    win32con.WM_COMMAND: self.command,

    win32con.WM_USER+20 : self.notify,}

    # Register the Window class.

    window_class = win32gui.WNDCLASS()

    hinst = window_class.hInstance = win32gui.GetModuleHandle(None)

    window_class.lpszClassName = self.window_class_name

    window_class.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW;

    window_class.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW)

    window_class.hbrBackground = win32con.COLOR_WINDOW

    window_class.lpfnWndProc = message_map # could also specify a wndproc.

    classAtom = win32gui.RegisterClass(window_class)

    # Create the Window.

    style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU

    self.hwnd = win32gui.CreateWindow(classAtom,

    self.window_class_name,

    style,

    0,

    0,

    win32con.CW_USEDEFAULT,

    win32con.CW_USEDEFAULT,

    0,

    0,

    hinst,

    None)

    win32gui.UpdateWindow(self.hwnd)

    self.notify_id = None

    self.refresh_icon()

    win32gui.PumpMessages()

    def _add_ids_to_menu_options(self, menu_options):

    result = []

    for menu_option in menu_options:

    option_text, option_icon, option_action = menu_option

    if callable(option_action) or option_action in self.SPECIAL_ACTIONS:

    self.menu_actions_by_id.add((self._next_action_id, option_action))

    result.append(menu_option + (self._next_action_id,))

    elif non_string_iterable(option_action):

    result.append((option_text,

    option_icon,

    self._add_ids_to_menu_options(option_action),

    self._next_action_id))

    else:

    print 'Unknown item', option_text, option_icon, option_action

    self._next_action_id += 1

    return result

    def refresh_icon(self):

    # Try and find a custom icon

    hinst = win32gui.GetModuleHandle(None)

    if os.path.isfile(self.icon):

    icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE

    hicon = win32gui.LoadImage(hinst,

    self.icon,

    win32con.IMAGE_ICON,

    0,

    0,

    icon_flags)

    else:

    print "Can't find icon file - using default."

    hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)

    if self.notify_id: message = win32gui.NIM_MODIFY

    else: message = win32gui.NIM_ADD

    self.notify_id = (self.hwnd,

    0,

    win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,

    win32con.WM_USER+20,

    hicon,

    self.hover_text)

    win32gui.Shell_NotifyIcon(message, self.notify_id)

    def restart(self, hwnd, msg, wparam, lparam):

    self.refresh_icon()

    def destroy(self, hwnd, msg, wparam, lparam):

    if self.on_quit: self.on_quit(self)

    nid = (self.hwnd, 0)

    win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)

    win32gui.PostQuitMessage(0) # Terminate the app.

    def notify(self, hwnd, msg, wparam, lparam):

    if lparam==win32con.WM_LBUTTONDBLCLK:

    self.execute_menu_option(self.default_menu_index + self.FIRST_ID)

    elif lparam==win32con.WM_RBUTTONUP:

    self.show_menu()

    elif lparam==win32con.WM_LBUTTONUP:

    pass

    return True

    def show_menu(self):

    menu = win32gui.CreatePopupMenu()

    self.create_menu(menu, self.menu_options)

    #win32gui.SetMenuDefaultItem(menu, 1000, 0)

    pos = win32gui.GetCursorPos()

    # See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp

    win32gui.SetForegroundWindow(self.hwnd)

    win32gui.TrackPopupMenu(menu,

    win32con.TPM_LEFTALIGN,

    pos[0],

    pos[1],

    0,

    self.hwnd,

    None)

    win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0)

    def create_menu(self, menu, menu_options):

    for option_text, option_icon, option_action, option_id in menu_options[::-1]:

    if option_icon:

    option_icon = self.prep_menu_icon(option_icon)

    if option_id in self.menu_actions_by_id:

    item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,

    hbmpItem=option_icon,

    wID=option_id)

    win32gui.InsertMenuItem(menu, 0, 1, item)

    else:

    submenu = win32gui.CreatePopupMenu()

    self.create_menu(submenu, option_action)

    item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,

    hbmpItem=option_icon,

    hSubMenu=submenu)

    win32gui.InsertMenuItem(menu, 0, 1, item)

    def prep_menu_icon(self, icon):

    # First load the icon.

    ico_x = win32api.GetSystemMetrics(win32con.SM_CXSMICON)

    ico_y = win32api.GetSystemMetrics(win32con.SM_CYSMICON)

    hicon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, ico_x, ico_y, win32con.LR_LOADFROMFILE)

    hdcBitmap = win32gui.CreateCompatibleDC(0)

    hdcScreen = win32gui.GetDC(0)

    hbm = win32gui.CreateCompatibleBitmap(hdcScreen, ico_x, ico_y)

    hbmOld = win32gui.SelectObject(hdcBitmap, hbm)

    # Fill the background.

    brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU)

    win32gui.FillRect(hdcBitmap, (0, 0, 16, 16), brush)

    # unclear if brush needs to be feed. Best clue I can find is:

    # "GetSysColorBrush returns a cached brush instead of allocating a new

    # one." - implies no DeleteObject

    # draw the icon

    win32gui.DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL)

    win32gui.SelectObject(hdcBitmap, hbmOld)

    win32gui.DeleteDC(hdcBitmap)

    return hbm

    def command(self, hwnd, msg, wparam, lparam):

    id = win32gui.LOWORD(wparam)

    self.execute_menu_option(id)

    def execute_menu_option(self, id):

    menu_action = self.menu_actions_by_id[id]

    if menu_action == self.QUIT:

    win32gui.DestroyWindow(self.hwnd)

    else:

    menu_action(self)

    def non_string_iterable(obj):

    try:

    iter(obj)

    except TypeError:

    return False

    else:

    return not isinstance(obj, basestring)

    # Minimal self test. You'll need a bunch of ICO files in the current working

    # directory in order for this to work...

    if __name__ == '__main__':

    import itertools, glob

    icons = itertools.cycle(glob.glob('*.ico'))

    hover_text = "SysTrayIcon.py Demo"

    def hello(sysTrayIcon): print "Hello World."

    def simon(sysTrayIcon): print "Hello Simon."

    def switch_icon(sysTrayIcon):

    sysTrayIcon.icon = icons.next()

    sysTrayIcon.refresh_icon()

    menu_options = (('Say Hello', icons.next(), hello),

    ('Switch Icon', None, switch_icon),

    ('A sub-menu', icons.next(), (('Say Hello to Simon', icons.next(), simon),

    ('Switch Icon', icons.next(), switch_icon),

    ))

    )

    def bye(sysTrayIcon): print 'Bye, then.'

    SysTrayIcon(icons.next(), hover_text, menu_options, on_quit=bye, default_menu_index=1)

    展开全文
  • 其实就是windowsApi的一层封装。.../usr/bin/env python# Module : SysTrayIcon.py# Synopsis : Windows System tray icon.# Programmer : Simon Brunning - simon@brunningonline.net# Date : 11 April 2005# Note...

    其实就是windowsApi的一层封装。

    #!/usr/bin/env python

    # Module : SysTrayIcon.py

    # Synopsis : Windows System tray icon.

    # Programmer : Simon Brunning - simon@brunningonline.net

    # Date : 11 April 2005

    # Notes : Based on (i.e. ripped off from) Mark Hammond's

    # win32gui_taskbar.py and win32gui_menu.py demos from PyWin32

    '''TODO

    For now, the demo at the bottom shows how to use it...'''

    import os

    import sys

    import win32api

    import win32con

    import win32gui_struct

    try:

    import winxpgui as win32gui

    except ImportError:

    import win32gui

    class SysTrayIcon(object):

    '''TODO'''

    QUIT = 'QUIT'

    SPECIAL_ACTIONS = [QUIT]

    FIRST_ID = 1023

    def __init__(self,

    icon,

    hover_text,

    menu_options,

    on_quit=None,

    default_menu_index=None,

    window_class_name=None,):

    self.icon = icon

    self.hover_text = hover_text

    self.on_quit = on_quit

    menu_options = menu_options + (('Quit', None, self.QUIT),)

    self._next_action_id = self.FIRST_ID

    self.menu_actions_by_id = set()

    self.menu_options = self._add_ids_to_menu_options(list(menu_options))

    self.menu_actions_by_id = dict(self.menu_actions_by_id)

    del self._next_action_id

    self.default_menu_index = (default_menu_index or 0)

    self.window_class_name = window_class_name or "SysTrayIconPy"

    message_map = {win32gui.RegisterWindowMessage("TaskbarCreated"): self.restart,

    win32con.WM_DESTROY: self.destroy,

    win32con.WM_COMMAND: self.command,

    win32con.WM_USER+20 : self.notify,}

    # Register the Window class.

    window_class = win32gui.WNDCLASS()

    hinst = window_class.hInstance = win32gui.GetModuleHandle(None)

    window_class.lpszClassName = self.window_class_name

    window_class.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW;

    window_class.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW)

    window_class.hbrBackground = win32con.COLOR_WINDOW

    window_class.lpfnWndProc = message_map # could also specify a wndproc.

    classAtom = win32gui.RegisterClass(window_class)

    # Create the Window.

    style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU

    self.hwnd = win32gui.CreateWindow(classAtom,

    self.window_class_name,

    style,

    0,

    0,

    win32con.CW_USEDEFAULT,

    win32con.CW_USEDEFAULT,

    0,

    0,

    hinst,

    None)

    win32gui.UpdateWindow(self.hwnd)

    self.notify_id = None

    self.refresh_icon()

    win32gui.PumpMessages()

    def _add_ids_to_menu_options(self, menu_options):

    result = []

    for menu_option in menu_options:

    option_text, option_icon, option_action = menu_option

    if callable(option_action) or option_action in self.SPECIAL_ACTIONS:

    self.menu_actions_by_id.add((self._next_action_id, option_action))

    result.append(menu_option + (self._next_action_id,))

    elif non_string_iterable(option_action):

    result.append((option_text,

    option_icon,

    self._add_ids_to_menu_options(option_action),

    self._next_action_id))

    else:

    print 'Unknown item', option_text, option_icon, option_action

    self._next_action_id += 1

    return result

    def refresh_icon(self):

    # Try and find a custom icon

    hinst = win32gui.GetModuleHandle(None)

    if os.path.isfile(self.icon):

    icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE

    hicon = win32gui.LoadImage(hinst,

    self.icon,

    win32con.IMAGE_ICON,

    0,

    0,

    icon_flags)

    else:

    print "Can't find icon file - using default."

    hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)

    if self.notify_id: message = win32gui.NIM_MODIFY

    else: message = win32gui.NIM_ADD

    self.notify_id = (self.hwnd,

    0,

    win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,

    win32con.WM_USER+20,

    hicon,

    self.hover_text)

    win32gui.Shell_NotifyIcon(message, self.notify_id)

    def restart(self, hwnd, msg, wparam, lparam):

    self.refresh_icon()

    def destroy(self, hwnd, msg, wparam, lparam):

    if self.on_quit: self.on_quit(self)

    nid = (self.hwnd, 0)

    win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid)

    win32gui.PostQuitMessage(0) # Terminate the app.

    def notify(self, hwnd, msg, wparam, lparam):

    if lparam==win32con.WM_LBUTTONDBLCLK:

    self.execute_menu_option(self.default_menu_index + self.FIRST_ID)

    elif lparam==win32con.WM_RBUTTONUP:

    self.show_menu()

    elif lparam==win32con.WM_LBUTTONUP:

    pass

    return True

    def show_menu(self):

    menu = win32gui.CreatePopupMenu()

    self.create_menu(menu, self.menu_options)

    #win32gui.SetMenuDefaultItem(menu, 1000, 0)

    pos = win32gui.GetCursorPos()

    # See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp

    win32gui.SetForegroundWindow(self.hwnd)

    win32gui.TrackPopupMenu(menu,

    win32con.TPM_LEFTALIGN,

    pos[0],

    pos[1],

    0,

    self.hwnd,

    None)

    win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0)

    def create_menu(self, menu, menu_options):

    for option_text, option_icon, option_action, option_id in menu_options[::-1]:

    if option_icon:

    option_icon = self.prep_menu_icon(option_icon)

    if option_id in self.menu_actions_by_id:

    item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,

    hbmpItem=option_icon,

    wID=option_id)

    win32gui.InsertMenuItem(menu, 0, 1, item)

    else:

    submenu = win32gui.CreatePopupMenu()

    self.create_menu(submenu, option_action)

    item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text,

    hbmpItem=option_icon,

    hSubMenu=submenu)

    win32gui.InsertMenuItem(menu, 0, 1, item)

    def prep_menu_icon(self, icon):

    # First load the icon.

    ico_x = win32api.GetSystemMetrics(win32con.SM_CXSMICON)

    ico_y = win32api.GetSystemMetrics(win32con.SM_CYSMICON)

    hicon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, ico_x, ico_y, win32con.LR_LOADFROMFILE)

    hdcBitmap = win32gui.CreateCompatibleDC(0)

    hdcScreen = win32gui.GetDC(0)

    hbm = win32gui.CreateCompatibleBitmap(hdcScreen, ico_x, ico_y)

    hbmOld = win32gui.SelectObject(hdcBitmap, hbm)

    # Fill the background.

    brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU)

    win32gui.FillRect(hdcBitmap, (0, 0, 16, 16), brush)

    # unclear if brush needs to be feed. Best clue I can find is:

    # "GetSysColorBrush returns a cached brush instead of allocating a new

    # one." - implies no DeleteObject

    # draw the icon

    win32gui.DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL)

    win32gui.SelectObject(hdcBitmap, hbmOld)

    win32gui.DeleteDC(hdcBitmap)

    return hbm

    def command(self, hwnd, msg, wparam, lparam):

    id = win32gui.LOWORD(wparam)

    self.execute_menu_option(id)

    def execute_menu_option(self, id):

    menu_action = self.menu_actions_by_id[id]

    if menu_action == self.QUIT:

    win32gui.DestroyWindow(self.hwnd)

    else:

    menu_action(self)

    def non_string_iterable(obj):

    try:

    iter(obj)

    except TypeError:

    return False

    else:

    return not isinstance(obj, basestring)

    # Minimal self test. You'll need a bunch of ICO files in the current working

    # directory in order for this to work...

    if __name__ == '__main__':

    import itertools, glob

    icons = itertools.cycle(glob.glob('*.ico'))

    hover_text = "SysTrayIcon.py Demo"

    def hello(sysTrayIcon): print "Hello World."

    def simon(sysTrayIcon): print "Hello Simon."

    def switch_icon(sysTrayIcon):

    sysTrayIcon.icon = icons.next()

    sysTrayIcon.refresh_icon()

    menu_options = (('Say Hello', icons.next(), hello),

    ('Switch Icon', None, switch_icon),

    ('A sub-menu', icons.next(), (('Say Hello to Simon', icons.next(), simon),

    ('Switch Icon', icons.next(), switch_icon),

    ))

    )

    def bye(sysTrayIcon): print 'Bye, then.'

    SysTrayIcon(icons.next(), hover_text, menu_options, on_quit=bye, default_menu_index=1)

    展开全文
  • 全屏的时候调用exit是正常的,最小化的的时候会报以下错误 我尝试写了先恢复窗口然后退出依然会报还错误 好像必须异步才可以 #!/usr/bin/python # -*- coding: UTF-8 -*- from tkinter.constants import BOTH, E, ...

    前言

    SysTrayIcon 改的 python tkinter 最小化至系统托盘
    根据博主方式实现了tkinter 界面最小化到托盘

    问题

    加上了自己的一些代码后,全屏的时候调用exit是正常的,最小化的的时候会报以下错误
    我尝试写了先恢复窗口然后退出依然会报还错误 好像必须异步才可以
    在这里插入图片描述

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    
    from tkinter.constants import BOTH, E, END, INSERT, LEFT, N, TOP, W, X, YES
    from turtle import color
    
    from PIL import ImageGrab
    from time import sleep
    from minIcon import SysTrayIcon
    
    import pyperclip
    import os
    import tkinter as tk          # 导入 Tkinter 库
    from tkinter import Y,ttk
    from tkinter import * 
    import tkinter.messagebox
    import traceback
    import IMG_Tran_TEXT as Itt
    import Text_transAPI as TextT
    
    
    About = "版本号信息 v1.2 \n\n 一款小而美的Ocr软件\n该软件仅用于交流学习应用,禁止任何形式的商用行为" 
    Shareble = 1
    
    
    #默认配置项
    default_lang = 'en'
    current_lang = default_lang
    
    
    def message_askyesno(root):
        '''
        # Gets the requested values of the height and width.
        windowWidth = root.winfo_reqwidth()
        windowHeight = root.winfo_reqheight()
    
        # Gets both half the screen width/height and window width/height
        positionRight = int(root.winfo_screenwidth()/2 - windowWidth/2)
        positionDown = int(root.winfo_screenheight()/2 - windowHeight/2)
        '''
        root.withdraw()  # ****实现主窗口隐藏
        root.update()  # *********需要update一下
        
        return (tk.messagebox.askyesno("提示","要执行此操作?"))
       
    
    
    def clearEdit(Editx):
            Editx.delete('1.0',END)
           # Editx.configure(fg='black')  # 修改字体颜色,修改其它参数只需要传入对应的参数即可
    
    
    #图片识别的结果显示在Edit1
    def OcrDisplayCallback(Edit1,Edit2):
        clearEdit(Edit1)
        clearEdit(Edit2)
        Edit1.insert(INSERT,pyperclip.paste())
    
    
    def TransCallback(Edit1,Edit2,fm):
        clearEdit(Edit2)
        var = TextT.TextTranslate(current_lang,Edit1.get('1.0',END))
        Edit2.insert(INSERT,var)
        fm.pack(side=LEFT, fill=BOTH, expand=YES)
     
    #语言菜单
    languages = {"英语":"en", "简中":"zh",  "日语":"jp", "西班牙语": "spa",
                  "韩语":"kor",  "繁中":"cht",  "意大利语":"it", "捷克语":"cs","法语":"fra"}
    
    '''
    OPTIONS = []
    for k,v in languages.items():
        OPTIONS.append(k)
    '''
    def showAbout():
        tkinter.messagebox.showinfo(title='Topic', message= About,)
    
    class MyCapture:
        def __init__(self, png, root):
            #变量X和Y用来记录鼠标左键按下的位置
            self.X = tkinter.IntVar(value=0)
            self.Y = tkinter.IntVar(value=0)
            #屏幕尺寸
            screenWidth = root.winfo_screenwidth()
            screenHeight = root.winfo_screenheight()
    
            #创建顶级组件容器
            self.top = tkinter.Toplevel(
                root, width=screenWidth, height=screenHeight)
    
            #不显示最大化、最小化按钮
            self.top.overrideredirect(True)
            self.canvas = tkinter.Canvas(
                self.top, bg='blue', width=screenWidth, height=screenHeight)
            
            #显示全屏截图,在全屏截图上进行区域截图
            self.image = tkinter.PhotoImage(file=png)
            self.canvas.create_image(
                screenWidth//2, screenHeight//2, image=self.image)
    
            def onRightButtonDown(event):
                self.top.destroy()
                os.remove(filename)
                root.state('normal')
            self.canvas.bind('<Button-3>', onRightButtonDown)
    
            #鼠标左键按下的位置
            def onLeftButtonDown(event):
                self.X.set(event.x)
                self.Y.set(event.y)
                #开始截图
                self.sel = True
            self.canvas.bind('<Button-1>', onLeftButtonDown)
    
            #鼠标左键移动,显示选取的区域
            def onLeftButtonMove(event):
                if not self.sel:
                    return
                global lastDraw
                try:
                    #删除刚画完的图形,要不然鼠标移动的时候是黑乎乎的一片矩形
                    self.canvas.delete(lastDraw)
                except Exception as e:
                    pass
                lastDraw = self.canvas.create_rectangle(
                    self.X.get(), self.Y.get(), event.x, event.y, outline='blue')
    
            self.canvas.bind('<B1-Motion>', onLeftButtonMove)
    
            #获取鼠标左键抬起的位置,保存区域截图
            def onLeftButtonUp(event):
                self.sel = False
                '''try:
                    self.canvas.delete(lastDraw)
                except Exception as e:
                    pass
                    '''
                sleep(0.1)
                #考虑鼠标左键从右下方按下而从左上方抬起的截图
                left, right = sorted([self.X.get(), event.x])
                top, bottom = sorted([self.Y.get(), event.y])
                pic = ImageGrab.grab((left+1, top+1, right, bottom))
                #弹出保存截图对话框
                file_path = './image/somefile.png'
                pic.save(file_path, 'PNG')
                sleep(1)
    
                '''
                fileName = tkinter.filedialog.asksaveasfilename(
                    title='保存截图', filetypes=[('image', '*.jpg *.png')])
                
                if fileName:
                    pic.save(fileName)
                '''
                #关闭当前窗口
                self.top.destroy()
                return pic
            self.canvas.bind('<ButtonRelease-1>', onLeftButtonUp)
    #让canvas充满窗口,并随窗口自动适应大小
            self.canvas.pack(fill=tkinter.BOTH, expand=tkinter.YES)
    
     #开始截图
    
    application_path = "./image/"
    iconFile = "icon.ico"
            
    class _Main:  #调用SysTrayIcon的Demo窗口
        def __init__(s):
            s.SysTrayIcon  = None  # 判断是否打开系统托盘图标
    
        def popup(s,event):
            s.menu.post(event.x_root, event.y_root)   # post在指定的位置显示弹出菜单
    
        def setlang(s,event): 
            global current_lang  
            print(s.v.get())
            current_lang = languages.get(s.v.get())  
    
        def Edit_about(s,action):
            '''option obtain "back","callback","clear","copy"."cut","paste",'''
            #撤销、重做
            
            if(action == "back"):
                try:
                    s.Edit1.edit_undo()
                    s.Edit2.edit_undo()
                except Exception as e:
                    traceback.print_exc()
        
            if(action == "callback"):
                try:
                    s.Edit1.edit_redo()
                    s.Edit2.edit_redo()
                except Exception as e:
                    traceback.print_exc()
    
            if(action == "clear"):
                try:
                    s.Edit1.delete('1.0',END)
                    s.Edit2.delete('1.0',END)
                except Exception as e:
                    traceback.print_exc()
    
            if(action == "cut"):
                s.Edit2.event_generate('<<Cut>>')
                s.Edit1.event_generate('<<Cut>>')
                
            if(action == "copy"):
                s.Edit1.event_generate('<<copy>>')
                s.Edit2.event_generate('<<copy>>')
                
            if(action == "Paste"):
                s.Edit2.event_generate('<<Paste>>')
                s.Edit1.event_generate('<<Paste>>')
        #用来显示全屏幕截图并响应二次截图的窗口类
    
    
        def buttonCaptureClick(s):
            #当前在截图.不支持最小化判断
            global Shareble
            Shareble = 0
            isNormal = 0
            #最小化主窗口
            if(s.root.state() == "normal"):
                s.root.withdraw() #隐藏tk窗口
                isNormal = 1
            #s.root.state('icon')
            sleep(0.2)
            global filename
            filename = 'temp.png'
    
            #grab()方法默认对全屏幕进行截图
    
            im = ImageGrab.grab()
            im.save(filename)
            im.close()
            #显示全屏幕截图
            w = MyCapture(filename,s.root)
            s.G.wait_window(w.top)
            #截图结束,恢复主窗口,并删除临时的全屏幕截图文件
            os.remove(filename)
            s.Catch_chipboard()
            if(isNormal):
                s.root.deiconify()
            else:
                s.resume()
            Shareble = 1
    
        def display(s):
            #Frame1
            s.B.pack(side=TOP,anchor=W,fill=X,expand=N)
            s.G.pack(side=TOP,anchor=W,fill=X,expand=N)
            s.D.pack(side=TOP,anchor=W,fill=X,expand=N)
            s.Notice.pack(side=TOP,anchor=W,fill=BOTH,expand=Y)
    
            #Frame2
            s.OcrRes.pack(side=TOP,anchor=W,fill=X,expand=N) 
            s.Edit1.pack(side=TOP,anchor=W,fill=BOTH,expand=Y)
            
            s.TransButton.pack(side=LEFT,anchor=CENTER,fill=X,expand=Y)
            s.TransChoose.pack(side=RIGHT,anchor=W,fill=BOTH,expand=Y)
    
            #Frame3
            s.TransRes.pack(side=TOP,anchor=W,fill=X,expand=N) 
            s.Edit2.pack(side=TOP,anchor=W,fill=BOTH,expand=Y)
    
            s.fm1.pack(side=LEFT, fill=BOTH, expand=YES)
            s.fm2.pack(side=LEFT, fill=BOTH, expand=YES)
            s.fm3.forget()
    
        def switch_icon(s, _sysTrayIcon, icon = 'D:\\2.ico'):
            #点击右键菜单项目会传递SysTrayIcon自身给引用的函数,所以这里的_sysTrayIcon = s.sysTrayIcon
            #只是一个改图标的例子,不需要的可以删除此函数
            _sysTrayIcon.icon = icon
            _sysTrayIcon.refresh()
            
            #气泡提示的例子
            s.show_msg(title = '图标更换', msg = '图标更换成功!', time = 500)
        
        def show_msg(s, title = '标题', msg = '内容', time = 500):
            s.SysTrayIcon.refresh(title = title, msg = msg, time = time)
    
        def Hidden_window(s, icon = './image./icon.ico', hover_text = "图文精灵"):
            '''隐藏窗口至托盘区,调用SysTrayIcon的重要函数'''
    
            #托盘图标右键菜单, 格式: ('name', None, callback),下面也是二级菜单的例子
            #24行有自动添加‘退出’,不需要的可删除
            
            menu_options=(('打开主界面', None,s.resume), 
                          ('识别图像', None, (('截图', None,s.buttonCaptureClick),('打开图像', None,s.Ocrtranslated))),
                          )       
    
            s.root.withdraw()   #隐藏tk窗口
            if not s.SysTrayIcon: s.SysTrayIcon = SysTrayIcon(
                                            icon,               #图标
                                            hover_text,         #光标停留显示文字
                                            menu_options,       #右键菜单
                                            on_quit = s.exit,   #退出调用
                                            tk_window = s.root, #Tk窗口
                                            )
            s.SysTrayIcon.activation()
    
        def resume(s):
            s.SysTrayIcon.destroy(exit = 0)
    
        def exit(s, _sysTrayIcon=None):
            sleep(0.2)
            s.root.destroy()
            print ('exit...')
    
        def Catch_chipboard(s):
            file_path = './image/somefile.png'
            image = Itt.get_file_content(file_path)
            if Itt.Transform_GT(Itt.High_precision, image):
                s.varInFm1.set('识别完成,结果已复制到粘贴板')
            else:        
                s.varInFm1.set('未识别到文字信息')
            
        def Ocrtranslated(s):
            if Itt.Transform_GT(Itt.High_precision):
                s.varInFm1.set('识别完成,结果已复制到粘贴板')
            else:
                s.varInFm1.set('未识别到文字信息')
    
            print(s.root.state())
            if(s.root.state() == "withdrawn"):
                s.resume()
    
            
    
        def main(s):
            #tk窗口
            s.root = tk.Tk()
            s.root.title('图像转文字 v2.0')
            s.root.geometry('500x300+100+100')
            s.fm1 = ttk.Frame(s.root,takefocus= "blue")
            s.fm2 = ttk.Frame(s.root)
            s.fm3 = ttk.Frame(s.root)
         
            s.varInFm1= StringVar()
            starkabe = tk.PhotoImage(file = "./image/background.png")
            s.Notice = ttk.Label(s.fm1,anchor='center',image=starkabe,textvariable=s.varInFm1, wraplength = 130,foreground='grey', font=('Microsoft Yahei', 12),compound="top")
            s.varInFm1.set('请打开图片或截图')
    
            #窗口大小不可变化
            #root.resizable(True, False)  
    
            #在图形界面上设定输入框控件entry并放置控件
            #Edit1 = tk.Text(fm1, show='*', font=('Courier New', 12))   # 显示成密文形式
            #Edit2 = tk.Text(fm3, show=None, font=('Courier New', 12))  # 显示成明文形式
    
            '''Farme1 function area'''
    
            s.B = ttk.Button(s.fm1, text="打开图像",command =s.Ocrtranslated,width=5)
            s.G = ttk.Button(s.fm1, text="屏幕截图",command=s.buttonCaptureClick,width=5)
            s.D = ttk.Button(s.fm1,text = "显示结果",command = lambda:OcrDisplayCallback(s.Edit1,s.Edit2),width=5)
    
            s.OcrRes = ttk.Label(s.fm2, text='识别结果', font=('Microsoft Yahei', 10), width=10)
            s.Edit1 = tk.Text(s.fm2,width=10, height=5,padx=10,pady=1, undo = True,font=("Microsoft Yahei",9))
            s.TableStr = ttk.Label(s.fm2, anchor='e',text='To:', font=('Microsoft Yahei', 10))
    
            s.TransButton = ttk.Button(s.fm2,text = "翻译成 >",command = lambda:TransCallback(s.Edit1,s.Edit2,s.fm3),width=10)
            s.TransRes = ttk.Label(s.fm3, text='翻译结果', font=('Microsoft Yahei', 10), width=10)
            s.Edit2 = tk.Text(s.fm3,width=10, height=5,padx=10,pady=1, undo = True,font=("Microsoft Yahei",9))
    
            '''创建一个弹出菜单'''
            
            s.menu = tk.Menu(s.root,
                tearoff=False,
                #bg="grey",
                )
            s.menu.add_command(label="剪切", command=s.Edit_about("cut"))
            s.menu.add_command(label="复制", command=s.Edit_about("copy"))
            s.menu.add_command(label="黏贴", command=s.Edit_about("paste"))
    
            s.Edit1.bind("<Button-3>", s.popup)                 # 绑定鼠标右键,执行popup函数
            s.Edit2.bind("<Button-3>", s.popup)               # 绑定鼠标右键,执行popup函数
    
            s.v = Variable()
            s.v.set('英语')
            '''Farme2 function area'''
            s.TransChoose = ttk.OptionMenu(s.fm2, s.v , '',
                                "英语", 
                                "简中", 
                                "日语",
                                "西班牙语",
                                "韩语", 
                                "繁中",
                                "意大利语", 
                                "捷克语",
                                "法语"
                                ,command=s.setlang)
    
            #菜单栏
            s.menubar = tk.Menu(s.root)
            s.root.config(menu=s.menubar)
    
            #添加菜单选项
            s.menu1 = tk.Menu(s.menubar,borderwidth = 3,tearoff=False)
            s.menubar.add_cascade(label="选项", menu = s.menu1)
    
            s.menu1.add_command(label="撤销↶",command = lambda: s.Edit_about("back"))
            s.menu1.add_command(label="重做↷",command = lambda: s.Edit_about("callback"))
            s.menu1.add_command(label="清空",command = lambda: s.Edit_about("clear"))
            s.menu1.add_separator()
            s.menu1.add_command(label="历史",command = lambda: showHistroy)
            s.menu1.add_command(label="清空历史",command = lambda: clearHistory)
            s.menu1.add_separator()
            s.menu1.add_command(label="关于",command = showAbout)
            '''快捷键'''
            s.display()                    
            s.root.bind("<Control-Button-1>",lambda:s.buttonCaptureClick())
            s.root.bind("<Unmap>", lambda event: s.Hidden_window() if ((s.root.state() == 'iconic') and Shareble) else False) #窗口最小化判断,可以说是调用最重要的一步
            s.root.protocol('WM_DELETE_WINDOW', s.exit) #点击Tk窗口关闭时直接调用s.exit,不使用默认关闭
            
            s.root.mainloop()
    
    
    if __name__ == '__main__':
        Main = _Main()
        Main.main()
    
        
    

    解决方法

    见评论区,原博主解释

    展开全文
  • ", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No) if reply == QtWidgets.QMessageBox.Yes: event.ignore() self.hide() self.tray_icon.show() # 显示最小化托盘图标 else: ...
  • SysTrayIcon 改的 python tkinter 最小化至系统托盘

    千次阅读 多人点赞 2018-09-07 15:35:18
    网上的SysTrayIcon改的,TK页面最小化托盘托盘图标单击恢复界面 代码如下: import os import win32api import win32con import win32gui_struct import win32gui Main = None class ...
  • 将之前写的小闹钟包装一下,让其最小化到托盘后台运行。闹钟本身是一个监听程序,若是一直放在任务栏不小心点掉了就很麻烦。 所以说明一下托盘的使用方法,这里以之前的小闹钟案例为例,没有的我的公众号内'...
  • 我使用网上的代码,把用户界面最小化后按钮启动的程序停止运行了,请问有大神指点一下吗? ``` import win32api import win32con import win32gui_struct import win32gui from multiprocessing import ...
  • 将前台的程序后台运行,这样就可以不让别人看到!不错的软件哦!
  • Qt中如何使窗口隐藏/最小化到托盘

    千次阅读 2020-12-24 14:48:25
    展开全部功能62616964757a686964616fe78988e69d8331333361303733:窗口最小化后或者点击“hide”按钮将窗口隐藏到托盘。通常最小化的窗口会在任务栏上显示一个按钮。当用户按一下这个按钮,窗口就还原了。这是一个被...
  • 实战PyQt5: 109-将应用最小化到托盘

    千次阅读 2020-12-11 11:19:08
    要实现一个具有最小化到托盘功能的程序,要使用类QSystemTrayIcon。该类为操作系统托盘的类,通过QSystemTrayIcon,可以在托盘上显示指定程序的图标,响应用户鼠标操作,显示指定消失,显示菜单等。
  • 【pyqt5学习】——窗口最小化托盘、取消任务栏图标
  • wxpython 最小化到托盘

    2021-01-30 21:18:35
    由于wxpython版本的更新有些函数被弃用了,还有一些因为版本的问题不能...使用的python为3.7 wxpython为4.0.4 import wx from wx import adv class TaskBarIcon(wx.adv.TaskBarIcon): # 系统托盘 ID_Play = wx.Ne
  • 系统托盘程序的应用,使用ShellAPI、一般WinAPI函数...... TNotifyIconData、、、
  • 一直在学习系统托盘的实现,于是自己写了一个简单的系统托盘实例,右键包括演示、最大化、最小化、退出和关于。在python2.6下测试通过。 注意,本节分享的python实例代码,这里是托盘上的图标弹出菜单是覆盖了...
  • 原版python3 QT5 端口转发工具_firseve的专栏-CSDN博客 # -*- coding: utf-8 -*- # 制作本地可执行文件 # pyinstaller -F -i ico.ico -w port.py import sys import json import socket,threading import os ...
  • 我写了一个闹钟工具,最小化到托盘后,无法继续倒计时,到点后也无法提醒。请各位大神看看问题要如何解决呢?下面是代码: 1、闹钟的代码,文件名alarm.py import ctypes import threading import time import ...
  • 自己写的一个简单的系统托盘实例,右键包括演示、最大化、最小化、退出和关于。在python2.6下测试通过。
  • 小孩放假了,天天在电脑上看动画片,时间有点长,对小孩视力和身体都不好,准备自己写个有个性的保护程序,就是固定时间直接播放声音,并锁定屏幕一定间隔,过后程序自动最小化到托盘。现在遇到问题,不知道vb.net...
  • pyqt5 窗口最小化到windows托盘

    千次阅读 2020-07-09 12:57:14
    平时我们使用的有些程序也会最小化到任务栏旁边的托盘上,就是在时间日期旁边的小图标,这个需要额外在pyqt5中写点代码设置下了。 首先我们创建一个demo程序,这个程序就是创建一个窗口,窗口中有一个按钮和text...
  • 系统托盘图示 (system tray icon) 通常用来在桌面应用程序最小化后,不希望在任务列(taskbar)出现时,提供一个简单跟使用者交互的接口。 透过这样的用户接口,应用程序可以在有重要事件发生时,即时通知用户。因此,...
  • 3. 最小化到托盘后实现两个功能(左键单击显示或隐藏主界面,右键显示显示选线可以关闭或者显示主界面,); 1. 首先用designer新建了一个demo,这个demo上只有两个控件,一个是textBrowser,一个是pushButton,...
  • 问题描述 python打包成的exe程序最小化后点击其他页面进行操作,该程序...在程序中使用了tkinter创建了窗口,最小化到托盘后,只要需要对界面进行操作都进行不下去。 解决办法 改tkinter为easygui进行窗口创建 ...
  • pyinstaller打包机制我们写的python脚本是不能脱离python解释器单独运行的,所以在打包的时候,至少会将python解释器和脚本一起打包,同样,为了打包的exe能正常运行,会把我们所有安装的第三方包一并打包exe。...
  • wxpython托盘最小化)实例
  • 火狐浏览器最小字体Does the idea of being able to minimize Firefox to the System Tray instead of the Taskbar sound appealing? If so, then see just how easy it is to set up with the MinimizeToTray ...
  • MinimizeToTray可以始终始终最小化到托盘而不是任务栏,最小化到关闭时的托盘,并且需要双击才能从托盘还原。 These addons can also be used on Firefox. But usally I don’t like to make Firefox minimized to ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 980
精华内容 392
热门标签
关键字:

python程序最小化到托盘