Python tkinter Misc类+Wm类详解

Misc类

这个类是模块中最基本的类,所有组件甚至是Tk都继承这个类。不过,组件并不直接继承这个类,而是继承Widget类(Widget类直接继承BaseWidget类,而BaseWidget类直接继承Misc),比较特殊的Toplevel继承的是BaseWidget类。

after(ms, func=None, *args)

等待ms毫秒(1s=1000ms)后执行func,并将所需参数通过args传递给func函数。常用于循环执行函数。

from tkinter import *

root = Tk()

def call(timer):    
    timer -= 1
    print(timer)

    root.after(1000, call, timer)

call(5)

mainloop()

如上示例,首先调用了一次call方法,在call方法里面将timer减去1,然后等待1秒后,将timer减去1后的值传递给call函数,然后在call函数里面再减一。每隔一秒就会打印一个数字。

after_cancel(id)

after方法返回一个标识符,可以传递给after_cancel方法取消after执行。

from tkinter import *

root = Tk()

def call(timer):    
    timer -= 1
    print(timer)

    id = root.after(1000, call, timer)
    if timer <= 0:
        root.after_cancel(id)

call(5)

mainloop()

如果检测到timer <= 0,after将会被取消,call函数也不会再执行。只有在after处于等待状态时,after_cancel才有效。

bell()

响铃一次,可参考Python tkinter一些十分灵活的运用方式和实用函数的第四节。

bind(sequence=None, func=None, add=None)

绑定事件。详见上一篇。

bind_all(sequence=None, func=None, add=None)

窗口所有组件绑定事件。详见上一篇。

bindtags(tagList=None)

设置事件执行的顺序。详见上一篇。

cget(key)

返回组件的key参数的值。如:label.cget("text")获取label的text参数值。

clipboard_append(string)

将string添加复制到剪贴板,复制的内容会被添加到上一次复制的内容后面。如果想要复制string,需先执行clipboard_clear()。

clipboard_clear()

清空剪贴板。

clipboard_get()

获取复制的内容。

config = configure(cnf=None, **kw)

更改组件的参数。cnf上一篇介绍过,和**kw一样可以用来传递参数,不过传递给cnf的是一个字典。

destroy()

销毁组件。窗口类也有这个方法,但是继承于Wm。

event_generate(sequence, **kw)

生成虚拟事件。详见上一篇。

focus = focus_set()

使窗口的输入焦点指向该组件。如果窗口未激活,这个组件将在用户激活窗口后作为该窗口的输入焦点。

focus_force()

使组件直接获取焦点,窗口将自动激活。和focus_set不同的是,focus_set不会自动激活窗口。

focus_get()

返回获取焦点的子组件。如果窗口未被激活,那么将返回None。

focus_lastfor()

返回窗口激活后将获取焦点的子组件。和focus_get不同的是,focus_lastfor即使没有激活窗口,也会返回将在激活后获取焦点的子组件。

grab_release()

释放组件焦点抓取。

grab_set()

设置组件焦点抓取。使焦点永远保持在这个组件上,在释放抓取之前不能转移焦点,只能在这个组件上操作。如果应用在窗口上,那么只能在这个应用程序的这个窗口上进行操作,无法操作其他的窗口(只能拖拽移动)。

image_names()

获取组件内可以应用的所有的图像名称,是Tcl内部的名称字符串。

keys()

返回组件所有的可设置参数列表。

lift = tkraise(aboveThis=None)

将窗口堆叠顺序抬升。如果不指定aboveThis,则窗口置于此应用程序所有窗口的最上方。如果指定aboveThis,则窗口置于aboveThis窗口的上方。

lower(belowThis=None)

将窗口堆叠顺序下降。如果不指定belowThis,则窗口置于此应用程序所有窗口的最下方。如果指定belowThis,则窗口置于belowThis窗口的下方。

nametowidget(name)

返回名为name的子组件。比如定义了一个Button(root, name="MyButton"),可以通过root.nametowidget("MyButton")返回Button对象本身。如果不会产生混淆,可以只提供组件本身的名字,不用提供组件的完整名称。

selection_clear()

清除子组件的选中内容。

selection_get(**kw)

获取子组件中的选中内容,如没有则会报错。如果某个输入类组件设定了exportselection=False,那么在这个组件上的选中内容不会被检测到。

unbind(sequence)

解除绑定。详见上一篇。

unbind_all(sequence)

解除bind_all的绑定。

update()

在事件循环中刷新,并刷新用户的动作引起的事件。

update_idletasks()

在事件循环中刷新,但不会处理用户动作引起的事件。

quit()

该组件退出事件循环(mainloop),但不销毁本身。

wait_variable(name="PY_VAR")

一直阻塞直到variable改变。见下方

wait_visibility(window=None)

一直阻塞直到window可见性改变。见下方

wait_window(window=None)

一直阻塞直到window销毁。见下方

tkinter的组件通常是一起绘制到窗口上面的,如果想要让一部分的绘制等待,就可以使用wait_window(),wait_visibility()和wait_variable()方法。使用这两种方法,可以使部分代码变简便。

比如在程序中,弹出一个对话框,等用户输入后按下确定,然后继续操作。这样的程序就必须使用wait_系列方法,等用户输入完后根据wait绑定的内容继续程序,否则无法直接操作用户的输入内容。

这时我们可以利用wait_系列方法:

  • Tk/Toplevel.wait_window(window=None):表示阻塞后面执行的内容,等后面的window组件销毁后才执行。
  • Tk/Toplevel.wait_visibility(window=None):表示阻塞后面的内容,等window的可见性改变后才执行后面的内容。
  • Tk/Toplevel.wait_variable(name="PY_VAR"):表示阻塞后面的内容,直到name(是一个PY_VAR,比如String Var,Int Var)

这样就可以直接用if句式,使代码简洁。

from tkinter import *

root = Tk()
root.wait_window(root)
print("root已经被销毁")

#mainloop()
#mainloop不需要执行,因为这一段执行到时root已经被销毁

在上面这段代码中,wait_window后面的内容不会被执行,但是当用户点下窗口的关闭按钮销毁窗口,才会打印后面的"root已经被销毁"。

from tkinter import *

root = Tk()
var = StringVar()
Button(root, text="改变var", command=lambda:var.set("change")).pack()
root.wait_variable(var)
print("var的内容出现了改变")

mainloop()

 在这一段代码中,只有当var的内容有了变化,才会停止阻塞,执行后面的print函数。用户点击Button时,将var的内容设置为"change",wait_variable检测到了内容改变,将后面的代码运行完毕,打印内容。因为这并不是一个事件,所以后面的代码只能运行一次。

from tkinter import *

root = Tk()
label = Label(root, text="")
Button(root, text="改变label的可见性", command=label.pack).pack()
root.wait_visibility(label)
print("label的可见性被改变!")

mainloop()

这一段代码中,当按下了Button,将label的可见性改变(如隐藏、放置) ,wait_visibility停止,执行后面的print代码。

在使用wait系列方法的时候,代码会自动进入主循环,你不需要考虑mainloop写在前面还是后面。

下面看一个示例,演示了wait_variable的使用。

from tkinter import *

root = Tk()
root.title("判断")
result = Variable(value=None)

Label(root, text="请问1+1=2是否正确?").pack()

Button(root, text="正确", command=lambda: result.set(True)).pack()
Button(root, text="错误", command=lambda: result.set(False)).pack()

root.wait_variable(result) #阻塞下面的进程,直到root.result改变
root.destroy() #在没有选择之前,这一段会一直阻塞

if result.get():
    print("你答对了")
else:
    print("你答错了")

winfo_children()

返回该组件的子组件列表。

winfo_class()

返回该组件的类名。比如Entry组件的类名是"Entry"。

winfo_containing(rootX, rootY)

返回位于电脑屏幕rootX, rootY的子组件。

winfo_exists()

返回组件是否存在。如果组件存在返回1,不存在(被destroy)返回0.

winfo_geometry()

返回组件的geometry信息(需要先映射组件,否则不准),返回格式为widthxheight+x+y。注:不是设置!

winfo_height(), winfo_width()

分别返回组件的高和宽(需要先映射组件,否则不准),会随着窗口的改变而更新。

winfo_reqheight(), winfo_reqwidth()

分别返回组件定义时的高和宽(不需要映射组件),不会随着窗口的改变而更新。

winfo_id()

返回窗口绘制组件区域(也就是整个窗口中,除去标题和菜单栏部分)的标识符,是一个整数。可以用这个方法返回Windows Tk窗口内部绘制组件区域的句柄,(注意:不是整个tk窗口!参见winfo_frame)

winfo_frame()

返回窗口的标识符,是一个十六进制字符串。可以用这个方法返回Windows Tk窗口的句柄。

winfo_name()

返回组件的Tcl内部名称。也可以用str(widget)代替这一句。

winfo_parent()

返回组件的父组件。

winfo_pointerx(), winfo_pointery(), winfo_pointerxy()

分别返回鼠标在屏幕上的x位置,y位置,以及x,y位置的元组。

winfo_rootx(), winfo_rooty()

分别返回组件在屏幕上的x位置,y位置(需要先映射组件,否则不准)。

winfo_screenheight(), winfo_screenwidth()

分别返回屏幕的高和宽。

winfo_x(), winfo_y()

分别返回组件在父容器上的x位置,y位置(需要先映射组件,否则不准)。

winfo_rgb(color)

返回组件中名为color的颜色的RGB色彩值。返回的是一个三个值的元组,每个值介于0和65535之间。

winfo_server()

返回屏幕的服务器信息。如:Windows 10.0 18363 Win64

注:使用winfo系列方法返回组件尺寸信息的时候,必须要在组件映射或update之后才能有效调用。mainloop方法就是在循环update窗口以及里面的组件,所以在调用mainloop后不需要执行update,但在mainloop之前需要执行update。但是winfo_reqwidth(), winfo_reqheight()不需要。

Wm类

参考资料:Toplevel顶级窗口和Tk根窗口方法汇总_近视的脚踏实地的博客-CSDN博客

WM是Window manager(窗口管理器)的缩写,所有窗口类继承Wm,也就是Tk和Toplevel。Wm类的方法以wm_作为开头,比如wm_destroy, wm_attributes,不过我们也可以写作destroy, attributes。在tk类中有很多这样的多名字的方法,这是因为类中对一些方法重命名过。

下面介绍Wm类(Tk和Toplevel)的方法。

注:由于方法过多,这里只筛选出可能有用的方法进行详细的解析。其他方法可见参考资料

aspect(minNumer=None, minDenom=None, maxNumer=None, maxDenom=None)

控制窗口的宽高比,使宽高比限制在:minNumer / minDenom ~ maxNumer / maxDenom。如果不设置参数,则返回这四个参数的元组。

attributes(*args)

设置窗口的各项属性。可以提供一个参数,是属性名称,将会返回窗口的属性值。如果再提供一个参数,则设置这个窗口的属性值。选项提供时,需要在前面加上一个-符号,比如:root.attributes("-alpha", 0.5)表示设置窗口半透明。

窗口的属性选项有:

选项 作用 系统
alpha 设置窗口的不透明度,是一个0-1的浮点数,1.0表示不透明,0.0表示完全透明。 Windows, Mac
disabled 窗口是否禁用,禁用时无法在窗口上进行任何操作 Windows
fullscreen 窗口是否全屏,全屏和最大化不同,全屏时窗口最大的同时标题栏会隐藏。 Windows, Mac
modified 窗口是否标记为改动过 Mac
titlepath 设置窗口代理图标的路径 Mac
toolwindow 窗口是否设置为工具窗口样式,可以参考Python tkinter一些十分灵活的运用方式和实用函数的第一节。 Windows
topmost 窗口是否始终置顶显示 Windows, Mac
transparentcolor 设置穿透颜色,可以参考Python tkinter一些十分灵活的运用方式和实用函数的第三节。 Windows

deiconify()

显示窗口(和withdraw方法相反)。

forget(window)

将窗口从窗口管理器中解除(参见下面的manage),可对Frame类组件或Toplevel操作。

geometry(newGeometry=None)

设置窗口尺寸,newGeometry格式有以下几种:

  • "%dx%d"%(width, height):设置窗口的宽和高。
  • "+%d+%d"%(left, top):设置窗口与屏幕左边、上边的距离。
  • "+%d-%d"%(left, bottom):设置窗口与屏幕左边、下边的距离。
  • "-%d-%d"%(right, bottom):设置窗口与屏幕右边、下边的距离。
  • "-%d+%d"%(right, top):设置窗口与屏幕右边、上边的距离。
  • "":设置为空字符串,表示窗口大小适应内部组件大小。
  • 也可以将窗口宽高与窗口偏移距离结合使用,如"100x100+50-30"表示:窗口大小100x100,与屏幕左边相隔50像素,与屏幕下边相隔30像素。
  • 数值可以也可以是负数,如"100x100+-7+0"表示距离左侧屏幕-7个像素。由于tkinter窗口的设计原因,设为0的时候窗口并不是刚好贴边,设为-7则刚刚好

iconbitmap(bitmap=None, default=None)

设置窗口图标为bitmap(是一个ico文件的路径字符串),如果设置default(一个文件名),那么该窗口的子窗口将自动设置图标为此图标文件。

iconify()

使窗口最小化。

iconphoto(default=False, *args)

设置窗口图标。如果default设置为True,那么该窗口的子窗口将自动设置图标为此图标文件。*args可以提供图标,提供的是PhotoImage对象。

manage(widget)

将某个组件作为顶层窗口管理,支持传递的组件包括Frame, LabelFrame, Toplevel。管理后,该组件会从窗口中移除,并作为一个单独的窗口显示。forget方法与之相对。

from tkinter import *

def switch():
    global isFrame
    
    if isFrame:
        root.manage(f)
    else:
        root.forget(f)
        f.pack()

    isFrame = not isFrame
    
root = Tk()
isFrame = True

f = Frame(root, name="frame window")
Button(f, text="Test", command=switch).pack(expand=True)
f.pack()

mainloop()

这个方法仍然存在一定缺陷,比如窗口的图标难以更改;标题会设为当前组件的名称,不便更改。 

maxsize(width=None, height=None)

设置窗口可以被拖拽的最大宽和高。

minsize(width=None, height=None)

设置窗口可以被拖拽的最小宽和高。

overrideredirect(boolean=None)

设置是否隐藏窗口的标题栏和边框。隐藏标题栏的窗口:

protocol(name=None, func=None)

当窗口检测到name协议的时候,执行func。协议是窗口管理器和应用的通信方式。最常用的协议是WM_DELETE_WINDOW,当用户点击窗口的关闭按钮时,将会调用func。此外还有一些协议:WM_SAVE_YOURSELF(当窗口被保存,被弃用),WM_TAKE_FOCUS(当窗口获取焦点,无效),但是都没有什么用。

下面的示例:在用户点击关闭按钮的时候,打印“你不能关闭”。

from tkinter import *
from PIL import Image, ImageTk

root = Tk()
root.protocol("WM_DELETE_WINDOW", lambda:print("你不能关闭"))

mainloop()

 

默认窗口检测到WM_DELETE_WINDOW会执行窗口的destroy方法将窗口销毁,但是更改了WM_DELETE_WINDOW的方法后,就只会执行给定的func回调函数。

resizable(width=None, height=None)

设置是否允许改变窗口尺寸。

state(newstate=None)

设置窗口的状态,newstate可以是"normal"(正常), "iconic"(最小化), "withdrawn"(被隐藏), "icon"(Wm.iconwindow), "zoomed"(最大化)。

title(string=None)

设置窗口的标题。

transient(master=None)

设置窗口为master窗口的临时窗口,临时窗口没有最大化和最小化按钮,只有关闭按钮。 可以参考Python tkinter一些十分灵活的运用方式和实用函数的第一节。

withdraw()

隐藏窗口,和最小化不同的是,隐藏的窗口不会在任务栏上显示,用户无法还原。和deiconify方法相反。

猜你喜欢

转载自blog.csdn.net/qq_48979387/article/details/131019454