Tkinter库的学习记录03-c窗口控件配置
3、窗口控件配置管理员在设计GUI程序时可以使用三种方法包装和定位各组件在容器或窗口内的位置这三个方法又称窗口控件配置管理员。(1) pack方法虽然我们称pack方法其实在tkinter内这是一个类别。这是最常使用的控件配置管理方法它是使用相对位置的概念处理widget控件配置至于控件的正确位置则是由pack方法自动完成。pack方法的语法格式如下pack(option, ...)option参数可以是side、fill、padx/pady、ipadx/ipady、anchor。side参数side参数可以垂直或水平配置控件再进一步讲解前先看下列程序实例from tkinter import * window Tk() window.title(ch3_1) lab1 Label(window, text明志科技大学, bglightyellow) lab2 Label(window, text长庚大学, bglightgreen) lab3 Label(window, text长庚科技大学, bglightblue) lab1.pack() lab2.pack() lab3.pack() window.mainloop()由运行上面代码可以看到当窗口中有多个组件时使用pack可以让组件由上往下排列显示这也是系统的默认设置。使用pack方法时也可以增加side参数设置组件的排列方式此参数的取值如下TOP这是默认值由上往下排列BOTTOM由下往上排列。LEFT由左往右排列RIGHT由右往左排列from tkinter import * Reliefs [flat, groove, raised, ridge, solid, sunken] root Tk() root.title(ch3_5) for relief in Reliefs: Label(root, textrelief, reliefrelief, fgblue, font(Time, 20, bold)).pack(sideLEFT, padx5) root.mainloop()运行结果from tkinter import * bitMaps [error, hourglass, info, questhead, question, warning, gray12, gray25, gray50, gray75] root Tk() root.title(ch3_5) for bitmap in bitMaps: Label(root, bitmapbitmap).pack(sideLEFT, padx5) root.mainloop()padx/pady参数在使用pack方法时可以使用padx/pady参数设定控件边界与容器(可想成窗口边界)的距离或是控件边界的距离。在默认环境下窗口控件间的距离是1像素如果希望有适度间距可以设置参数padx/pady代表水平间距/垂直间距可以分别在组件间增加间距。from tkinter import * window Tk() window.title(ch3_1) lab1 Label(window, text明志科技大学, bglightyellow, width15) lab2 Label(window, text长庚大学, bglightgreen, width15) lab3 Label(window, text长庚科技大学, bglightblue, width15) lab1.pack(sideLEFT) lab2.pack(sideLEFT, padx10) lab3.pack(sideLEFT) window.mainloop()ipadx/ipdy参数ipadx参数可以控制标签文字与标签容器的x轴间距ipady参数可以控制标签文字与标签容器的y轴间距。from tkinter import * window Tk() window.title(ch3_1) lab1 Label(window, text明志科技大学, bglightyellow, width15) lab2 Label(window, text长庚大学, bglightgreen, width15) lab3 Label(window, text长庚科技大学, bglightblue, width15) lab1.pack() lab2.pack(ipadx10) lab3.pack(ipady10) window.mainloop()执行结果anchor参数anchor参数可以设定widget控件在窗口中的位置与属性设置中的类似但是本节中是指控件内容在控件区域的位置设置(实际的例子中是指标签文字在标签区域的位置)NWNNEWCNETERESWSSEfrom tkinter import * window Tk() window.title(ch3_12) window.geometry(300x180) okLabel Label(window, textOK, fontTimes 20 bold, fgwhite, bgblue) okLabel.pack(anchorS, sideRIGHT, padx10, pady10) noLabel Label(window, textNO, fontTimes 20 bold, fgwhite, bgred) noLabel.pack(anchorS, sideRIGHT, pady10) window.mainloop()运行结果fill参数fill参数的主要功能是告诉pack管理程序设置控件填满所分配容器区间的方式如果是fillX表示控件可以填满所分配空间的X轴不留白如果是fillY表示控件可以填满所分配控件的Y轴不留白如果是fillBOTH表示控件可以填满所分配空间的X轴和Y轴。fill默认值是NONE表示保持原大小。from tkinter import * window Tk() window.title(ch3_14) lab1 Label(window, text明志科技大学, bglightyellow, width15) lab2 Label(window, text长庚大学, bglightgreen, width15) lab3 Label(window, text长庚科技大学, bglightblue, width15) lab1.pack(sideLEFT, fillY) lab2.pack(fillX) lab3.pack(fillBOTH) window.mainloop()运行结果从上诉结果来看fillBOTH并没有发挥作用在扩充窗口大小时并没有扩充给Y轴的空间。原因是当Widget空间从左到右配置时pack配置管理员所配置的空间是Y轴的空间。当Widget控件从上到下配置时pack配置管理员所配置的空间是X轴的空间。以上诉实例而言当扩展窗口大小时“长庚科技大学”标签在Y轴的空间称为额外空间这时需要借助expand参数设置。expand参数expand参数可设定Widget控件是否填满额外的父容器控件默认是False(或是0)表示不填满如果是True(或是1)表示填满。from tkinter import * window Tk() window.title(ch3_21) Label(window, textMississippi, bgred, fgwhite, fontTimes 20 bold).pack(fillX) Label(window, textKentucky, bggreen, fgwhite, fontArial 20 bold italic).pack(fillBOTH, expandTrue) Label(window, textPurdue, bgblue, fgwhite, fontTimes 24 bold).pack(fillX) window.mainloop()pack的方法pack其实在python tkinter中是一个类别它提供下列方法供我们使用。方法名称说明slaves()传回所有Widget控件对象info()传回pack选项的对应值forget()隐藏Widget控件可以用pack(option,...)复原显示location(x, y)传回此点是否在单元格如果是传回坐标如果不是传回(-1,-1)size()传回Widget控件大小propagate(boolean)参数是True表示父窗口大小由子控件决定默认是Truefrom tkinter import * window Tk() window.title(ch3_23) window.geometry(300x180) print(执行前, window.pack_slaves()) okLabel Label(window, textOK, bgblue, fgwhite, fontTimes 20 bold) okLabel.pack(anchorS, sideRIGHT, padx10, pady10) noLabel Label(window, textNO, bgred, fgwhite, font(Times, 20, bold)) noLabel.pack(anchorS, sideRIGHT, pady10) print(执行后, window.pack_slaves()) window.mainloop()(2) grid方法这是一种以格状或者类似Excel电子表格方式包装和定位窗口组件的方法。grid方法的格式如下grid(option, ...)options参数可以是row、column、padx/padyrowspan、columnspan、sticky下面将详细说明。row和columnrow和column的取值row0 ... row n, column0 ... columnn可以适度调整grid()方法内的row和column值即可包装窗口组件的位置。from tkinter import * window Tk() window.title(ch3_24) lab1 Label(window, text明志科技大学, bglightyellow, width15) lab2 Label(window, text长庚大学, bglightgreen, width15) lab3 Label(window, text长庚科技大学, bglightblue, width15) lab1.grid(row0, column0) lab2.grid(row1, column0) lab3.grid(row1, column1) window.mainloop()运行结果columnspan参数可以设定控件在column方向的合并数量在正式讲解columnspan参数功能前下面先介绍建立一个含8个标签的应用。from tkinter import * window Tk() window.title(ch3_26) lab1 Label(window, text标签1, reliefraised) lab2 Label(window, text标签2, reliefraised) lab3 Label(window, text标签3, reliefraised) lab4 Label(window, text标签4, reliefraised) lab5 Label(window, text标签5, reliefraised) lab6 Label(window, text标签6, reliefraised) lab7 Label(window, text标签7, reliefraised) lab8 Label(window, text标签8, reliefraised) lab1.grid(row0, column0) lab2.grid(row0, column1) lab3.grid(row0, column2) lab4.grid(row0, column3) lab5.grid(row1, column0) lab6.grid(row1, column1) lab7.grid(row1, column2) lab8.grid(row1, column3) window.mainloop()执行结果如果发生了标签2和标签3的区间被一个标签占用的情况此时就是使用columnspan参数的场合。from tkinter import * window Tk() window.title(ch3_26) lab1 Label(window, text标签1, reliefraised) lab2 Label(window, text标签2, reliefraised) lab4 Label(window, text标签4, reliefraised) lab5 Label(window, text标签5, reliefraised) lab6 Label(window, text标签6, reliefraised) lab7 Label(window, text标签7, reliefraised) lab8 Label(window, text标签8, reliefraised) lab1.grid(row0, column0) lab2.grid(row0, column1, columnspan2) lab4.grid(row0, column3) lab5.grid(row1, column0) lab6.grid(row1, column1) lab7.grid(row1, column2) lab8.grid(row1, column3) window.mainloop()运行结果rowspan参数可以设定控件在row方向的合并数。from tkinter import * window Tk() window.title(ch3_26) lab1 Label(window, text标签1, reliefraised) lab2 Label(window, text标签2, reliefraised) lab3 Label(window, text标签3, reliefraised) lab4 Label(window, text标签4, reliefraised) lab5 Label(window, text标签5, reliefraised) lab7 Label(window, text标签7, reliefraised) lab8 Label(window, text标签8, reliefraised) lab1.grid(row0, column0) lab2.grid(row0, column1, rowspan2) lab3.grid(row0, column2) lab4.grid(row0, column3) lab5.grid(row1, column0) lab7.grid(row1, column2) lab8.grid(row1, column3) window.mainloop()运行结果如果标签2标签3标签6标签7同时合并成一个标签那么columnspan和rowspan参数都要设置。padx和pady参数这两个参数的用法与上一小节pack方法的padx/pady参数相同。from tkinter import * window Tk() window.title(ch3_26) lab1 Label(window, text标签1, reliefraised) lab2 Label(window, text标签2, reliefraised) lab3 Label(window, text标签3, reliefraised) lab4 Label(window, text标签4, reliefraised) lab5 Label(window, text标签5, reliefraised) lab6 Label(window, text标签6, reliefraised) lab7 Label(window, text标签7, reliefraised) lab8 Label(window, text标签8, reliefraised) lab1.grid(row0, column0, padx5, pady5) lab2.grid(row0, column1, padx5, pady5) lab3.grid(row0, column2, padx5, pady5) lab4.grid(row0, column3, padx5, pady5) lab5.grid(row1, column0, padx5) lab6.grid(row1, column1, padx5) lab7.grid(row1, column2, padx5) lab8.grid(row1, column3, padx5) window.mainloop()运行结果sticky参数这个参数的功能类似anchor但是只可以设定N/S/W/E即上/下/左/右对齐。原则上相同的column的Widget控件如果宽度不同时grid方法会保留最宽的控件当作基准这时比较短的控件会居中对齐参考以下实例。from tkinter import * window Tk() window.title(ch3_31) lab1 Label(window, text明志工专) lab2 Label(window, bgyellow, width20) lab3 Label(window, text明志科技大学) lab4 Label(window, bgaqua, width20) lab1.grid(row0, column0, padx5, pady5) lab2.grid(row0, column1, padx5, pady5) lab3.grid(row1, column0, padx5) lab4.grid(row1, column1, padx5) window.mainloop()运行结果从上图可以看到“明志工专”标签时居中对齐。from tkinter import * window Tk() window.title(ch3_31) lab1 Label(window, text明志工专) lab2 Label(window, bgyellow, width20) lab3 Label(window, text明志科技大学) lab4 Label(window, bgaqua, width20) lab1.grid(row0, column0, padx5, pady5, stickyW) lab2.grid(row0, column1, padx5, pady5) lab3.grid(row1, column0, padx5) lab4.grid(row1, column1, padx5) window.mainloop()运行结果sticky参数的可能值N/S/W/E也可以组合使用。stickyNS可以拉长高度让控件在顶端和底端对齐。stickyWE可以拉长宽度让控件在左边和右边对齐。stickyNSE可以拉长高度让控件在顶端和底端对齐同时切齐右边。stickyNSW可以拉长高度让控件在顶端和底端对齐同时切齐左边。stickyNSWE可以拉长高度让控件在顶端和底端对齐同时切齐左右边。观察下面代码from tkinter import * window Tk() window.title(ch3_31) lab1 Label(window, text明志工专, reliefraised) lab2 Label(window, bgyellow, width20) lab3 Label(window, text明志科技大学, reliefraised) lab4 Label(window, bgaqua, width20) lab1.grid(row0, column0, padx5, pady5) lab2.grid(row0, column1, padx5, pady5) lab3.grid(row1, column0, padx5) lab4.grid(row1, column1, padx5) window.mainloop()运行结果上述程序的目的主要时了解标签的宽度。下面这个程序主要时观察“明志工专”标签被拉长后的结果。from tkinter import * window Tk() window.title(ch3_31) lab1 Label(window, text明志工专, reliefraised) lab2 Label(window, bgyellow, width20) lab3 Label(window, text明志科技大学, reliefraised) lab4 Label(window, bgaqua, width20) lab1.grid(row0, column0, padx5, pady5, stickyWE) lab2.grid(row0, column1, padx5, pady5) lab3.grid(row1, column0, padx5) lab4.grid(row1, column1, padx5) window.mainloop()运行结果grid方法的应用from tkinter import * window Tk() window.title(ch3_35) Colors [red, orange, yellow, green, blue, purple] r 0 for color in Colors: Label(window, textcolor, reliefgroove, width20).grid(rowr, column0) Label(window, bgcolor, reliefridge, width20).grid(rowr, column1) r 1 window.mainloop()运行结果rowconfigure()和columnconfigure()在设计Widget控件的布局时有时候会碰上窗口缩放大小此时可以使用这个两个方法设计底几个row或column的缩放比例。例如rowconfigure(0, weight1) # row 0的控件当窗口改变大小时缩放比是1 columnconfigure(0, weight1) # column 0的控件当窗口改变大小时缩放比是1下面程序认识rowconfigure()和columnconfigure()与sticky参数的用法此处不使用sticky参数。from tkinter import * window Tk() window.title(ch3_35) window.rowconfigure(1, weight1) window.columnconfigure(0, weight1) lab1 Label(window, textLabel 1, bgpink) lab1.grid(row0, column0, padx5, pady5) lab2 Label(window, textLabel 2, bglightblue) lab2.grid(row0, column1, padx5, pady5) lab3 Label(window, bgyellow) lab3.grid(row1, column0, columnspan2, padx5, pady5) window.mainloop()运行结果上面代码中特别使用底色表达各个标签所占据的空间可以看到在没有使用sticky参数的情况下各个控件所占据的空间。from tkinter import * window Tk() window.title(ch3_35) window.rowconfigure(1, weight1) window.columnconfigure(0, weight1) lab1 Label(window, textLabel 1, bgpink) lab1.grid(row0, column0, padx5, pady5, stickyW) lab2 Label(window, textLabel 2, bglightblue) lab2.grid(row0, column1, padx5, pady5) lab3 Label(window, bgyellow) lab3.grid(row1, column0, columnspan2, padx5, pady5, stickyNSWE) window.mainloop()运行结果通过上诉执行结果可以得知下方的标签控件可以随着窗口大小更改主要是上面的代码中“stickyNSWE”的结果。至于设置的“stickyW”会让lab1控件向左对齐。(3) place方法这是使用直接指定方式将Widget控件放在容器(可想成窗口)中的方法。这个方法的语法格式如下。place(option, ...)option参数可以是height/width、relx/rely、x/y、relheight/relwidth、bordermode、anchor下面将详细介绍。x/y参数place()方法内的x和y参数可直接设定窗口组件的左上方位置单位是像素。窗口显示区的左上角是(x0, y0)x是向右递增y是向下递增。同时使用这种方法时窗口将不会自动重设大小而是使用默认的大小显示参考下面代码。from tkinter import * window Tk() window.title(ch3_36) lab1 Label(window, text明志科技大学, bglightyellow, width15) lab2 Label(window, text长庚大学, bglightgreen, width15) lab3 Label(window, text长庚科技大学, bglightblue, width15) lab1.place(x0, y0) lab2.place(x30, y50) lab3.place(x60,y100) window.mainloop()运行结果width/height参数有时候在设计窗口应用程序时所预留的控件有限如果想要将图片插入窗口内却担心图片太大可以在插入图片时同时设定图片的大小此时可以使用width/height参数这两个参数可以直接设定Widget控件的实体大小。在窗口内直接设置图片控件的位置和大小。from tkinter import * window Tk() window.title(ch3_37) window.geometry(640x480) night PhotoImage(filetest.png) labl Label(window, imagenight) labl.place(x20, y30, width200, height120) snow PhotoImage(filetest.png) lab2 Label(window, imagesnow) lab2.place(x200, y200, width400, height240) window.mainloop()运行结果relx/rely参数与relwidth/relheight参数relx/rely可以设置相对于父容器(可想成父窗口)的位置relwidth/relheight设置相对大小这个相对位置与相对大小是相对于父窗口而言其值为0.0 ~ 1.0。下面程序将图片test.png从相对位置(0.1, 0.1)开始放置相对大小是(0.8, 0.8)。from tkinter import * window Tk() window.title(ch3_38) window.geometry(640x480) night PhotoImage(filetest.png) labl Label(window, imagenight) labl.place(relx0.1, rely0.1, relwidth0.8, relheight0.8) window.mainloop()运行结果在设计时如果参数的某个相对大小未设定(可能是relwidth或relheight)未设置的部分将以实际大小显示此时可能需要放大窗口宽度才可以显示。Widget控件位置总结我们使用tkinter模块设计GUI程序时虽然可以使用place()方法很精确地设置控件的位置不过建议尽量使用pack()和grid()方法定位组件因为当窗口中组件较多时使用place()计算组件位置较不方便同时如有新增或减少组件时又须重新计算设置组件位置这样会不方便。