tkinter 模块的最强辅助模块 —— tkintertools(万字详解)

—— 现在 tkintertools 模块已经上传到 PyPi 啦——

大家可以用 pip 下载该模块啦

特别注意:这篇文章是针对于 tkintertools 2.5.0 版本的,不是最新版!!!

此篇文章仅做参考(弃坑,不再更新),旧版语法已无法完全与新版兼容,新版更强大,更稳定,性能更好,建议去代码仓库里看使用教程!

大家 pip 下来的是最新的稳定版本,使用教程代码仓库里面:链接​​​​​

        或许大家在使用 tkinter 模块时总感觉 tkinter 模块的功能不够强大,有些功能需要自己实现,但是!现在,我为大家带来了这个 tkinter 模块的最强辅助模块 —— tkintertools

为什么强大?它可以做到以下操作或提供以下功能:

可透明可圆角化可自定义的控件;

自动控制图片大小和控件大小;

可缩放的 png 图片和可播放的 gif 图片;

④ 按一定规律或函数移动控件和画布界面;

渐变色对比色

长度和对齐方式可控的文本;

……

—— 本文章会随着模块的更新而进行动态修改 ——

模块基本信息

模块名称:tkintertools

模块描述:tkinter 模块的扩展模块

编写作者:小康2022

当前版本:2.5(2022/11/21)

运行要求Python3.10 及以上版本(新版只需要3.7以及3.7以上)

模块源代码下载地址tkintertools(最新版)

模块源代码仓库地址小康2022 / tkintertools · GitCode

模块结构

一、引用模块

sys:用于检测 Python 版本信息

② tkinter:基础模块

③ typing:用于类型提示

二、常量

COLOR_FILL_BUTTON = '#E1E1E1', '#E5F1FB', '#CCE4F7', '#F0F0F0'      # 默认的按钮内部颜色
COLOR_FILL_TEXT = '#FFFFFF', '#FFFFFF', '#FFFFFF', '#F0F0F0'        # 默认的文本内部颜色
COLOR_OUTLINE_BUTTON = '#C0C0C0', '#4A9EE0', '#4884B4', '#D5D5D5'   # 默认按钮外框颜色
COLOR_OUTLINE_TEXT = '#C0C0C0', '#5C5C5C', '#4A9EE0', '#D5D5D5'     # 默认文本外框颜色
COLOR_TEXT = '#000000', '#000000', '#000000', '#A3A9AC'             # 默认的文本颜色
COLOR_NONE = '', '', '', ''                                         # 透明颜色

BORDERWIDTH = 1     # 默认控件外框宽度
CURSOR = '│'        # 文本光标
FONT = '楷体', 15   # 默认字体
LIMIT = -1          # 默认文本长度
NULL = ''           # 空字符
RADIUS = 0          # 默认控件圆角半径

三、主体结构

1、容器控件类

Tk:窗口主体,具有处理关联事件和缩放控件及图像的能力

Toplevel: 顶级窗口,和 Tk 类似,但有着 tkinter 模块原来的 Toplevel 类同样的功能

③ Canvas:画布,用于承载虚拟控件和绘制其他细节

2、虚拟画布基类

_BaseWidget:内部类,虚拟画布控件基类

_TextWidget:内部类,虚拟画布文本控件基类

3、虚拟画布控件类

CanvasLabel:虚拟画布标签类

CanvasButton:虚拟画布按钮类

CanvasEntry:虚拟画布输入框类

CanvasText:虚拟画布文本框类

4、工具类

PhotoImage: 具有加载与缩放 png 图片和解析并播放 gif 图片的功能

5、功能函数

① move_widget:可按照按一定规则(函数)移动控件

② correct_text:修正文本长度,占有一定长度并使其居中、靠左或靠右

change_color:产生渐变色及对比色

四、测试程序

测试程序就是直接运行该模块本身的效果(该测试函数名为 test,可引入其并运行以查看测试效果) 。下面的效果就是测试程序运行的结果,说明一下,窗口带有一点透明效果,关闭窗口时会有一个关闭询问(忘记展示出来了 T_T)。这里只展示了虚拟控件的默认外观,它们也可以自定义外观,甚至可以透明,以方便大家使用背景图片来装饰我们的窗口!

1、基本测试

基本测试

2、图像测试

图像测试

3、颜色测试

颜色测试

模块使用方法

一、基本框架

1、基本框架代码

import tkintertools


root = tkintertools.Tk()  # 创建窗口
canvas = tkintertools.Canvas(root, 960, 540)  # 创建虚拟画布,960和540分别为长度和宽度
canvas.place(x=0, y=0)  # 放置画布
"""
这里写其他代码
"""
root.mainloop()  # 消息事件循环

 2、效果展示

代码基础框架

        是不是感觉和 tkinter 模块的基本框架差别不大,只是多了一个 Canvas 对吧?对!就这么简单,与原来的 tkinter 模块相比,改变的其实只有一个,那就是控件的承载容器变了。tkinter 模块里面是 Tk,而这里实际上是 Canvas,这一点很重要!

二、容器控件类

1、Tk

用于集中处理 Canvas 容器控件绑定的关联事件以及缩放操作

初始化参数说明

Tk(title: str | None = None,
   geometry: str | None = None,
   minisize: tuple[int, int] | None = None,
   alpha: float | None = None,
   proportion_lock: bool = False,
   shutdown=None,  # type: function | None
   **kw)

title: 窗口标题

geometry: 窗口大小及位置(格式:'宽度x高度+左上角横坐标+左上角纵坐标' 或者 '宽度x高度')

minisize: 窗口的最小缩放大小(为 None 时会自动改为参数 geometry 的匹配值)

alpha: 窗口透明度,范围为0~1,0为完全透明

proportion_lock: 窗口缩放是否保持原比例

shutdown: 关闭窗口之前执行的函数(会覆盖原来的关闭操作)

**kw: 与原 tkinter 模块中的 Tk 类的参数相同

是不是与原来 tkinter 模块里面的不一样呢?实际上,原 tkinter 模块里面对 Tk 类的一些操作(什么方法啊,函数啊之类的)都适用于这个新 Tk 类。

实例属性

width: 窗口的初始宽度

height: 窗口的初始高度

③ canvas_list: Tk 类所承载的 Canvas 类的列表

toplevel_list: Tk 类的所有子窗口 Toplevel 的列表

实例方法

与 tkinter 模块里面原生的 Tk 相同。

详细用法

这里就简单地给个示例吧。示例窗口略微带点透明度。

Tk 详细用法

以上示例的源代码如下:

import tkintertools
from tkinter.messagebox import askyesno


shutdown = lambda:root.quit() if askyesno('提示', '确认关闭吗?') else None
root = tkintertools.Tk('tkintertools辅助模块操作说明', '540x360', alpha=0.8, shutdown=shutdown)
root.mainloop()

上面代码中,关于 tkinter 的库(子库 messagebox)和 tkintertools 都用到了,也说明了 tkinter 模块和 tkintertools 模块是兼容的。 

2、Toplevel

用法类似于原 tkinter 模块里的 Toplevel,同时增加了 Tk 的功能

初始化参数说明

Toplevel(master: Tk,
         title: str | None = None,
         geometry: str | None = None,
         minisize: tuple[int, int] | None = None,
         alpha: float | None = None,
         proportion_lock: bool = False,
         shutdown=None,  # type: function | None
         **kw)

master: 父窗口,一般指 Tk (也可以是 Toplevel,即 Toplevel 的 Toplevel)

title: 窗口标题

geometry: 窗口大小及位置(格式:'宽度x高度+左上角横坐标+左上角纵坐标' 或者 '宽度x高度')

minisize: 窗口的最小缩放大小(为 None 时会自动改为参数 geometry 的匹配值)

alpha: 窗口透明度,范围为0~1,0为完全透明

proportion_lock: 窗口缩放是否保持原比例

shutdown: 关闭窗口之前执行的函数(会覆盖原来的关闭操作)

**kw: 与原 tkinter 模块中的 Toplevel 类的参数相同

其余的用法都和 Tk 类差不多啦。

实例属性

width: 新窗口的初始宽度

height: 新窗口的初始高度

③ canvas_list: Toplevel 类所承载的 Canvas 类的列表

toplevel_list: Toplevel 类的所有子窗口 Toplevel 的列表

实例方法

这个和 tkinter 原生的 Toplevel 一样啦。

3、Canvas

用于承载虚拟的画布控件

初始化参数说明

Canvas(master,  # type: Tk
       width: int,
       height: int,
       lock: bool = True,
       expand: bool = True,
       **kw)

master: 父控件(一般为 Tk 类,但其他容器控件也可)

width: 画布宽度

height: 画布高度

lock: 画布内控件的功能锁(False 时没有功能)

expand: 画布及其控件是否能缩放

**kw: 与原 tkinter 模块内 Canvas 类的参数相同

原来 tkinter 模块里面的 Canvas 类的一些方法仍然适用于该新的 Canvas 类,像什么绘制图形的,都可以。

实例属性

master: 父容器控件(只能是 tkintertools 的 Tk,不是 tkinter 模块的 Tk)

widget_list: Canvas 类所承载的所有虚拟画布控件的列表

lock: Canvas 的锁,为 False 时其承载的控件的功能全部失效(但没有删除)

width: 画布的初始宽度,不会改变

height: 画布的初始高度,不会改变

expand: 画布缩放的标识

⑦ rate_x: 横向缩放倍率,初始为 1

⑧ rate_y: 纵向缩放倍率,初始为 1

实例方法

setlock

setlock(boolean: bool)

设置 Canvas 的 lock 属性,并更新刚刚设为 True 的 Canvas 的大小以适应缩放状态

其余的实例方法均与 tkinter 模块里面原生的 Canvas 相同。

三、虚拟画布控件类

总体参数说明

下面是参数说明是适用于所有的虚拟画布控件类的 

标准参数

canvas: 父画布容器控件

x: 控件左上角的横坐标

y: 控件左上角的纵坐标

width, height: 控件的宽度与高度

radius: 控件的四个角圆角化的半径

text: 控件显示的文本,对于文本控件而言,可以为一个元组:(默认文本, 鼠标触碰文本)

justify: 文本的对齐方式

borderwidth: 外框的宽度

font: 控件的字体设定 (字体, 大小, 样式)

color_text: 控件文本的颜色

color_fill: 控件内部的颜色

color_outline: 控件外框的颜色

特定参数

command: 按钮控件的关联函数

show: 文本控件的显示文本

limit: 文本控件的输入字数限制,为负数时表示没有字数限制

space: 文本控件能否输入空格的标识

read: 文本控件的只读模式

cursor: 文本输入提示符的字符,默认为一竖线

详细说明

1、字体的值为一个包含两个值或三个值的元组,共两种形式

形式一:(字体名称, 字体大小)

形式二:(字体名称, 字体大小, 字体样式)

例如: ('微软雅黑', 15, 'bold') 

2、颜色为一个包含三个或四个 RGB 颜色字符串或颜色单词的元组

不使用禁用功能时: (正常颜色, 触碰颜色, 交互颜色)

需使用禁用功能时: (正常颜色, 触碰颜色, 交互颜色, 禁用颜色)

例如:('#F1F1F1', '#666666', 'springgreen', 'grey')

颜色设置为空字符代表透明!

3、当圆角化半径过大时,会自动取允许的最大值

总体实例属性说明

下面是所有的画布虚拟控件都有的实例属性。 

master: 父容器控件(只能是 Canvas)

live: 控件活跃的标识(可单独设置以对单个的控件进行控制,False 时控件功能失效)

③ text: 控件的文本,实际类型为 tkinter._CanvasItemId

④ radius: 圆角化半径

⑤ font: 控件字体

⑥ justify: 控件文本对齐方式

⑦ widthheight: 控件宽度与高度

⑧ color_text: 控件文本颜色

⑨ color_fill: 控件内部颜色

⑩ color_outline: 控件外框颜色

总体实例方法

下面是所有的画布虚拟控件都有的实例方法。

state

state(mode: Literal['normal', 'touch', 'press', 'disabled'] | None)

 改变控件的状态

mode: 状态的模式,可选 normal、touch、press、disabled 四种模式,或 None(默认值)

        normal: 一般状态,外观为颜色元组的第一个元素

        touch: 触碰状态,外观为颜色元组的第二个元素

        press: 按下状态,外观为颜色元组的第三个元素

        disabled: 禁用状态,外观为颜色元组的第四个元素

为 None 时表示更新控件的外观状态(强行修改外观后我们需要这个功能进行更新)

move

move(dx: float, dy: float)

 移动控件的位置(瞬移)

dx: 横向移动距离(单位:像素)

dy: 纵向移动距离

③ configure

configure(*args, **kw)

修改或查询部分参数的初始值

可供修改的参数有 text、color_text、color_fill 及 color_outline

        text: 显示的文本

        color_text: 控件文本的颜色

        color_fill: 控件内部的颜色

        color_outline: 控件外框的颜色

若只是以字符串的形式输入参数,则会返回名为该输入字符串的参数的值

【代码示例】

button = CanvasButton(...)
button.configure(text='新文本')

④ destroy

destroy()

没有参数,执行后将删除控件,控件将不复存在,释放内存 

set_live

set_live(boolean: bool | None = None)

 修改或查询控件的 live 参数

boolean: 为 bool 类型的值时,设置控件的 live 属性为 boolean,为 None (默认值)时,返回控件当前的 live 值

当 live 属性为 False 时,控件将处于禁用状态

1、CanvasLabel

创建一个虚拟的标签控件,用于显示少量文本

初始化参数

CanvasLabel(canvas: Canvas,
            x: int,
            y: int,
            width: int,
            height: int,
            radius: int = RADIUS,
            text: str = NULL,
            borderwidth: int = BORDERWIDTH,
            justify: str = tkinter.CENTER,
            font: tuple[str, int, str] = FONT,
            color_text: tuple[str, str, str] = COLOR_TEXT,
            color_fill: tuple[str, str, str] = COLOR_FILL_BUTTON,
            color_outline: tuple[str, str, str] = COLOR_OUTLINE_BUTTON)

默认外观

CanvasLabel 默认外观

详细用法

当然了,我们也可以给 CanvasLabel 加一些参数,使其外观符合我们的需求。

CanvasLabel 详细用法

该效果的源代码:

import tkintertools


root = tkintertools.Tk('tkinter辅助模块操作说明', '960x540', (960, 540))
canvas = tkintertools.Canvas(root, 960, 540)
canvas.place(x=0, y=0)
background = tkintertools.PhotoImage('background.png')
canvas.create_image(480, 270, image=background)

tkintertools.CanvasLabel(canvas, 100, 100, 300, 200, 0, '这是一个\n虚拟画布标签控件',
                         font=('华文行楷', 20),
                         color_fill=tkintertools.COLOR_NONE,  # 内部透明
                         color_outline=('grey', 'springgreen', ''))
"""
CanvasLabel的颜色参数元组的最后一个元素实际没有意义
最后一个是控件被点击时的外观
然鹅,CanvasLabel是没有点击事件的
"""

root.mainloop()

2、CanvasButton

创建一个虚拟的按钮,并执行关联函数

初始化参数

CanvasButton(canvas: Canvas,
             x: int,
             y: int,
             width: int,
             height: int,
             radius: int = RADIUS,
             text: str = NULL,
             borderwidth: int = BORDERWIDTH,
             justify: str = tkinter.CENTER,
             font: tuple[str, int, str] = FONT,
             command=None,  # type: function | None
             color_text: tuple[str, str, str] = COLOR_TEXT,
             color_fill: tuple[str, str, str] = COLOR_FILL_BUTTON,
             color_outline: tuple[str, str, str] = COLOR_OUTLINE_BUTTON)

默认外观

CanvasLabel 默认外观

详细用法

按钮的操作就比较多了,不仅外观可以改变,也可以像原版的 tkinter 一样执行关联函数(command 参数写法一样)。

CanvasButton 详细用法

实现上面效果的源代码:

import tkintertools


root = tkintertools.Tk('tkinter辅助模块操作说明', '960x540', (960, 540))
canvas = tkintertools.Canvas(root, 960, 540)
canvas.place(x=0, y=0)
background = tkintertools.PhotoImage('background.png')
canvas.create_image(480, 270, image=background)
test = canvas.create_rectangle(200, 200, 250, 250, fill='black', width=0)

callback = lambda: canvas.itemconfigure(test, fill='red' if canvas.itemcget(test, 'fill') == 'black' else 'black')

tkintertools.CanvasButton(canvas, 100, 100, 150, 30, 0, '按钮',
                          command=callback,
                          color_text=('grey', 'black', 'black'),
                          color_fill=('', 'yellow', 'orange'),
                          color_outline=('grey', 'yellow', 'orange'))


root.mainloop()

3、CanvasEntry

创建一个虚拟的输入框控件,可输入单行少量字符,并获取这些字符

初始化参数

CanvasEntry(canvas: Canvas,
            x: int,
            y: int,
            width: int,
            height: int,
            radius: int = RADIUS,
            text: tuple[str] | str = NULL,
            show: str | None = None,
            limit: int = LIMIT,
            space: bool = False,
            cursor: str = CURSOR,
            borderwidth: int = BORDERWIDTH,
            justify: str = tkinter.LEFT,
            font: tuple[str, int, str] = FONT,
            color_text: tuple[str, str, str] = COLOR_TEXT,
            color_fill: tuple[str, str, str] = COLOR_FILL_TEXT,
            color_outline: tuple[str, str, str] = COLOR_OUTLINE_TEXT)

实例方法

get

get()

获取输入框的输入的值,无参数

set

set(value: str)

设置输入框的值

value: 要修改的值

append

append(value: str)

 给输入框添加值

value: 添加的值,用法类比与列表的 append 方法

默认外观

CanvasEntry 默认外观

详细用法

这个输入框,功能还算比较完整,可以输入一些允许的文本,有默认值,提示值,以及特殊的显示(如密码显示为黑圆点),可以限制文本输入长度,等等……

但是还有一些功能没有做到,如选中一些输入的文本、快捷键全选(Ctrl+A)、复制等等(粘贴还是做到了),这些我会努力去实现的。

关于输入框一些属性

read: 输入框的只读模式的标识

space: 输入框是否能输入空格的标识

icursor: 输入框文本输入提示符的字符

value_surface: 表面的值,一般和 value 一样,但 show 属性有值的时候为若干个 show 的值

value_normal: 一般显示文本,即鼠标未在输入框上面时显示文本

value_touch: 鼠标触碰到的值,即鼠标放在输入框上面但未点下去时显示的文本

show: 输入文本后对外显示的值,与原 tkinter 里 Entry 的 show 参数一样的效果

limit: 文本长度的限制(一般字符长度算 1,中文字符长度算 2 个),为负数时表示无限制

下面就展示一个用法的实例:

CanvasEntry 详细用法

实现上面效果的源代码:

import tkintertools


root = tkintertools.Tk('tkinter辅助模块操作说明', '960x540')
canvas = tkintertools.Canvas(root, 960, 540)
canvas.place(x=0, y=0)
background = tkintertools.PhotoImage('background.png')
canvas.create_image(480, 270, image=background)

tkintertools.CanvasEntry(
    canvas, 380, 370, 200, 25, 0, ('账号', '点击输入'),
    color_fill=tkintertools.COLOR_NONE,  # 内部始终透明
    color_text=('white', 'white', 'white'),
    color_outline=('white', 'springgreen', 'springgreen'))
tkintertools.CanvasEntry(
    canvas, 380, 400, 200, 25, 0, ('密码', '点击输入'), '•',
    color_fill=tkintertools.COLOR_NONE,  # 内部始终透明
    color_text=('white', 'white', 'white'),
    color_outline=('white', 'springgreen', 'springgreen'))


root.mainloop()

4、CanvasText

创建一个透明的虚拟文本框,用于输入多行文本和显示多行文本(只读模式)

初始化参数

CanvasText(canvas: Canvas,
           x: int,
           y: int,
           width: int,
           height: int,
           radius: int = RADIUS,
           text: tuple[str] | str = NULL,
           limit: int = LIMIT,
           space: bool = True,
           read: bool = False,
           cursor: bool = CURSOR,
           borderwidth: int = BORDERWIDTH,
           justify: str = tkinter.LEFT,
           font: tuple[str, int, str] = FONT,
           color_text: tuple[str, str, str] = COLOR_TEXT,
           color_fill: tuple[str, str, str] = COLOR_FILL_TEXT,
           color_outline: tuple[str, str, str] = COLOR_OUTLINE_TEXT)

实例方法

get

get()

获取文本框中的值,没有参数

② set

set(value: str)

重新设定显示文字

value: 要修改的值

③ append

append(value: str)

给文本框添加一些文本

value: 要添加的文本,用法类比于列表的 append 方法

默认外观

CanvasText 默认外观

详细用法

这个文本框呢,功能描述和上面的输入框(CanvasEntry)差不多的,但是还是有一些不同。

比如,文本框里面默认是可以输入空格符号的,而输入框默认不行(可通过 space 参数修改)。

其次,如果这个文本框的 limit 参数设置的比较大,且 read 参数为 True 时,那在超过了文本框显示的范围之后,它会只显示一部分……还有很多特性。

关于文本框一些属性

read: 输入框的只读模式的标识

space: 输入框是否能输入空格的标识

icursor: 输入框文本输入提示符的字符

value_surface: 表面的值,一般和 value 一样,但文本过多时,两者不一样

value_normal: 一般显示文本,即鼠标未在输入框上面时显示文本

value_touch: 鼠标触碰到的值,即鼠标放在输入框上面但未点下去时显示的文本

limit: 文本长度的限制(一般字符长度算 1,中文字符长度算 2 个),为负数时表示无限制

下面展示一个实例:(更好的实例可以去后面的“实战效果展示”中查看)

CanvasText 详细用法

实例的源代码:

import tkintertools


root = tkintertools.Tk('tkinter辅助模块操作说明', '960x540')
canvas = tkintertools.Canvas(root, 960, 540)
canvas.place(x=0, y=0)
background = tkintertools.PhotoImage('background.png')
canvas.create_image(480, 270, image=background)

tkintertools.CanvasText(canvas, 100, 100, 300, 150, 0,
                        color_text=('grey', 'white', 'white'),
                        color_fill=tkintertools.COLOR_NONE,
                        color_outline=('grey', 'white', 'white'))


root.mainloop()

四、工具类

PhotoImage

这个就是原 tkinter 模块的 PhotoImage 类的强化版

仍是只支持 png 和 gif 格式的图片,但可以很好的处理 gif 的格式,且提供对 png 图片的缩放操作

参数说明

PhotoImage(file: str | bytes, **kw)

file: 文件路径,和原 tkinter 模块里的 PhotoImage 一样的参数

**kw: 其他参数,为了兼容原 tkinter 模块里的 PhotoImage 的其他参数

实例方法

parse

parse()

用于解析动图,没有参数,返回一个生成器(Generator)

play

play(canvas: Canvas,
     id,  # type: tkinter._CanvasItemId
     interval: int)

用于播放动图(播放条件:canvas 的 lock 属性的值为 True)

canvas: 播放动画的画布

id: 播放动画的 _CanvasItemId(就是 create_text 的返回值)

interval: 每帧动画的间隔时间(单位:毫秒)

zoom

zoom(rate_x: float, rate_y: float, precision: float = 1)

缩放图片(目前返回值为原 tkinter 的 PhotoImage 类)

暂时只支持对 png 格式图片的缩放,gif 格式的仍在测试中……

rate_x: 横向缩放倍率

rate_y: 纵向缩放倍率

precision: 精度到小数点后的位数,越大运算就越慢

详细用法

如果是 png 格式的图片,用法和原 tkinter 模块里的 PhotoImage 用法一模一样,没有任何改变,主要是对 gif 格式图片有所改变。

首先是,读取 gif 格式的图片时,不需要再写 format 参数了,自动读取并解析每一帧的动画。先实例化一个 gif 格式的图片的 PhotoImage 类,然后再解析它,可以一次性解析它全部的帧数,但考虑到大的动图解析很慢,所以就将解析方法的返回值改成了生成器,以便在外部用协程的方式去迭代它,以实现进度条的功能。这里说的很抽象,具体看下面的示例。

动图播放

上述效果的源代码:

import tkintertools


root = tkintertools.Tk('tkinter辅助模块操作说明', '960x540')
canvas = tkintertools.Canvas(root, 960, 540, bg='black')
canvas.place(x=0, y=0)


# 用来播放动图的 _CanvasItemId
background = canvas.create_image(480, 270)

# 创建 PhotoImage 类
image = tkintertools.PhotoImage('background.gif')

# 解析每一帧的图片
for i in image.parse():
    # 每次读取的返回值为当前已解析的帧数
    print(i)

# 播放动图
image.play(canvas, background, 70)


root.mainloop()

上述代码执行后并不是立刻就会弹出窗口的,因为它此时正在解析,在命令行上会看到打印出的当前已解析的帧数。解析完后窗口会立刻弹出并播放动图。

解析的方法设计成这样,一是避免解析大动图(帧数很多)时造成卡顿,二是可以实现进度条的效果,实时查看解析的进度,这样当我们在写大项目的时候,一开始要解析很多动图时,就可以这样把所有的动图整合起来,一次性加载,顺便搞个进度条。而且!最重要的是!这样加载动图并实现进度条的功能,是不需要多线程的参与的!实现这些的功能是最简单的协程 —— yield 关键字!

当然了,也可以用错误捕捉加上 next 函数去迭代生成器以实现进度条的功能:

进度条

上述产生进度条的源代码:

import tkintertools


root = tkintertools.Tk('tkinter辅助模块操作说明', '960x540')
canvas = tkintertools.Canvas(root, 960, 540, bg='black')
canvas.place(x=0, y=0)


# 用来播放动图的 _CanvasItemId
background = canvas.create_image(480, 270)

# 创建 PhotoImage 类
image = tkintertools.PhotoImage('background.gif')

# 创建生成器
generator = image.parse()

# 创建进度条
canvas.create_rectangle(60, 450, 900, 480, outline='orange', width=2)
bar = canvas.create_rectangle(60, 450, 60, 480, width=0, fill='lightgreen')


def load():
    """ 加载函数 """
    try:
        # 解析下一帧
        i = next(generator)
        # 修改进度条的长度
        canvas.coords(bar, 60, 450, 60 + i * 20, 480)
        # 再次执行该函数,间隔1毫秒
        root.after(1, load)
    except:
        # 播放动图
        image.play(canvas, background, 70)


load()
root.mainloop()

关于缩放,那就很简单了嘛,但是!你可以去网上找找,看看有没有不用 PIL 库就可以实现缩放图片的,我曾经找过,几乎没有!然鹅,我这里在不引入第三方库的情况下,实现了!虽然在计算速度上可能比 PIL 库稍差一点,但是也足以满足我们的需求!

回到缩放的方法上,precision 参数可以是浮点数,默认为 1,那么缩放的倍率呢就支持到小数点后一位,多了也不精准。顺便一提,将 precision 提升至 2 的话,计算量和计算时间会增长 10 倍!因此,若非对精度有很高的要求,建议把 precision 设在 1.5 以下为好。

这里还要附加地说明一个缺点,这个缺点不是我这个模块造成的,而是原 tkinter 模块就有这个缺陷。就是原 tkinter 的 PhotoImage 的示例对象必须是全局变量的情况下,才能显示其图片,否则只是一片空白,所以用 zoom 进行缩放后得到的图片,记得要“全局化”后再调用!

五、功能函数

1、move_widget

控件移动函数

以特定方式移动由 Place 布局的某个控件或某些控件的集合或图像

参数说明

move_widget(master: Tk | Canvas | tkinter.Misc | tkinter.BaseWidget,
            widget: Canvas | _BaseWidget | tkinter.BaseWidget,
            dx: int,
            dy: int,
            times: int,
            mode: # type: Literal['smooth', 'rebound', 'flat'] | tuple[function, float, float]
)

master: 控件所在的父控件

widget: 要移动位置的控件

dx: 横向移动的距离(单位:像素)

dy: 纵向移动的距离

times: 移动总时长(单位:秒)

mode: 模式,可选三种

        smooth: 速度先慢后快再慢(Sin函数模式,0~π)

        rebound: 和 smooth 一样,但是最后会回弹一下(Cos函数模式,0~0.6π)

        flat: 匀速平移

或者为一个元组的形式:(移动函数, 起始值,终止值)

详细用法

这个函数不仅仅可以对本模块的控件产生效果,对所有原 tkinter 模块的控件也有同样的效果。

有了它,我们可以很轻松的实现以下效果:(鼠标左键按下弹出提示框)

【默认外观】

默认外观-提示框

源代码:

import tkintertools


root = tkintertools.Tk('tkinter辅助模块操作说明', '960x540')
canvas = tkintertools.Canvas(root, 960, 540)
canvas.place(x=0, y=0)


def callback():
    """ 键盘关联函数 """
    tip = tkintertools.CanvasLabel(canvas, 700, 550, 250, 100, 0, '— 提示 —\n恭喜你!\n账号登录成功!')
    tkintertools.move_widget(canvas, tip, 0, -120, 0.3, 'rebound')


# 按下鼠标左键执行关联函数(当然,其他函数的触发方式也可)
root.bind('<Button-1>', lambda _: callback())
root.mainloop()

【换上皮肤】

换上皮肤-提示框

源代码:

import tkintertools


root = tkintertools.Tk('tkinter辅助模块操作说明', '960x540')
canvas = tkintertools.Canvas(root, 960, 540)
canvas.place(x=0, y=0)
background = tkintertools.PhotoImage('background.png')
canvas.create_image(480, 270, image=background)


def callback():
    """ 键盘关联函数 """
    tip = tkintertools.CanvasLabel(canvas, 700, 550, 250, 100, 0, '— 提示 —\n恭喜你!\n账号登录成功!',
                                   color_fill=tkintertools.COLOR_NONE,
                                   color_text=('grey', 'white', ''),
                                   color_outline=('grey', 'white', ''))
    tkintertools.move_widget(canvas, tip, 0, -120, 0.3, 'rebound')


# 按下鼠标左键执行关联函数(当然,其他函数的触发方式也可)
root.bind('<Button-1>', lambda _: callback())
root.mainloop()

同样的道理,我们也可以让它在适当的时候,再收回去,然后删除它以释放内存。这样,一个提示框的功能就轻易实现了!

又或者我们可以实现一个界面切换的操作(移动 Canvas 控件):

界面切换

上述例子的源代码:

import tkintertools


root = tkintertools.Tk('界面切换', geometry='960x540')
canvas_1 = tkintertools.Canvas(root, 960, 540, bg='lightgreen')
canvas_2 = tkintertools.Canvas(root, 960, 540, bg='skyblue')
canvas_1.place(x=0, y=0)
canvas_2.place(x=960, y=0)

tkintertools.CanvasButton(
    canvas_1, 830, 500, 120, 30, 5, '切换界面',
    command=lambda: (tkintertools.move_widget(root, canvas_1, -960, 0, 0.25, 'smooth'),
                     tkintertools.move_widget(root, canvas_2, -960, 0, 0.25, 'smooth')))
tkintertools.CanvasButton(
    canvas_2, 10, 500, 120, 30, 5, '切回界面',
    command=lambda: (tkintertools.move_widget(root, canvas_1, 960, 0, 0.25, 'smooth'),
                     tkintertools.move_widget(root, canvas_2, 960, 0, 0.25, 'smooth')))


root.mainloop()

2、correct_text

修正字符串长度

可将目标字符串改为目标长度并以某种方式对齐

参数说明

correct_text(length: int, 
             string: str, 
             position: Literal['left', 'center', 'right'] = 'center')

length: 目标长度

string: 要修改的字符串

position: 文本处于该长度范围的位置,可选靠左、居中、靠右三个值

        left: 文本靠左

        center: 文本居中

        right: 文本靠右

详细用法

这个就很简单了,一般用于多行文本和单行多个文本之间的对齐,直接给出一个示例吧。

print(tkintertools.correct_text(20, '这是个文本'))
""" 输出
    tkintertools    #到这里截止
"""

实战中就是像下面这样的:

correct_text 详细用法

这里每一列的文本长度都不是一定,所以就用 correct_text 函数改变它们的长度,并让其居中以达到对齐的效果。

3、change_color

颜色处理函数

按一定比率给出已有 RGB 颜色字符串的渐变 RGB 颜色字符串或其对比色

change_color(color: tuple[str, str] | list[str, str] | str, proportion: float = 1)

color: 颜色元组 (要修改的颜色, 目标颜色),或者一个颜色(返回其对比色)

proportion: 改变比率,默认为 1

详细用法

这个很简单,就是按着参数的来就行,下面给个实例:

渐变色的效果

效果展示的代码:

import tkintertools
from math import sin, pi


root = tkintertools.Tk('tkinter辅助模块操作说明', '960x540')
canvas = tkintertools.Canvas(root, 960, 540)
canvas.place(x=0, y=0)


for i in range(700):
    canvas.create_line(
        (100 + i) * canvas.rate_x,
        100 * canvas.rate_x,
        (100 + i) * canvas.rate_x,
        400 * canvas.rate_y,
        fill=tkintertools.change_color(('#0000FF', '#00FF00'), sin(pi*i/700)), width=2)


root.mainloop()

更加逼真的效果:

逼真的渐变色

怎么样?看起来是不是有内味儿了?源代码在下面:

import tkintertools


root = tkintertools.Tk('tkinter辅助模块操作说明', '960x540')
canvas = tkintertools.Canvas(root, 960, 540, bg='white')
canvas.place(x=0, y=0)


for i in range(200):
    color = tkintertools.change_color(('#FFFFFF', '#000000'), i/200)
    canvas.create_oval(200 - i/2, 200 - i/2, 300 + i, 300 + i, outline=color, width=2)


root.mainloop()

又或者说,我们可以用这个渐变色啊,干点好玩的事情……

变幻色按钮

上面骚操作的源代码如下:

import tkintertools
from random import randint


root = tkintertools.Tk('tkinter辅助模块操作说明', '960x540')
canvas = tkintertools.Canvas(root, 960, 540)
canvas.place(x=0, y=0)


def colorful(ind=0, color=[None, '#F1F1F1']):
    """ 颜色变幻函数 """
    if not ind:
        color[0], color[1] = color[1], '#%06X' % randint(0, 1 << 24)
    colorful_button.color_fill[0] = tkintertools.change_color(color, ind)
    colorful_button.state()  # 更新按钮外观
    root.after(10, colorful, 0 if ind >= 1 else ind+0.01)


colorful_button = tkintertools.CanvasButton(
    canvas, 100, 100, 120, 30, 0, '颜色变幻', command=colorful)


root.mainloop()

后记

看了这么多,你了解到这个辅助模块有多强大了么?它基本上只用原 tkinter 模块(typing 只用来进行类型提示,sys 只用来检测 Python 版本)就做出了这些功能,不知道是否让你满意呢?如果你认为可以,那是否可以为我点一个小小的赞呢?

求点赞!求收藏!求评论!求分享!

目前该模块的制作者只有我一个人,我会继续加油努力的!

模块源代码下载地址:tkintertools

模块源代码仓库地址:小康2022 / tkintertools · GitCode

更多知识专栏:Python Tkinter 桌面应用程序开发专栏


—— 文章更新于 2022/11/22 ——

  • 36
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 44
    评论
这是一个VB6的IDE插件(Addin),使用VB6的IDE直接设计Python的界面。 Python和VB都是能让人快乐的编程语言,我使用了Python之后,很多自己使用的工具都使用Python开发或改写了,因为最终实现的Python代码实在太短了(相比VB),有时候Python一行代码就可以实现VB一个函数的功能。 Python就是这种让人越用越开心的语言。 不过说实在,使用Python开发GUI界面还是麻烦了一些了,自带的标准库Tkinter使用起来非常简单,不过对于习惯了VB拖放控件完成界面设计的同学来说,还是不够人性化。TK也有一个工具叫GUI Builder,不过它使用Layout布局,不够直观,而且界面简陋,用起来也不爽。 至于PyQt/wxPython等GUI库,尽管有可视化设计工具,但总感觉做一般的轻量级应用是杀鸡用牛刀,学习起来也比较复杂,而且不够环保,不够低碳,要带一个很大的库,需要目标机器上夜同样安装了PyQt/wxPython,做不了绿色软件。 所以最终的结果是我更喜欢Tkinter,用起来很简单,绿色环保,真正的跨平台,一个py文件到处运行(担心泄密就编译成pyc)。 很多人都认为TK的界面不够美观,不过导入Python自带的标准TTK主题库,界面非常Native,不输PyQt/wxPython。 此Addin默认启用TTK支持,也可选择关闭。 总而言之,轻量级GUI,TK+TTK足够。 使用此Addin,你可以不用写一句代码就可以生成一个完整可运行的Python的GUI界面,支持python 2.X和3.X。 安装方法:将压缩包解压到你希望的目录,然后执行Setup.exe完成注册插件过程,打开VB6就可以用了。 在VB窗体上设计完成界面后(你可以大胆的设置各控件的属性,Addin尽量将其翻译为tkinter的控件属性),点工具栏上的VisualTkinter(图标为一片橙红色羽毛),再点'生成代码'按钮,即可生成可运行的Python代码,可以拷贝至剪贴板或保存至文件。 一般情况下你可以不用再改变tkinter的控件属性,但是如果你熟悉tkinter,需要更多的控制,可以一一核对各属性,并且修改,再生成代码。 除了用来设计界面外,此ADDIN内置的各控件属性列表可以做为编程参考,比较完整,除了极少数我认为大多数人都不用的属性外,属性定义基本上是我从官方的tkinter文档直接翻译的。 如果还没有VB6,网上找一个VB6精简版即可(建议使用12M的版本,6M的版本也可以使用,不过工具栏图标无法显示,可以通过菜单执行此插件)。 经过网友测试,完美支持WinXP,Windows 7, Windows 8。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小康2022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值