使tkinter窗口出现在任务栏中

发布于 2021-01-29 14:11:13

我正在制作音乐播放器GUI,但无法使其显示在任务栏或Alt-
Tab中。我已将overrideredirect()设置为true以删除边框和标题。我也做到了,这样当用户执行“鼠标单击并拖动”操作时,窗口就会移动。这是代码:

import tkinter
import sys
import os


class Win(tkinter.Tk):
    global imgfile
    imgfile = r"play.png"

    def __init__(self, master=None):
        def close():
            self.destroy()
            sys.exit()

        def dirchosen():
            global songlist
            songlist = []
            try:
                os.chdir(dirinput.get())
            except:
                print("Invalid Directory")
                raise
            for file in os.listdir(dirinput.get()):
                songlist.append(file)

        tkinter.Tk.__init__(self, master)
        self.overrideredirect(True)
        self._offsetx = 0
        self._offsety = 0

        self.bind('<Button-1>', self.clickwin)
        self.bind('<B1-Motion>', self.dragwin)

        self.geometry("350x200")
        self.config(bg="#FF4766")

        titlelabel = tkinter.Label(self, text="FoxSGR Media Player", bg="#FF4766", font=("Segoe UI", 12))
        titlelabel.pack(ipady=4)

        chdirbutton = tkinter.Button(self, relief="groo", activebackground="#FF8080", command=dirchosen)
        chdirbutton.config(text="Choose Directory", bg="#FF4766", font=("Segoe UI", 8))
        chdirbutton.pack()
        chdirbutton.place(relx=0.66, rely=0.22)

        dirinput = tkinter.Entry(self, font=("Segoe UI", 8), width="34")
        dirinput.pack()
        dirinput.place(relx=0.05, rely=0.23)

        xbutton = tkinter.Button(self, text="x", height="1", command=close)
        xbutton.config(bg="red", activebackground="#FF8080", relief="groo", font=("Segoe UI", 8))
        xbutton.pack()
        xbutton.place(relx=0.90, rely=0.05)

    def dragwin(self, event):
        x = self.winfo_pointerx() - self._offsetx
        y = self.winfo_pointery() - self._offsety
        self.geometry('+{x}+{y}'.format(x=x, y=y))

    def clickwin(self, event):
        self._offsetx = event.x
        self._offsety = event.y

win = Win()

# Had to set the images appart from up there

imgplay = tkinter.PhotoImage(file=imgfile)
playbutton = tkinter.Button(win, image=imgplay, bg="#FF4766", relief="flat")
playbutton.pack()
playbutton.place(rely=0.45, relx=0.4)

imgnext = tkinter.PhotoImage(file="next.png")
nextbutton = tkinter.Button(win, image=imgnext, bg="#FF4766", relief="flat")
nextbutton.pack()
nextbutton.place(rely=0.45, relx=0.57)

imgprev = tkinter.PhotoImage(file="previous.png")
prevbutton = tkinter.Button(win, image=imgprev, bg="#FF4766", relief="flat")
prevbutton.pack()
prevbutton.place(rely=0.45, relx=0.30)

win.mainloop()

有什么办法可以使其至少出现在Alt-Tab中?

关注者
0
被浏览
101
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    经过一些研究,我发现有一种方法可以执行此操作,但是它涉及使用ctypes,并且是Windows的唯一解决方案:

    import tkinter as tk
    import tkinter.ttk as ttk
    from ctypes import windll
    
    GWL_EXSTYLE=-20
    WS_EX_APPWINDOW=0x00040000
    WS_EX_TOOLWINDOW=0x00000080
    
    def set_appwindow(root):
        hwnd = windll.user32.GetParent(root.winfo_id())
        style = windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
        style = style & ~WS_EX_TOOLWINDOW
        style = style | WS_EX_APPWINDOW
        res = windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, style)
        # re-assert the new window style
        root.wm_withdraw()
        root.after(10, lambda: root.wm_deiconify())
    
    def main():
        root = tk.Tk()
        root.wm_title("AppWindow Test")
        button = ttk.Button(root, text='Exit', command=lambda: root.destroy())
        button.place(x=10,y=10)
        root.overrideredirect(True)
        root.after(10, lambda: set_appwindow(root))
        root.mainloop()
    
    if __name__ == '__main__':
        main()
    

    这涉及使用ctypes来操纵Windows样式,但是您需要根据应用程序环境使用正确的Get / Set函数。对于32位窗口,看来您需要使用:
    GetWindowLongWSetWindowLongW

    GetWindowLongASetWindowLongA

    但64位的需要:
    GetWindowLongPtrWSetWindowLongPtrW

    GetWindowLongPtrASetWindowLongPtrA
    看到

    或者,如果您默认需要这种行为:

    import tkinter as tk
    
    from ctypes import windll
    
    class Tk(tk.Tk):
        def overrideredirect(self, boolean=None):
            tk.Tk.overrideredirect(self, boolean)
            GWL_EXSTYLE=-20
            WS_EX_APPWINDOW=0x00040000
            WS_EX_TOOLWINDOW=0x00000080
            if boolean:
                print("Setting")
                hwnd = windll.user32.GetParent(self.winfo_id())
                style = windll.user32.GetWindowLongW(hwnd, GWL_EXSTYLE)
                style = style & ~WS_EX_TOOLWINDOW
                style = style | WS_EX_APPWINDOW
                res = windll.user32.SetWindowLongW(hwnd, GWL_EXSTYLE, style)
            self.wm_withdraw()
            self.wm_deiconify()
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看