最近,工作上需要写一个windows上可执行的客户端,已经与tkinter打交道了一周了。趁着知识还没冷掉,做一下梳理。
根据我写的界面,通常会遇到的问题是组件居中处理。
创建了一个Toplevel对象后,为了美化,通常会对该对象进行居中展示。demo完整代码如下:
from tkinter import *
class Win_Program:
def __init__(self):
self.master = Tk()
self.master.state("zoomed") # 窗口最大化
self.master.title("demo")
self.master.grid()
def get_db_configure(self):
top = Toplevel(self.master)
top.title("数据库配置")
top.resizable(0,0) # 大小不可变
# 创建的Toplevel对象 在最上层
top.attributes("-toolwindow", 1)
top.wm_attributes("-topmost", 1)
top.grid()
return top
def widget_to_center(self, master, width, height):
# 获取屏幕长/宽
self.width = self.master.winfo_screenwidth()
self.height = self.master.winfo_screenheight()
x = self.width / 2 - width / 2
y = self.height / 2 - height / 2
master.geometry('%dx%d+%d+%d' % (width, height, x, y))
master.grid()
print(self.width, self.height, x, y)
if __name__ == "__main__":
win_program = Win_Program()
win_program.widget_to_center(win_program.get_db_configure(), 500, 400)
mainloop()
先来看 get_db_configure 方法,生成一个Toplevel对象。生成后,若没有
top.attributes("-toolwindow", 1)
top.wm_attributes("-topmost", 1)
此代码进行设置,你会发现,生成的top对象窗口会在self.master主窗口背后,这显然不是我们想要的。故需加上此设置。
而top.resizable(0,0)
保证了当窗口变大/变小之后,top对象的大小不会发生改变。
此时,若没有特殊处理, top对象默认在主窗口的左上方。居中处理其实也很简单,python中有现成的方法 geometry
。需要传递的参数有四个:主窗口的长与宽(或者说是父窗口),新窗口的长与宽(或者说是子窗口)。
现在再来看widget_to_center
方法,通过
self.width = self.master.winfo_screenwidth()
self.height = self.master.winfo_screenheight()
获取屏幕的长与宽(此种情况其实并不完全正确,只有主窗口时最大化全屏展示时,才能如此放心处理;当主窗口并不是最大化全屏展示,并且主窗口展示不是居中的时候,此方法不适用,可注释self.master.state("zoomed")
代码尝试)。geometry
的参数可以理解为:一个坐标,以及从坐标点开始花一个多长、多款的矩形。通过观察,坐标其实是新窗口的左上角的那个点,获取到坐标后,然后往下画给定高度height,往右画给定宽度width,一个矩形即形成。原理懂了,坐标的数据处理一看就明白了。下图圈中的即为坐标位置: