简体   繁体   English

是否可以为 tkinter 中的网格管理器布局的帧设置动画?

[英]Is it possible to animate frames that are layed out with the grid manager in tkinter?

I made this desktop application with tkinter and finished the main functionalities.我用 tkinter 制作了这个桌面应用程序并完成了主要功能。 But now I want to make it look better and even animate the menus is possible.但现在我想让它看起来更好,甚至可以为菜单设置动画。 The thing is the buttons and widgets that I used are contained in frames and all of them were put by using the grid layout manageR.问题是我使用的按钮和小部件包含在框架中,所有这些都是使用网格布局managerR放置的。 So I was wondering if i could maybe animate elements ( mainly buttons and frames ) w所以我想知道我是否可以为元素(主要是按钮和框架)设置动画

For an example if I hover my mouse over a button it'll increase its size a bit, but I want of course to see the increase of that size in time.例如,如果我 hover 我的鼠标悬停在一个按钮上,它的大小会增加一点,但我当然希望及时看到该大小的增加。 O r maybe when I click one button and I need to change to a new frame, then the old one will slide to the right for example O r 也许当我点击一个按钮,我需要换一个新的框架,然后旧的会滑到右边,例如

The following code combines some ideas for interactive buttons within a grid cell:以下代码结合了网格单元格中交互式按钮的一些想法:

  • callbacks <Enter> and <Leave> for mouse hovering用于鼠标悬停的回调<Enter><Leave>
  • a button size specified in pixels as suggested by Bryan Oakley (here: https://stackoverflow.com/a/46286221/13257648 ) Bryan Oakley 建议的以像素为单位指定的按钮大小(此处: https://stackoverflow.com/a/46286221/13257648
  • using padx/pady and width/height to control space reserved for button使用 padx/pady 和 width/height 来控制为按钮保留的空间
  • root.after(milliseconds, function) as suggested in furas comment root.after(milliseconds, function)如 furas 评论中所建议
import tkinter as tk

buttonsize = [120, 50]
extrasize = [10, 10]
framepad = [6, 6]
anim_time = 40
anim_steps = 10

root = tk.Tk()
pixel = tk.PhotoImage(width=1, height=1)

def SizeChange(event, fraction):
    event.widget.grid_configure(padx=(1.0-fraction)*extrasize[0], pady=(1.0-fraction)*extrasize[1])
    event.widget.configure(width=buttonsize[0]+2*fraction*extrasize[0],
        height=buttonsize[1]+2*fraction*extrasize[1])
    root.update_idletasks()


def Highlight(event):
    for idx in range(anim_steps):
        fraction = float(idx+1)/anim_steps
        root.after(int(fraction*anim_time), SizeChange(event, fraction))


def Unhighlight(event):
    for idx in range(anim_steps):
        fraction = 1.0 - float(idx+1)/anim_steps
        root.after(int(fraction*anim_time), SizeChange(event, fraction))


def AddButton(row, col, name):
    tkframe = tk.Frame(root, width=buttonsize[0]+extrasize[0],
        height=buttonsize[1]+extrasize[1])
    tkframe.grid(row=row, column=col, padx=framepad[0], pady=framepad[1], sticky='nsew')
    tkbutton = tk.Button(tkframe, text=name, compound='c', image=pixel,
        width=buttonsize[0], height=buttonsize[1])
    tkbutton.grid(row=0, column=0, padx=extrasize[0], pady=extrasize[1])
    tkbutton.bind('<Enter>', Highlight)
    tkbutton.bind('<Leave>', Unhighlight)


for idx in range(4):
    AddButton(row=idx//2, col=idx%2, name='Button ' + str(idx))


root.mainloop()

Although it seems the smoothness of the animation is highly dependent on the extra size added to the button size and the time steps.虽然看起来 animation 的平滑度很大程度上取决于按钮大小和时间步长的额外大小。

This is example which use after to move Frame with Label and Button .这是使用LabelButton移动Frame after使用的示例。 I used place() to use relative position so Frame leave window even if you change window size.我使用place()来使用相对 position 所以即使您更改 window 大小, Frame也会离开 window。

import tkinter as tk

# --- functions ---

def move(steps=10, distance=0.1):
    if steps > 0:
        # get current position
        relx = float(frame.place_info()['relx'])

        # set new position
        frame.place_configure(relx=relx+distance)

        # repeate it after 10ms
        root.after(10, move, steps-1, distance)

def on_click():
    print('on_click')
    # start move
    move(50, 0.02) # 50*0.02 = 1

# --- main --

root = tk.Tk()

frame = tk.Frame(root, background='red')
frame.place(relx=0, rely=0, relwidth=1, relheight=1)

# to center label and button
#frame.grid_columnconfigure(0, weight=1)
#frame.grid_rowconfigure(0, weight=1)
#frame.grid_rowconfigure(3, weight=1)

label = tk.Label(frame, text='Frame with Label and Button')
label.grid(row=1, column=0)

button = tk.Button(frame, text='MOVE', command=on_click)
button.grid(row=2, column=0)

root.mainloop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM