tkinter创建动态出现窗口


tkinter本身视觉效果就不太好,当我们创建tkinter窗口时,总感觉有点单调,因此我想着怎么实现窗口以动态方式出现。

构思

当程序退出时实现动态关闭很简单,我们可以用:
root.protocol(‘WM_DELETE_WINDOW’,exit_window)
来绑定窗口关闭时所要运行的函数。函数 exit_window的内容如下

def exit_window():
    MyText.delete(1.0,END)
    for i in range(0,750,25)[::-1]:#生成数字表的反向序列
        root.geometry(str(i)+'x750+0+10')
        root.update()
        time.sleep(0.013)
    root.destroy()

这里引入了time模块。
其中,root.update()是必不可少。否则,程序窗口退出时不会出现动态收缩的效果,而是等一段时间以后直接消失关闭。使用该方法可以使窗口每次变化都刷新一遍,在这里可以在每一个for循环改变窗口宽度,达到动态退出的视觉效果。
我这里是750x750的窗口往左收缩,窗口宽度差可以自己调整,但是要记住:既不能移动太快,也不能拖延太久。

既然我们已经做到了如何实现窗口收缩关闭,那么再想想怎样扩张打开吧。但是问题出现了,tkinter窗口需要在使用mainloop()之后才能够呈现出来,而使用mainloop()之后,我们不能让程序自己进行任何操作,否则Python会报错。
虽然我们不能够在mainloop()循环之后进行操作,但是我们可以想想怎样在窗口进入循环之前进行操作,在操作的同时刷新窗口。
有点绕口,但是没关系,Python的多线程可以帮助我们做到这一点。

Python因为GIL使多线程无法大幅度提高效率,但是不影响我们的使用

实现

首先,让我们实现一个动态扩张的函数:

def start():
    for i in range(0,775,25):#这里不会生成775,要使用比750大25的数字结尾
        root.geometry(str(i)+'x750+0+10')
        time.sleep(0.013)

但这里为什么没有update()呢?往下再解释。
现在已经完成了窗口打开时的函数,接下来就可以实现在刷新窗口的同时运行这段函数了。同步执行的工作,交给threading就可以了,这里,我使用了其中的Thread。

root=Tk()
root.geometry('10x750+0+10')
root.title('test')
root.protocol('WM_DELETE_WINDOW',exit_window)#这就是上面的退出函数
#......
start_tk=Thread(target=start)#将开始函数放入多线程容器
start_tk.start()#与mainloop同步执行
root.mainloop()

我已经将该import的都import了
我单独使用Thread

因为使用多线程时,mainloop与函数是同步执行的,当函数执行完以后,mainloop才算是真正开始独立运行。所以在函数执行期间,每一次循环都会进行一次窗口刷新,因此就不需要使用update()了。

这样,tkinter窗口的动态出现就大功告成了~~

2020-3-15更新:

拓展

移动

我们还可以让窗口位置自动变化,只需要修改start函数就可以了。

def start():
    for i in range(0,300,10)#因为移动距离小,所以间隔要大
        root.geometry('750x750+'+i+'+10')
        time.sleep(0.02)

现在可以实现窗口右移了。如果想要实现左移,可以使用 750x750-i-900,具体数值视个人情况而定,这里只作为参考。

淡出淡入

此外,让窗口淡出淡入也是完全没问题的。这里需要用到tkinter窗口的属性,也就是attributes(),具体用法这里就不细讲,先上代码。

#淡入
def start():
    for i in range(0,105,5):
        root.attributes('-alpha',i/100)
        time.sleep(0.013)
        root.update()
#淡出
def end():
    for i in range(0,105,5)[::-1]:
        root.attributes('-alpha',i/100)
        time.sleep(0.013)
        root.update()

range好像不能有float类型,所以这里我取0~100的整数,接着再除以100就可以得到符合窗口透明属性的参数了。

颜色渐变

我们知道,tkinter的颜色最底层,其实就是RGB格式的,即 R, G, B 。只不过除了部分有名称的颜色,tkinter所有的颜色都可以用“#”加上十六进制的RGB。
RGB格式的最大值为 255,在十六进制里刚好是 FF。现在假设我们需要一个 130, 130, xx 系列的颜色,那我只需要将蓝色部分从0到255(可以是任何不大于255的数)的十进制转化为十六进制后再与前面的拼接,就可以得到一系列颜色了。

#十六进制的 130 为 82
#...
root=Tk()
#...
#我们只改变背景色
label=Label(root)
label.pack()
#...
for i in rang(0,250,10):
    col=str(format(i,'x'))
    color='#8282'+col
    label['bg']=color
    time.spleep(0.013)
    root.update()

这个操作不建议在性能差的电脑上运行,可能会没有效果

控件大小、位置等(未验证)

改变控件大小需要使用place来布局。这里推荐一个可视化编辑器PAGE
(代码验证后更新)

写在最后

虽然tkinter在视觉上和控件丰富性上比不上wx或pyqt,但是我们仍然可以通过一些细节的修改或增加来优化tkinter。如果你有更加好的方法,欢迎在评论区留言~~

☀tkinter创新☀

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值