2015-06-29 108 views
4

我正在製作一個音樂播放器GUI,我不能讓它出現在任務欄或Alt-Tab中。我已經將overrideredirect()設置爲true來刪除邊框和標題。我也做了這樣的事情,當用戶做一個「點擊並拖動」動作時,窗口就會移動。 下面的代碼:使tkinter窗口出現在任務欄

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

這不回答你的問題,但是從您的評論後'贏得=贏()',我猜你有一些麻煩圖片在課堂內創建它們時正確渲染。這是因爲PhotoImage實例的過早垃圾回收。請參閱[爲什麼我的Tkinter圖片不出現?](http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm)以獲取指導。 – Kevin

+0

@Kevin之前我曾經看過那篇文章,當時我正試圖解決圖像問題,但當時並沒有多大幫助。也許我沒有正確應用該頁面中的內容。 – FoxSGR

+0

你是作爲腳本運行項目還是凍結它? – timeyyy

回答

2

我發現有一種方法可以做到這一點,但它涉及到使用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風格,但是,您需要根據應用程序環境使用正確的獲取/設置功能。 32位Windows,看來你需要使用兩種:
GetWindowLongWSetWindowLongW

GetWindowLongASetWindowLongA

,但64位的需求:
GetWindowLongPtrWSetWindowLongPtrW

GetWindowLongPtrASetWindowLongPtrA
this

或另外,如果你想用默認這種行爲:

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()