tkinter各种控件库控件创建速度比较

前言

tkinter作为Python的标准库之一,是很多初学者学习Python+GUI的第一步。随着越来越多的开发者为tkinter提供开源库,tkinter的延伸功能也越来越强大,比如:

  • 显示地图、视频、表格、网页

  • 窗体设计

  • 窗口嵌套

  • 基于tkinter的新控件库

等等。

其中,“基于tkinter的新控件库”是一个重要部分,虽然目前这类第三方库比较少,但是它的重要性也很大——为tkinter提供新的样式控件。这类控件是独立于tkinter原生控件以及贴图控件的存在,提供了一种全新的窗口风格。

这类拓展库主要有三种:

  • 贴图库

  • 重绘库

  • 新元素库

这是我起的名称,接下来会有详细说明。

本篇,我们侧重于看看它们创建控件的速度。

各类控件库

贴图库

实际上,这种类型的新控件库很多,比如:ttkbootstrap、ttkthemes、sun-valley-ttk等等。它们为tkinter提供了近乎一整套的、风格独立的控件。但是,这些只是在原生tkinter控件的基础上,通过改变配色、使用gif贴图实现的,根本上还是tkinter控件,只是加入了成套归类的风格样式。

通过gif贴图创建样式涉及到操作TCL层,该操作无法在Python层面完成,如太阳谷ttk。

因此,本次测试直接用tkinter.ttk来代表这些贴图库。这些贴图的控件创建速度应该是略慢于原生ttk的。

重绘库

这就是使用有限的tkinter控件,以每个控件为单位,提供一套全新的控件。最出名的就是CustomTkinter,即CTK。

其实,这种类型库也只有CTK一个。

趁现在帮CTK宣传一波:CTK是一个“重型tkinter重绘库”,它使用画布重新实现每一个控件,其样式参考了winui3。它使用画布来绘制所有所提供的控件,使之有高样式可控度,此外还有由画布带来的众多特殊功能。它自己提供的画布渲染引擎,甚至可以在Windows平台上抵消画布锯齿,十分强大。

但是这也造成了另一个问题,就是CTK的加载速度理论上会更慢。

新元素库

这种类型的库是以一个tkinter控件为主控件,在这个统一的框架下提供拥有一整套组件的tkinter新控件,其中的几乎每一个组件都是绘制出来,在整个框架中被称作元素。

目前,这种类型库有TinUI,tkintertools等。

TinUI相较于CTK是一个轻量库。TinUI提供一个整体类:TinUI或BasicTinUI,所有的控件都是其中的一个个画布元素。麻雀虽小五脏俱全,TinUI的实际控件数量要比CTK多,而计算资源和绘图引擎却要小很多,当然,TinUI也就无可避免的会在斜线、圆角设计中出现锯齿。

只有Windows平台的tkinter画布才会出现明显锯齿。

理论上,通过统一画布绘制控件的速度应该要快很多,就像WPF的ElementHost。

测试

现在,我们就这三种新控件库进行控件创建速度。

  1. 均使用200个按钮

  2. 在画布中创建(因为TinUI只能使用绝对布局,且画布易查看所有控件)

测试代码

本次测试中使用修饰器来测试三种函数,用于控件创建。

from tkinter import Tk, Canvas
from tkinter import ttk
import customtkinter as ctk
from TinUI import BasicTinUI
import time

def timeit(func):
    def go():
        start=time.time()
        func()
        end=time.time()
        print(end-start)
    return go

@timeit
def load_tk():
    for i in range(1,201):
        a.create_window((5,40*i),window=ttk.Button(a,text=str(i))
                ,anchor='nw')
    a.config(scrollregion=a.bbox('all'))

@timeit
def load_ctk():
    for i in range(1,201):
        b.create_window((5,40*i),window=ctk.CTkButton(b,text=str(i))
                        ,anchor='nw')
    b.config(scrollregion=b.bbox('all'))

@timeit
def load_ui():
    for i in range(1,201):
        c.add_button((5,50*i),text=str(i))
    c.config(scrollregion=c.bbox('all'))


r=Tk()
r.title('速度测试')
r.geometry('1400x750+5+5')

a=Canvas(r,width=400,bg='white')
a.pack(fill='y',padx=10,side='left')
a.create_window((5,5),window=ttk.Button(a,text='load tk',command=load_tk)
                ,anchor='nw')
def set_ay_view(event):
    a.yview_scroll(int(-1*(event.delta/120)), "units")
a.bind('<MouseWheel>',set_ay_view)

b=Canvas(r,width=400,bg='white')
b.pack(fill='y',padx=10,side='left')
b.create_window((5,5),window=ttk.Button(b,text='load ctk',command=load_ctk)
                ,anchor='nw')
def set_by_view(event):
    b.yview_scroll(int(-1*(event.delta/120)), "units")
b.bind('<MouseWheel>',set_by_view)

c=BasicTinUI(r,width=400,bg='white')
c.pack(fill='y',padx=10,side='left')
c.create_window((5,5),window=ttk.Button(c,text='load ui',command=load_ui)
                ,anchor='nw')
def set_cy_view(event):
    c.yview_scroll(int(-1*(event.delta/120)), "units")
c.bind('<MouseWheel>',set_cy_view)

r.mainloop()

测试结果

tkinter原生

效果:

在这里插入图片描述

耗时:0.2319960594177246秒

创建速度还是很快的,基本不会有拖拉的感觉,也就是说组件基本是一起创建的。但是因为一次只能看到20个按钮,仔细观察会发现从第一个到第二十个按钮实际上也有可感的、极小的时间差,如果能够显示200个按钮,这个时间差就会很明显了。此外,在滚动过程中,组件会出现掉帧、重叠现象。

CTK

效果:
在这里插入图片描述

耗时:1.3687105178833008秒

这个耗时就有点大了,可以感到明显的延时。此外,创建过程中还会看到单个控件画布元素创建的时间差,也就是单个控件也会出现渲染时差问题。在GitHub上有人提过这个问题,但是CTK的开发者还没有想好怎么解决。在滚动查看方面,CTK也会出现tkinter原生一样掉帧、重叠的问题。

当然,CTK的渲染引擎在控件细节、方法、配色、缩放等方面有很深造诣。

TinUI

效果:

在这里插入图片描述

耗时:0.06800603866577148秒

200个按钮真的是小意思,0.06秒的速度比人类平均反应速度还要快(稍逊于0.05秒的最快潜意识反应),察觉不到什么延时。滚动过程比较“丝滑”。

不过,TinUI还是有相对计算量大的渲染控件元素,可是毕竟基于画布自身绘制,速度还是会比tkinter窗口要快。

2022-7-23新测试 TinUI圆角按钮创建速度

效果:
在这里插入图片描述
耗时:0.07651877403259277

稍慢于TinUI的button。但是考虑到TinUI的button2(圆角按钮)需要额外计算边框元素和背景元素,这部分的计算和渲染速度还是挺快的。

结论

以TinUI耗时作为单位1,那么tkinter原生的耗时是TinUI的4倍。

而CustomTkinter的耗时则是TinUI的19倍!!!

换成速度的话(较准确值),那就是TinUI的元素控件创建速度是tkinter原生的3.3倍,是CTK的19.6倍。也就是说TinUI要创建4000个按钮才会有CTK一样的延时,而且在可视范围内仍然不会有延时的感觉。😏

本次测试还有众多需要完善的地方,感兴趣的开发者或爱好者可以自己玩玩。


结语

无论哪种tkinter控件库,都没有优劣之分,都应当依据自己的项目需求来使用。

🔆tkinter创新🔆

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值