悬停按钮的顶级窗口和顶级窗口本身

时间:2019-05-19 23:07:55

标签: python python-3.x tkinter

我不喜欢Python,为了练习,我尝试使用Tkinter创建音频播放器 现在,我试图创建一个顶级窗口来更改音量,就像在许多播放器或浏览器中一样 基本思想和复杂性在于以下事实:当您将光标悬停在“按钮”上时,窗口应该出现,而当光标离开按钮和对话框本身时,窗口应该消失(例如:类似于Youtube) 我知道,有一个绑定事件,例如Motion或Enter / Leave。但是如何确保不仅考虑按钮,也要考虑顶层工具的空间?

1 个答案:

答案 0 :(得分:0)

可以通过多种方式将音量悬停在窗口上,您也可以悬停Frame而不是使用Toplevel窗口,但是使用Toplevel()的想法为您提供了更多选择自定义并使它看起来更像我一样。

  • 我制作了一个函数,仅通过Button.bind("<Enter>", change_volume)就可以将其分配给任何按钮。

  • 在该函数中,将在“” 上创建一个顶级窗口,并在“”上分别创建destroy()

  • 我使用wm_overrideredirect(True)Toplevel窗口中删除了装饰,例如窗口边缘周围的标题栏边框。

  • 我还使用了一些 -alpha 属性,以attributes('-alpha', 0.6)为窗口提供了一些透明度。

  • 您还可以使用ttk themed Scale,它具有圆形旋钮,看起来比默认旋钮更好,并且ttk像tkinter一样已预安装。但它会返回一个 float 值,其中正常的Scale返回 integer

Restuls:

_________ (Defualt) _________。 ________ (以ttk为主题) ________

HoverVolume .. enter image description here

代码示例:

from tkinter import *
from tkinter import ttk  # for round knob scale widget

root = Tk()
root['bg'] = 'lightyellow'
root.geometry('200x200+100+100')
volvar = IntVar(value=5)

def change_volume(evt=None):
    global vol_wid
    wid = evt.widget  # Get the widget the instance
    # Try / except to avoid errors like AttributeError.. 
    try: 
        # Returns if a window alrealy present
        if vol_wid.winfo_exists(): return 
    except: pass
    vol_wid = Toplevel(root)
    vol_wid.wm_overrideredirect(True)  # Removes the titlrbar and borders
    vol_wid.update()   # Don't need if not on macos
    vol_wid.lift()
    vol_wid.attributes('-alpha', 0.6) # Makes the window transparent
    vol_wid.attributes('-topmost', 1) # Be on top of every window
    scale = Scale(vol_wid, from_=0, to=10, variable=volvar, orient='horizontal', 
               bg='black', fg='white')    # NORMAL DEFAULT SCALE
    # scale = ttk.Scale(vol_wid, from_=0, to=10, variable=volvar, 
    #           orient='horizontal')    # ROUND KNOB SCALE
    scale.pack()
    # Set the window just above the button 
    width = int((scale.winfo_reqwidth() - wid.winfo_width()) / 2)
    vol_wid.geometry('+%s+%s' %(wid.winfo_rootx()-width, 
            wid.winfo_rooty()-scale.winfo_reqheight()))
    vol_wid.focus()  # Gives focus
    vol_wid.bind("<Leave>", lambda e: vol_wid.destroy()) # Bind to destroy window

Label(root, textvariable=volvar, font=('',16)).pack(pady=25)
B = Button(root, text='Volume',bg='lightpink', padx=10)
B.pack(pady=25)
B.bind("<Enter>", change_volume)
mainloop()