You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设置启用overrideredirect的tkinter窗口激活时显示任务栏图标

问题解决方法

问题原因

你设置overrideredirect(1)后,窗口会被系统识别为无系统标题栏的工具类窗口,默认不会在任务栏生成对应图标,你当前只有最小化时临时切回overrideredirect(0)才会触发任务栏图标显示。

解决方案(Windows平台通用,适配你现有代码逻辑)

我们可以通过ctypes调用Windows系统API,修改窗口的扩展样式,强制让无标题栏窗口在任务栏显示图标,不需要改动你现有的最小化、拖拽、缩放逻辑。

具体修改步骤:

  1. 导入ctypes相关模块,获取主窗口的HWND句柄
  2. 在窗口初始化完成后调用API修改窗口扩展属性
  3. 调整恢复窗口的逻辑,避免恢复时覆盖修改的样式

修改后的完整代码:

from tkinter import Tk, Frame, TOP, X
from tkinter.constants import DISABLED, LEFT, RIGHT
from tkinter.ttk import Button, Label
import pyautogui as pg
import time
import ctypes
from ctypes import wintypes

# 定义Windows API需要的常量
GWL_EXSTYLE = -20
WS_EX_APPWINDOW = 0x00040000
WS_EX_TOOLWINDOW = 0x00000080

def set_taskbar_icon(hwnd):
    # 修改窗口扩展样式,添加任务栏显示属性
    style = ctypes.windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
    style = style & ~WS_EX_TOOLWINDOW # 移除工具窗口属性
    style = style | WS_EX_APPWINDOW # 添加常规窗口属性
    ctypes.windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, style)
    # 刷新窗口样式使其生效
    ctypes.windll.user32.ShowWindow(hwnd, 1)

root = Tk()
root.geometry("700x700")
root.attributes("-topmost", 1)
root.overrideredirect(1)

# 初始化完成后设置任务栏图标
root.update()
hwnd = wintypes.HWND(root.winfo_id())
set_taskbar_icon(hwnd)

ma = False  # For getting window state
tr = 1  # Transparency level
gx = 700 # Geometry X and Y
gy = 700

def nor(event):
    top.config(cursor="arrow")

def place_center():
    # Getting screen size
    reso = pg.size()
    rx = reso[0]    # Resolution: X and Y
    ry = reso[1]
    x = int((rx/2) - (700/2))   # Places to place the window in the center
    y = int((ry/2) - (700/2))
    root.geometry(f"700x700+{x}+{y}")

def drag(event):
    global ma
    root.state("normal")
    top.config(cursor="fleur")  # Changing the cursor
    resb.config(text="     [ ]     ")    # Changing the button
    ma = False  # Window isn't maximized
    fx = root.winfo_pointerx() - 250    # Placing the window as per cursor movement
    fy = root.winfo_pointery() - 10
    root.geometry(f"700x700+{fx}+{fy}")

def restore(event):
    global tr
    tr = 0
    root.overrideredirect(1)
    root.unbind("<Map>")    # So that it wont flicker while restoring
    # 恢复后重新设置任务栏图标属性
    set_taskbar_icon(hwnd)
    while tr <= 1.0:    # Fade in animation
        root.attributes("-alpha", tr)
        tr += 0.2
        time.sleep(0.04)
    else:
        root.state('normal')

def minimize():
    global tr
    root.update_idletasks()
    while tr > 0:   # fade out animation
        root.attributes("-alpha", tr)
        tr -= 0.1
    else:
        root.withdraw() # withdrawing the window
        root.overrideredirect(0)    # Activating DWM to be able to minimize
        root.iconify()
    root.bind("<Map>", restore) # To be able to restore the window

def cl():  # Closing the window
    global tr
    if tr > 0:  # Fade out animation
        root.attributes("-alpha", tr)
        tr -= 0.1
        root.after(4, lambda: cl())
    else:
        root.quit()

def zoom(): # To maximize the window
    global ma
    root.state("zoomed")
    ma = True   # Window is maximized
    resb.config(text="     []]     ")    # Changing the maximize button

def maximize():
    global ma
    root.unbind("<Map>")    # To avoid flickering
    if ma == False: # Maximize if not
        zoom()
    else:
        root.state('normal')
        root.geometry(f"700x700")
        ma = False  # Window isn't maximized
        resb.config(text="     [ ]     ")    # Changing the maximize button 

place_center()

# Packing the control buttons and other things (like title bar)
top = Frame(root, height=50, bg='white')
closeb = Button(top, text="      X     ", command=cl)
closeb.pack(side=RIGHT)
resb = Button(top, text="     [ ]     ", command=maximize)
resb.pack(side=RIGHT)
minb = Button(top, text="     __     ", command=minimize)
minb.pack(side=RIGHT)
tit = Label(top, text="My Window", background="white")
tit.pack(side=LEFT)

top.pack(side=TOP, fill=X)

# For the window to move
top.bind("<B1-Motion>", drag)
top.bind("<ButtonRelease-1>", nor)

root.attributes("-topmost", 1)
root.config(bg="grey")

root.mainloop()

补充说明

  • 上述方案仅适用于Windows平台,如果你需要跨平台适配,可以考虑创建一个不可见的辅助主窗口,将自定义窗口作为它的子窗口,辅助窗口始终保持在任务栏显示状态,两个窗口的最小化、激活状态同步即可。
  • 你原代码的可读性很好,逻辑清晰。

内容的提问来源于stack exchange,提问作者IJ_123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 20:36:00