【问题标题】:Tkinter overridedirect (minimizing and windows task bar issues)Tkinter overridedirect(最小化和 windows 任务栏问题)
【发布时间】:2020-11-22 19:00:43
【问题描述】:

我想要实现的是一个 Tkinter 窗口,使用 overridedirect,它显示在你的任务栏中。您可以像普通窗口一样将其最小化,然后像普通窗口一样将其恢复。我现在遇到的问题是我已经将它添加到任务栏,但是由于某种原因,当您将其最小化然后将其恢复时,它不再出现在任务栏上。

# Imports
from tkinter import *
from ctypes import windll
# Some WindowsOS styles, required for task bar integration
GWL_EXSTYLE = -20
WS_EX_APPWINDOW = 0x00040000
WS_EX_TOOLWINDOW = 0x00000080
def set_appwindow(mainWindow):
    # Honestly forgot what most of this stuff does. I think it's so that you can see 
# the program in the task bar while using overridedirect. Most of it is taken 
# from a post I found on stackoverflow.
    hwnd = windll.user32.GetParent(mainWindow.winfo_id())
    stylew = windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
    stylew = stylew & ~WS_EX_TOOLWINDOW
    stylew = stylew | WS_EX_APPWINDOW
    res = windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, stylew)
    # re-assert the new window style
    mainWindow.wm_withdraw()
    mainWindow.after(10, lambda: mainWindow.wm_deiconify())
def main():
    global mainWindow
    # Default window configuration
    mainWindow = Tk()
    mainWindow.geometry('800x400')
    mainWindow.resizable(width=False, height=False)
    mainWindow.overrideredirect(True)
    mainWindow.after(10, lambda: set_appwindow(mainWindow))
    def exitGUI():
        mainWindow.destroy()
    def minimizeGUI():
        mainWindow.state('withdrawn')
        mainWindow.overrideredirect(False)
        mainWindow.state('iconic')
    def frameMapped(event=None):
        mainWindow.overrideredirect(True)
        mainWindow.state("normal")
        mainWindow.iconbitmap("ANALOG.ico")
    exitButton = Button(mainWindow, text='', bg='#212121', fg='#35DAFF',
     command=exitGUI)
    minimizeButton = Button(mainWindow, text='', bg="#212121", fg='#35DAFF',
     command=minimizeGUI)
    exitButton.place(x=780, y=0)
    minimizeButton.place(x=759, y=0)
    mainWindow.bind("<Map>", frameMapped) # This brings back the window
    mainWindow.mainloop()  # Window Loop
if __name__ == '__main__':
    main()

【问题讨论】:

  • 使用overridedirect 有这样的缺点,我认为实际上没有办法解决它。
  • 看看this
  • @CoolCloud 我想可以通过使根不可见然后使用顶层来代替。但我不明白这些花哨的东西。我希望我的应用程序适合系统。
  • @CoolCloud 您的链接显示了这个想法,但缺少一些要点。因为他想最小化他的窗口。他需要将此顶层设置为瞬态或组。
  • 瞬态?我认为一旦窗口是瞬态的,它就不会显示为窗口并且更难最小化?

标签: python tkinter window


【解决方案1】:

好吧,我终于想通了。

# Imports
from tkinter import *
from ctypes import windll

# Some WindowsOS styles, required for task bar integration
GWL_EXSTYLE = -20
WS_EX_APPWINDOW = 0x00040000
WS_EX_TOOLWINDOW = 0x00000080

lastClickX = 0
lastClickY = 0


def SaveLastClickPos(event):
    global lastClickX, lastClickY
    lastClickX = event.x
    lastClickY = event.y


def Dragging(event):
    x, y = event.x - lastClickX + mainWindow.winfo_x(), event.y - lastClickY + mainWindow.winfo_y()
    mainWindow.geometry("+%s+%s" % (x , y))

def set_appwindow(mainWindow):
    # Honestly forgot what most of this stuff does. I think it's so that you can see
    # the program in the task bar while using overridedirect. Most of it is taken
    # from a post I found on stackoverflow.
    hwnd = windll.user32.GetParent(mainWindow.winfo_id())
    stylew = windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
    stylew = stylew & ~WS_EX_TOOLWINDOW
    stylew = stylew | WS_EX_APPWINDOW
    res = windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, stylew)
    # re-assert the new window style
    mainWindow.wm_withdraw()
    mainWindow.after(10, lambda: mainWindow.wm_deiconify())


def main():
    global mainWindow, z
    # Default window configuration
    mainWindow = Tk()
    mainWindow.geometry('800x400')
    mainWindow.resizable(width=False, height=False)
    mainWindow.overrideredirect(True)
    mainWindow.after(10, lambda: set_appwindow(mainWindow))
    mainWindow.bind('<Button-1>', SaveLastClickPos)
    mainWindow.bind('<B1-Motion>', Dragging)
    z = 0

    def exitGUI():
        mainWindow.destroy()

    def minimizeGUI():
        global z
        mainWindow.state('withdrawn')
        mainWindow.overrideredirect(False)
        mainWindow.state('iconic')
        z = 1

    def frameMapped(event=None):
        global z
        mainWindow.overrideredirect(True)
        mainWindow.iconbitmap("ANAL_OG.ico")
        if z == 1:
            set_appwindow(mainWindow)
            z = 0


    exitButton = Button(mainWindow, text='', bg='#212121', fg='#35DAFF',
                        command=exitGUI)
    minimizeButton = Button(mainWindow, text='', bg="#212121", fg='#35DAFF',
                            command=minimizeGUI)
    exitButton.place(x=780, y=0)
    minimizeButton.place(x=759, y=0)
    mainWindow.bind("<Map>", frameMapped)  # This brings back the window
    mainWindow.mainloop()  # Window Loop


if __name__ == '__main__':
    main()

感谢您的所有建议!

【讨论】:

  • 干得好,尽管我不喜欢覆盖重定向,但还是很感激。 :D
猜你喜欢
  • 2011-08-14
  • 1970-01-01
  • 2014-11-19
  • 1970-01-01
  • 2012-11-08
  • 2011-09-09
  • 1970-01-01
  • 2015-08-22
  • 2013-07-10
相关资源
最近更新 更多