布局方向

grid 栅格

和 CSS 组件 bootstrap 的栅格系统类似

简单代码

  1. import tkinter as tk
  2. import webbrowser
  3. from tkinter import messagebox
  4. class Application(tk.Frame):
  5. def __init__(self, master=None):
  6. # 绑定主画布
  7. super().__init__(master)
  8. self.master = master
  9. self.pack()
  10. self.createWidget()
  11. # 创建组件
  12. def createWidget(self):
  13. # grid 布局
  14. self.l1 = tk.Label(self, {
  15. 'text': '用户名:',
  16. }).grid({
  17. 'row': 0,
  18. 'column': 0,
  19. })
  20. self.E1 = tk.Entry(self).grid({
  21. 'row': 0,
  22. 'column': 1,
  23. })
  24. self.l2 = tk.Label(self, {
  25. 'text': '密码:',
  26. }).grid({
  27. 'row': 1,
  28. 'column': 0,
  29. })
  30. self.E2 = tk.Entry(self).grid({
  31. 'row': 1,
  32. 'column': 1,
  33. })
  34. self.B1 = tk.Button(self, {
  35. 'text': '登录',
  36. }).grid({
  37. 'row': 2,
  38. 'column': 1,
  39. 'sticky': 'EW'
  40. })
  41. self.B2 = tk.Button(self, {
  42. 'text': '取消'
  43. }).grid({
  44. 'row': 2,
  45. 'column': 2,
  46. 'sticky': 'E',
  47. })
  48. # 窗口主体
  49. root = tk.Tk()
  50. root.geometry("600x300+500+300")
  51. root.title('GUI 测试')
  52. # 子窗口
  53. app = Application(master=root)
  54. root.mainloop()

计算器GUI实例

注意 grid 的参数 row 为第几行 (竖) column 为第几列 (横) rowspan 为占用多少行 (竖) columnspan 为占用多少列 (横)

  1. import tkinter as tk
  2. import webbrowser
  3. from tkinter import messagebox
  4. class Application(tk.Frame):
  5. def __init__(self, master=None):
  6. # 绑定主画布
  7. super().__init__(master)
  8. self.master = master
  9. self.pack()
  10. self.createWidget()
  11. # 创建组件
  12. def createWidget(self):
  13. # grid 布局计算器
  14. butTuple = (('C', '±', '/', 'X'),
  15. (7, 8, 9, '-'),
  16. (4, 5, 6, '+'),
  17. (1, 2, 3, '='),
  18. (0, '.'))
  19. tk.Entry(self).grid({
  20. 'row': 0,
  21. 'column': 0,
  22. 'columnspan': 4,
  23. 'pady': 10
  24. })
  25. for index, item in enumerate(butTuple):
  26. for index1, item1 in enumerate(item):
  27. if item1 == '=':
  28. tk.Button(self, {
  29. 'width': 3,
  30. 'text': item1,
  31. }).grid({
  32. 'row': index + 1,
  33. # 占用多少行(竖)
  34. 'rowspan': 2,
  35. 'column': index1,
  36. 'sticky': 'NSEW'
  37. })
  38. elif item1 == 0:
  39. tk.Button(self, {
  40. 'width': 3,
  41. 'text': item1,
  42. }).grid({
  43. 'row': index + 1,
  44. # 占用多少列(横)
  45. 'columnspan': 2,
  46. 'column': index1,
  47. 'sticky': 'NSEW'
  48. })
  49. elif item1 == '.':
  50. tk.Button(self, {
  51. 'width': 3,
  52. 'text': item1,
  53. }).grid({
  54. 'row': index + 1,
  55. 'column': index1 + 1,
  56. 'sticky': 'NSEW'
  57. })
  58. else:
  59. tk.Button(self, {
  60. 'width': 3,
  61. 'text': item1,
  62. }).grid({
  63. 'row': index + 1,
  64. 'column': index1,
  65. 'sticky': 'NSEW'
  66. })
  67. # 窗口主体
  68. root = tk.Tk()
  69. root.geometry("600x300+500+300")
  70. root.title('GUI 测试')
  71. # 子窗口
  72. app = Application(master=root)
  73. root.mainloop()

place 像素布局

这个布局拥有更大的想象空间, 使用绝对定位和相对定位与像素

简单用法

  1. def __init__(self, master=None):
  2. # 绑定主画布
  3. super().__init__(master)
  4. # master 为 root
  5. # self 为子窗口
  6. self.master = master
  7. self.master['bg'] = '#cccccc'
  8. self.place({
  9. # 向 x 轴方向移 20%
  10. 'relx': 0.2,
  11. # 向 y 轴方向移 10px
  12. 'y': 10,
  13. # 宽度 20%
  14. 'relwidth': 0.2,
  15. # 高度 50%
  16. 'relheight': 0.5,
  17. })

扑克实例

  1. import tkinter as tk
  2. import webbrowser
  3. from tkinter import messagebox
  4. class Application(tk.Frame):
  5. def __init__(self, master=None):
  6. # 绑定主画布
  7. super().__init__(master)
  8. # master 为 root
  9. # self 为子窗口
  10. self.master = master
  11. self.master['bg'] = '#cccccc'
  12. self.pack()
  13. self.createWidget()
  14. # 创建组件
  15. def createWidget(self):
  16. # place 布局
  17. num = 7
  18. # 创建图片对象列表
  19. self.photos = [tk.PhotoImage(file='img/0%d.GIF' % (i + 1)) for i in range(num)]
  20. # 创建 label 对象列表
  21. self.pk = [tk.Label(self.master, {
  22. 'image': self.photos[i]
  23. }) for i in range(num)]
  24. index = 1
  25. # 循环显示 label
  26. for item in self.pk:
  27. print(item)
  28. item.place({
  29. 'x': index * 80,
  30. 'y': 40,
  31. })
  32. index += 1
  33. # 绑定事件
  34. item.bind('<Button-1>', self.chupai)
  35. def chupai(self, e):
  36. # 获得坐标信息
  37. print(e.widget.winfo_geometry())
  38. # 获得 x 坐标
  39. print(e.widget.winfo_x())
  40. # 获得 y 左右
  41. print(e.widget.winfo_y())
  42. # 更改目标label 的 y 坐标
  43. if e.widget.winfo_y() == 40:
  44. e.widget.place(y=20)
  45. elif e.widget.winfo_y() == 20:
  46. e.widget.place(y=40)
  47. # 窗口主体
  48. root = tk.Tk()
  49. root.geometry("1200x400+500+300")
  50. root.title('GUI 测试')
  51. # 子窗口
  52. app = Application(master=root)
  53. root.mainloop()