The strongest auxiliary module of the tkinter module - tkintertools (detailed explanation)

——Now the tkintertools module has been uploaded to PyPi——

You can download this module with pip

Special Note: This article is for tkintertools version 2.5.0, not the latest version (I will update this old tutorial when I have time)! What you pip down is the latest stable version, use the tutorial code warehouse: [ link ]

        Perhaps when you use the tkinter module, you always feel that the functions of the tkinter module are not powerful enough, and some functions need to be implemented by yourself, but! Now, I bring you the most powerful auxiliary module of this tkinter module - tkintertools !

Why strong? It can do or provide the following functionality:

Transparent , rounded and customizable controls;

②Automatically control the size of the picture and the size of the control;

Scalable png  images and playable gif  images;

④ Move controls and canvas interface according to certain rules or functions ;

Gradient color and contrasting color ;

Text with controllable length and alignment ;

……

—— This article will be dynamically modified as the module is updated——

Module Basic Information

Module Name : tkintertools

Module Description : An extension module for the tkinter module

Author : Xiaokang 2022

Current version : 2.5 (2022/11/21)

Running requirements : Python3.10  and above

Module source code download address : tkintertools (latest version)

Module source code warehouse address : Xiaokang 2022 / tkintertools · GitCode

modular structure

1. Reference module

sys : used to detect Python version information

②  tkinter : basic module

③  typing : used for type hints

Two, constant

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          # 默认控件圆角半径

3. Main structure

1. Container control class

Tk : window body, with the ability to handle associated events and zoom controls and images

Toplevel : top-level window, similar to Tk, but has the same function as the original Toplevel class of the tkinter module

③  Canvas : Canvas, used to host virtual controls and draw other details

2. Virtual canvas base class

_BaseWidget : internal class, base class of virtual canvas control

_TextWidget : internal class, base class of virtual canvas text control

3. Virtual canvas control class

CanvasLabel : virtual canvas label class

CanvasButton : virtual canvas button class

CanvasEntry : virtual canvas input box class

CanvasText : virtual canvas text box class

4. Tools

PhotoImage : It has the functions of loading and scaling png images and parsing and playing gif images

5. Functions

①  move_widget : You can move the widget according to certain rules (functions)

②  correct_text : Correct the text length, occupy a certain length and make it centered, left or right

change_color : Generate gradient and contrasting colors

4. Test procedure

The test program is the effect of directly running the module itself (the test function is called test, which can be introduced and run to see the test effect). The following effect is the result of running the test program. To explain, the window has a little transparency effect, and there will be a closing query when closing the window (forgot to show T_T) . Here only the default appearance of the virtual controls is shown, they can also customize the appearance, even transparent, so that everyone can use background images to decorate our windows!

1. Basic test

basic test

2. Image test

image test

3. Color test

color test

How to use the module

1. Basic framework

1. Basic framework code

import tkintertools


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

 2. Effect display

code base framework

        Does it feel that it is not much different from the basic framework of the tkinter module, but there is an extra Canvas, right? right! It's that simple. Compared with the original tkinter module, there is actually only one change, that is, the container of the control has changed. Inside the tkinter module is Tk, but here is actually a Canvas, which is very important!

2. Container control class

1、Tk

Used to centralize the associated events bound to the Canvas container control and zoom operations

Description of initialization parameters

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 : window title

geometry : window size and position (format: 'width x height + abscissa of upper left corner + ordinate of upper left corner' or 'width x height')

minisize : The minimum zoom size of the window (when it is None, it will be automatically changed to the matching value of the parameter geometry)

alpha : window transparency, range is 0~1, 0 is completely transparent

proportion_lock : Whether to keep the original ratio of window scaling

shutdown : the function to be executed before closing the window (will override the original closing operation)

**kw : The same parameters as the Tk class in the original tkinter module

Is it different from the original tkinter module? In fact, some operations (methods, functions, etc.) on the Tk class in the original tkinter module are applicable to this new Tk class.

instance attribute

width : the initial width of the window

height : the initial height of the window

③  canvas_list : A list of Canvas classes carried by the Tk class

toplevel_list : A list of all sub-windows Toplevel of the Tk class

instance method

Same as native Tk in the tkinter module.

Detailed usage

Here is a simple example. The sample window is slightly transparent.

Detailed usage of Tk

The source code for the above example is as follows:

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()

In the above code, both the tkinter library (sublibrary messagebox) and tkintertools are used, which also shows that the tkinter module and the tkintertools module are compatible

2、Toplevel

The usage is similar to the Toplevel in the original tkinter module, while adding the function of Tk

Description of initialization parameters

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 : the parent window, generally refers to Tk (it can also be Toplevel, that is, the Toplevel of Toplevel)

title : window title

geometry : window size and position (format: 'width x height + abscissa of upper left corner + ordinate of upper left corner' or 'width x height')

minisize : The minimum zoom size of the window (when it is None, it will be automatically changed to the matching value of the parameter geometry)

alpha : window transparency, range is 0~1, 0 is completely transparent

proportion_lock : Whether to keep the original ratio of window scaling

shutdown : the function to be executed before closing the window (will override the original closing operation)

**kw : Same as the parameter of the Toplevel class in the original tkinter module

The rest of the usage is almost the same as the Tk class.

instance attribute

width : the initial width of the new window

height : the initial height of the new window

③  canvas_list : list of Canvas classes carried by the Toplevel class

toplevel_list : List of all sub-windows Toplevel of the Toplevel class

instance method

This is the same as tkinter's native Toplevel.

3、Canvas

Canvas controls for hosting virtual

Description of initialization parameters

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

master : parent control (usually Tk class, but other container controls are also available)

width : canvas width

height : canvas height

lock : the function lock of the control in the canvas (no function when False)

expand : Whether the canvas and its controls can be zoomed

**kw : the same as the parameters of the Canvas class in the original tkinter module

Some methods of the Canvas class in the original tkinter module are still applicable to the new Canvas class, such as drawing graphics.

instance attribute

master : parent container control (only Tk of tkintertools, not Tk of tkinter module)

widget_list : A list of all virtual canvas controls hosted by the Canvas class

lock : Canvas lock, when it is False, all the functions of the controls it carries are invalid (but not deleted)

width : The initial width of the canvas, which will not change

height : The initial height of the canvas, which will not change

expand : Canvas scaling logo

⑦  rate_x : Horizontal zoom ratio, initially 1

⑧  rate_y : vertical zoom ratio, initially 1

instance method

setlock

setlock(boolean: bool)

Set the lock property of the Canvas, and update the size of the Canvas just set to True to accommodate the zoom state

The rest of the instance methods are the same as the native Canvas in the tkinter module.

3. Virtual canvas control class

Overall parameter description

The following parameter descriptions are applicable to all virtual canvas control classes 

standard parameters

canvas : parent canvas container control

x : the abscissa of the upper left corner of the control

y : the vertical coordinate of the upper left corner of the control

width , height : the width and height of the control

radius : the radius of the four corners of the control to be rounded

text : the text displayed by the control, for a text control, it can be a tuple: (default text, mouse touch text)

justify : the alignment of the text

borderwidth : the width of the border

font : the font setting of the control (font, size, style)

color_text : the color of the control text

color_fill : the color inside the control

color_outline : the color of the control outline

specific parameters

command : the associated function of the button control

show : the display text of the text control

limit : the input word limit of the text control, when it is a negative number, it means there is no word limit

space : Whether the text control can enter a space

read : read-only mode of the text control

cursor : the character of the text input prompt, the default is a vertical bar

Detailed description

1. The value of the font is a tuple containing two or three values, in two forms

Form 1: (font name, font size)

Form 2: (font name, font size, font style)

For example: ('Microsoft Yahei', 15, 'bold') 

2. Color is a tuple containing three or four RGB color strings or color words

When not using disable function: (normal color, touch color, interactive color)

When disable function is required: (normal color, touch color, interactive color, disabled color)

For example: ('#F1F1F1', '#666666', 'springgreen', 'grey')

The color is set to an empty character to represent transparency!

3. When the fillet radius is too large, it will automatically take the maximum value allowed

General instance attribute description

The following are the instance properties that all canvas virtual controls have. 

master : parent container control (canvas only)

live : The indicator that the control is active (can be set separately to control a single control, when False, the control function will be invalid)

③  text : the text of the control, the actual type is tkinter._CanvasItemId

④  radius : fillet radius

⑤  font : control font

⑥  justify : control text alignment

⑦  width , height : control width and height

⑧  color_text : control text color

⑨  color_fill : internal color of the control

⑩  color_outline : Control outline color

overall instance method

The following are the instance methods that all canvas virtual controls have.

state

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

 change the state of the control

mode : the mode of the state, four modes can be selected: normal, touch, press, disabled, or None (default value)

        normal : normal state, the appearance is the first element of the color tuple

        touch : touch state, the appearance is the second element of the color tuple

        press : the pressed state, the appearance is the third element of the color tuple

        disabled : Disabled state, the appearance is the fourth element of the color tuple

When it is None, it means to update the appearance state of the control (we need this function to update after forcibly modifying the appearance)

move

move(dx: float, dy: float)

 Move the position of the control (teleport)

dx : lateral movement distance (unit: pixel)

dy : Vertical movement distance

③ configure

configure(*args, **kw)

Modify or query the initial value of some parameters

The parameters that can be modified are text, color_text, color_fill and color_outline

        text : the displayed text

        color_text : the color of the control text

        color_fill : the color inside the control

        color_outline : the color of the control outline

If the parameter is only input as a string, the value of the parameter named the input string will be returned

【Code example】

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

④ destroy

destroy()

Without parameters, the control will be deleted after execution, the control will no longer exist, and the memory will be released 

set_live

set_live(boolean: bool | None = None)

 Modify or query the live parameters of the control

boolean : When it is a value of bool type, set the live property of the control to boolean, and when it is None (default value), return the current live value of the control

When the live property is False, the control will be disabled

1、CanvasLabel

Create a dummy label control for displaying small amounts of text

Initialization parameters

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)

default appearance

CanvasLabel default appearance

Detailed usage

Of course, we can also add some parameters to CanvasLabel to make its appearance meet our needs.

Detailed usage of CanvasLabel

Source code for this effect:

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

Create a virtual button and execute the associated function

Initialization parameters

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)

default appearance

CanvasLabel default appearance

Detailed usage

There are more operations on the button, not only the appearance can be changed, but also the associated function can be executed like the original tkinter (command parameter is written in the same way).

Detailed usage of CanvasButton

The source code to achieve the above effect:

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

Create a virtual input box control that can input a few characters in a single line and get these characters

Initialization parameters

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)

instance method

get

get()

Get the input value of the input box, no parameters

set

set(value: str)

Set the value of the input box

value : the value to modify

append

append(value: str)

 Add value to input box

value : the added value, the usage is analogous to the append method of the list

default appearance

CanvasEntry default appearance

Detailed usage

The function of this input box is relatively complete, you can enter some allowed text, there are default values, prompt values, and special display (such as passwords are displayed as black dots), you can limit the length of text input, etc...

However, there are still some functions that have not been implemented, such as selecting some input text, shortcut keys to select all (Ctrl+A), copying, etc. (pasting is still possible), I will work hard to achieve these.

[ About some attributes of the input box ]

read : the identifier of the read-only mode of the input box

space : Whether the input box can enter a space

icursor : the character of the input box text input prompt

value_surface : The value of the surface, generally the same as value, but when the show attribute has a value, it is several show values

value_normal : The text is generally displayed, that is, the text is displayed when the mouse is not over the input box

value_touch : The value touched by the mouse, that is, the text displayed when the mouse is placed on the input box but not clicked down

show : The value displayed externally after entering the text, which has the same effect as the show parameter of Entry in the original tkinter

limit : the limit of the text length (the length of a general character counts as 1, and the length of a Chinese character counts as 2), when it is a negative number, it means unlimited

An example of usage is shown below:

Detailed usage of CanvasEntry

The source code to achieve the above effect:

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

Creates a transparent dummy text box for entering and displaying multiple lines of text (read-only mode)

Initialization parameters

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)

instance method

get

get()

Get the value in the textbox, no parameters

② set

set(value: str)

reset display text

value : the value to modify

③ append

append(value: str)

Add some text to the textbox

value : the text to be added, the usage is similar to the append method of the list

default appearance

CanvasText default appearance

Detailed usage

The function description of this text box is similar to that of the above input box (CanvasEntry), but there are still some differences.

For example, a space symbol can be entered by default in the text box, but not in the input box by default (can be modified by the space parameter).

Secondly, if the limit parameter of this text box is set relatively large, and the read parameter is True, then after exceeding the display range of the text box, it will only display a part...and many other features.

[ About some properties of the text box ]

read : the identifier of the read-only mode of the input box

space : Whether the input box can enter a space

icursor : the character of the input box text input prompt

value_surface : the value of the surface, generally the same as value, but when there are too many texts, the two are different

value_normal : The text is generally displayed, that is, the text is displayed when the mouse is not over the input box

value_touch : The value touched by the mouse, that is, the text displayed when the mouse is placed on the input box but not clicked down

limit : the limit of the text length (the length of a general character counts as 1, and the length of a Chinese character counts as 2), when it is a negative number, it means unlimited

An example is shown below: (better examples can be viewed in the "Practical Effect Display" later)

Detailed usage of CanvasText

Example source code:

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()

4. Tools

PhotoImage

This is the enhanced version of the PhotoImage class of the original tkinter module

It still only supports images in png and gif formats, but it can handle gif formats very well, and provides zoom operations for png images

Parameter Description

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

file : file path, the same parameters as PhotoImage in the original tkinter module

**kw : Other parameters, in order to be compatible with other parameters of PhotoImage in the original tkinter module

instance method

parse

parse()

Used to parse animations, no parameters, returns a generator (Generator)

play

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

Used to play animations (playing conditions: the value of the lock property of the canvas is True)

canvas : The canvas for playing animation

id : The _CanvasItemId of the animation (that is, the return value of create_text)

interval : the interval time of each frame of animation (unit: milliseconds)

zoom

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

Scale the picture (the current return value is the original tkinter PhotoImage class)

Temporarily only supports the scaling of images in png format, and the image in gif format is still being tested...

rate_x : Horizontal zoom ratio

rate_y : vertical zoom ratio

precision : the precision is the number of digits after the decimal point, the larger the value, the slower the operation

Detailed usage

If it is a picture in png format, the usage is exactly the same as that of PhotoImage in the original tkinter module, without any change, mainly for the picture in gif format.

First of all, when reading a picture in gif format, there is no need to write the format parameter, and the animation of each frame is automatically read and parsed. First instantiate the PhotoImage class of a picture in gif format, and then parse it. You can parse all its frames at one time, but considering that the parsing of large animations is very slow, so the return value of the parsing method is changed to generate device, so that it can be iterated externally in the form of a coroutine to realize the function of the progress bar. What is said here is very abstract, see the following example for details.

animation play

Source code for the above effect:

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()

After the above code is executed, the window will not pop up immediately, because it is being parsed at this time, and you will see the number of currently parsed frames printed out on the command line. After the analysis is completed, the window will pop up immediately and play the animation.

The parsing method is designed in this way, one is to avoid lagging when parsing large animations (with a lot of frames), and the other is to achieve the effect of a progress bar and view the progress of parsing in real time, so that when we are writing a large project, we can easily When you start to analyze a lot of animations, you can integrate all the animations in this way, load them at one time, and set up a progress bar by the way. and! the most important is! In this way, the function of loading the animation and realizing the progress bar does not require the participation of multiple threads! The function to achieve these is the simplest coroutine - the yield keyword!

Of course, you can also use error capture and the next function to iterate the generator to realize the function of the progress bar:

progress bar

The above source code that produces the progress bar:

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()

Regarding scaling, it is very simple, but! You can search online to see if there is any way to scale images without using the PIL library. I have looked for it, and there are almost none! However, I realized it here without introducing a third-party library! Although the calculation speed may be slightly worse than the PIL library, it is enough to meet our needs!

Going back to the scaling method, the precision parameter can be a floating-point number, and the default is 1. Then the scaling factor supports one decimal place, and it is not accurate if it is too much. By the way, if you increase the precision to 2, the calculation amount and calculation time will increase by 10 times! Therefore, if you do not have high requirements for precision, it is recommended to set the precision below 1.5.

Here is an additional shortcoming. This shortcoming is not caused by my module, but the original tkinter module has this shortcoming. That is, the sample object of the original tkinter PhotoImage must be a global variable before its picture can be displayed, otherwise it will be blank, so remember to "globalize" the picture obtained after zooming and then call it!

5. Functions

1、move_widget

control move function

Moves a control or collection of controls or images laid out by Place in a specific way

Parameter Description

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 : the parent control where the control is located

widget : the widget to move the position

dx : the distance to move laterally (unit: pixel)

dy : the distance to move vertically

times : total time of movement (unit: second)

mode : mode, three options are available

        smooth : the speed is first slow, then fast and then slow (Sin function mode, 0~π)

        rebound : Same as smooth, but it will rebound at the end (Cos function mode, 0~0.6π)

        flat : uniform translation

Or in the form of a tuple: (move function, start value, end value)

Detailed usage

This function can not only have an effect on the controls of this module, but also have the same effect on all the controls of the original tkinter module.

With it, we can easily achieve the following effects: (press the left mouse button to pop up a prompt box)

【Default Appearance】

Default Appearance - Tooltip

source code:

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()

【Put on the skin】

Change the skin - prompt box

source code:

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()

In the same way, we can also let it be taken back at an appropriate time, and then delete it to free up memory. In this way, the function of a prompt box is easily realized!

Or we can implement an interface switching operation (move the Canvas control):

interface switching

Source code for the above example:

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

Fix string length

Can change target string to target length and align in some way

Parameter Description

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

length : target length

string : the string to modify

position : the position of the text within the length range, three values ​​are optional: left, center, and right

        left : Text to the left

        center : center the text

        right : Text to the right

Detailed usage

This is very simple. It is generally used for alignment between multi-line text and single-line multiple text. Give an example directly.

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

In practice it looks like this:

correct_text detailed usage

The text length of each column here is not constant, so use the correct_text function to change their lengths and center them to achieve alignment.

3、change_color

color processing function

Gives a gradient RGB color string or its contrasting color to an existing RGB color string by a certain ratio

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

color : color tuple (color to be modified, target color), or a color (return its contrast color)

proportion : change ratio, default is 1

Detailed usage

This is very simple, just follow the parameters, here is an example:

gradient effect

Code for effect display:

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()

More realistic effect:

Realistic Gradients

How about it? Does it look like it has an inside smell? The source code is below:

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()

Or, we can use this gradient color to do something fun...

color changing button

The source code of the above Sao operation is as follows:

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()

postscript

After reading so much, do you understand how powerful this auxiliary module is? It basically only uses the original tkinter module (typing is only used for type hints, and sys is only used to detect the Python version) to make these functions. I wonder if it satisfies you? If you think so, can you give me a little like?

Ask for likes! Ask for collection! Ask for a comment! Please share!

At present, the producer of this module is only me, and I will continue to work hard!

Module source code download address: tkintertools

Module source code warehouse address: Xiaokang 2022 / tkintertools · GitCode

More knowledge column: Python Tkinter desktop application development column


—— Article updated on 2022/11/22 ——

Guess you like

Origin blog.csdn.net/weixin_62651706/article/details/127374661