Tairraos 发表于 2020-10-25 12:57

Python tkinter UI指南

本帖最后由 Tairraos 于 2020-10-25 15:50 编辑

想要自己的Python脚本用起来更直观一些吗?
做一个GUI界面吧。大约半天可以小成,练习个3,4天就能大成。然后给你的开源脚本升级出GUI吧。

帖子很长,收藏下来必然某天用得到。喜欢请点击下方免费评分,谢谢
======================
还有几帖你一定会喜欢的:
Python资源大全:https://www.52pojie.cn/thread-1081229-1-1.html
Python tkinter UI指南 https://www.52pojie.cn/thread-1290751-1-1.html
原生 Javascript 实现 jQuery 的功能: https://www.52pojie.cn/thread-1084552-1-1.html
Chrome调试器Console的进阶用法 https://www.52pojie.cn/thread-1156239-1-1.html
Javascript 极限省字节(看懂混淆后的代码) https://www.52pojie.cn/thread-1056860-1-1.html
写JS必备,ESLINT配置说明 https://www.52pojie.cn/thread-1290700-1-1.html
======================
# tkinter介绍

> tkinter是python自带的GUI库,是对图形库TK的封装
> tkinter是一个跨平台的GUI库,开发的程序可以在win,linux或者mac下运行



# 组件概念

> 一个窗口中任意内容都可以称之为一个组件

### tkinter的组件包含以下几种

### 按钮组件

```python
Button         按钮组件
RadioButton      单选框组件
CheckButton      选择按钮组件
Listbox          列表框组件
```

### 文本输入框组件

```python
Entry            单行文本框组件
Text             多行文本框组件
```

### 标签组件

```python
Label            标签组件,可以显示图片和文字
Message          标签组件,可以根据内容将文字换行
```

### 菜单组件

```python
Menu             菜单组件
MenuButton       菜单按钮组件,可以使用Menu代替
```

### 滚动条组件

```python
scale            滑块组件
Scrollbar      滚动条组件
```

### 其他组件

```python
Canvas         画布组件
Frame            框架组件,将多个组件编组
Toplevel         创建子窗口容器组件
```



# 创建窗口

### 简单的窗口

```python
import tkinter
# 创建一个主窗口
win = tkinter.Tk()
# 设置标题
win.title("Python-14")
# 设置窗口大小和位置
# 500x500 表示窗口大小
# +200+50 表示窗口距离电脑屏幕的左边缘和上边缘的距离
win.geometry("500x500+200+50")
# 启动主窗口
win.mainloop()
```



### 带有组件的窗口

```python
import tkinter
#生成主窗口对象
root = tkinter.Tk()
#创建标签 并且添加到主窗口中
label = tkinter.Label(root,text = '爷来了')
label.pack()
#创建按钮,并且添加到主窗口中
btn1 = tkinter.Button(root,text = '按钮1')
btn1.pack()
btn2 = tkinter.Button(root,text = '按钮2')
btn2.pack()
#保持主窗口一直消息循环中。。
root.mainloop()
```



# 组件布局

### 组件布局一共三种方式

```python
pack()   按照方位布局
place()    按照坐标布局
grid()   按照网格布局
```

## 1.pack布局方法

> 所有的Tkinter组件都包含专用的几何管理方法,这些方法是用来组织和管理整个父配件区中子配件的布局的。Tkinter提供了截然不同的三种几何管理类:pack、grid和place。
> pack几何管理采用块的方式组织配件,在快速生成界面设计中广泛采用,若干组件简单的布局,采用pack的代码量最少。pack几何管理程序根据 组件创建生成的顺序将组件添加到父组件中去。通过设置相同的锚点(anchor)可以将一组配件紧挨一个地方放置,如果不指定任何选项,**默认在父窗体中自顶向下添加组件。**

### pack()布局的通用公式

```python
组件对象.pack(设置, …)   
```

| 名称         | 描述                                                         | 取值范围                                                   |
| ------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| expand       | 当值为“yes”时,side选项无效。组件显示在父配件中心位置;若fill选项为”both”,则填充父组件的剩余空间。 | “yes”, 自然数, “no”, 0(默认值为“no”或0)                  |
| fill         | 填充x(y)方向上的空间,当属性side=”top”或”bottom”时,填充x方向;当属性side=”left”或”right”时,填充”y”方向;当expand选项为”yes”时,填充父组件的剩余空间。 | “x”, “y”, “both”(默认值为待选)                           |
| ipadx, ipady | 组件内部在x(y)方向上填充的空间大小,默认单位为像素,可选单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点,即1/27英寸),用法为在值后加以上一个后缀既可。 | 非负浮点数(默认值为0.0)                                    |
| padx, pady   | 组件外部在x(y)方向上填充的空间大小,默认单位为像素,可选单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点,即1/27英寸),用法为在值后加以上一个后缀既可。 | 非负浮点数(默认值为0.0)                                    |
| side         | 定义停靠在父组件的哪一边上。                                 | “top”, “bottom”, “left”, “right”(默认为”top”)            |
| before       | 将本组件于所选组建对象之前pack,类似于先创建本组件再创建选定组件。 | 已经pack后的组件对象                                       |
| after      | 将本组件于所选组建对象之后pack,类似于先创建选定组件再本组件。 | 已经pack后的组件对象                                       |
| in_          | 将本组件作为所选组建对象的子组件,类似于指定本组件的master为选定组件。 | 已经pack后的组件对象                                       |
| anchor       | 相对于摆放组件的位置的对齐方式,左对齐”w”,右对齐”e”,顶对齐”n”,底对齐”s” | “n”, “s”, “w”, “e”, “nw”, “sw”, “se”, “ne”, “center”(默认为” center”) |

> **注:以上选项中可以看出expand、fill和side是相互影响的。**

### pack类提供了下列函数

| 函数名             | 描述                                                         |
| ------------------ | ------------------------------------------------------------ |
| slaves()         | 以列表方式返回本组件的所有子组件对象。                     |
| propagate(boolean) | 设置为True表示父组件的几何大小由子组件决定(默认值),反之则无关。 |
| info()             | 返回pack提供的选项所对应得值。                               |
| forget()         | Unpack组件,将组件隐藏并且忽略原有设置,对象依旧存在,可以用pack(option, …),将其显示。 |
| location(x, y)   | x, y为以像素为单位的点,函数返回此点是否在单元格中,在哪个单元格中。返回单元格行列坐标,(-1, -1)表示不在其中。 |
| size()             | 返回组件所包含的单元格,揭示组件大小。                     |

## 2.grid布局方法

> grid几何管理采用类似表格的结构组织配件,使用起来非常灵活,用其设计对话框和带有滚动条的窗体效果最好。grid采 用行列确定位置,行列交汇处为一个单元格。每一列中,列宽由这一列中最宽的单元格确定。每一行中,行高由这一行中最高的单元格决定。组件并不是充满整个单 元格的,你可以指定单元格中剩余空间的使用。你可以空出这些空间,也可以在水平或竖直或两个方向上填满这些空间。你可以连接若干个单元格为一个更大空间, 这一操作被称作跨越。创建的单元格必须相临。

### grid()布局的通用公式为

```python
组件对象.grid(option, …)
```

### grid类提供了下列设置属性

| 名称         | 描述                                                         | 取值范围                                                   |
| ------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| column       | 组件所置单元格的列号。                                       | 自然数(起始默认值为0,而后累加)                            |
| columnspan   | 从组件所置单元格算起在列方向上的跨度。                     | 自然数(起始默认值为0)                                    |
| ipadx, ipady | 组件内部在x(y)方向上填充的空间大小,默认单位为像素,可选单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点,即1/27英寸),用法为在值后加以上一个后缀既可。 | 非负浮点数(默认值为0.0)                                    |
| padx, pady   | 组件外部在x(y)方向上填充的空间大小,默认单位为像素,可选单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点,即1/27英寸),用法为在值后加以上一个后缀既可。 | 非负浮点数(默认值为0.0)                                    |
| row          | 组件所置单元格的行号。                                       | 自然数(起始默认值为0,而后累加)                            |
| rowspan      | 从组件所置单元格算起在行方向上的跨度。                     | 自然数(起始默认值为0)                                    |
| in_          | 将本组件作为所选组建对象的子组件,类似于指定本组件的master为选定组件。 | 已经pack后的组件对象                                       |
| sticky       | 组件紧靠所在单元格的某一边角。                               | “n”, “s”, “w”, “e”, “nw”, “sw”, “se”, “ne”, “center”(默认为” center”) |

### grid类提供了下列函数

| 函数名             | 描述                                                         |
| ------------------ | ------------------------------------------------------------ |
| slaves()         | 以列表方式返回本组件的所有子组件对象。                     |
| propagate(boolean) | 设置为True表示父组件的几何大小由子组件决定(默认值),反之则无关。 |
| info()             | 返回pack提供的选项所对应得值。                               |
| forget()         | Unpack组件,将组件隐藏并且忽略原有设置,对象依旧存在,可以用pack(option, …),将其显示。 |
| grid_remove()      | 从网格管理器中删除此小部件。小部件不会被销毁,并且可以由网格或任何其他管理器重新显示。 |

## 3.place布局方法

> 这个的几何管理器组织放置在一个特定的位置,在他们的父widget部件.

### place()布局的通用公式为:

```python
组件对象.place(option, …)
```

| 名称      | 描述                                                         | 取值范围                                                   |
| --------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| anchor    | 相对于摆放组件的坐标的位置                                 | 请参阅:可能是N,E,S,W,东北,西北,东南或西南,罗盘方向指示的widget的角落,双方默认是净重(部件上左上角) |
| height    | 以像素为单位的高度.(绝对布局专用)                        | 像素                                                         |
| width   | 以像素为单位的宽度.(绝对布局专用)                        | 像素                                                         |
| relheight | 组件相对于窗口的的高度(相对布局专用)                     | 0~1                                                         |
| relwidth| 组件相对于窗口的的宽度(相对布局专用)                     | 0~1                                                         |
| relx      | 水平偏移为0.0和1.0之间浮动,父widget的一小部分的高度和宽度.(相对布局专用) | 0~1                                                         |
| rely      | 垂直偏移为0.0和1.0之间浮动,父widget的一小部分的高度和宽度.(相对布局专用) | 0~1                                                         |
| x         | 组件距离左上角的x坐标(绝对布局专用)                        | 像素                                                         |
| y         | 组件距离左上角的y坐标(绝对布局专用)                        | 像素                                                         |

### place类提供了下列函数(使用组件实例对象调用)

| 函数名                        | 描述                                                         |
| ----------------------------- | ------------------------------------------------------------ |
| place_slaves()                | 以列表方式返回本组件的所有子组件对象。                     |
| place_configure(option=value) | 给pack布局管理器设置属性,使用属性(option)= 取值(value)方式设置 |
| propagate(boolean)            | 设置为True表示父组件的几何大小由子组件决定(默认值),反之则无关。 |
| place_info()                  | 返回pack提供的选项所对应得值。                               |
| grid_forget()               | Unpack组件,将组件隐藏并且忽略原有设置,对象依旧存在,可以用pack(option, …),将其显示。 |
| location(x, y)                | x, y为以像素为单位的点,函数返回此点是否在单元格中,在哪个单元格中。返回单元格行列坐标,(-1, -1)表示不在其中 |
| size()                        | 返回组件所包含的单元格,揭示组件大小。                     |



# 组件介绍

## 组件1 按钮(button)

### 用于定义GUI界面中的按钮组件

```python
tkinter.Button(用于存放的父组件,属性参数...)
```

### 具备以下属性

```python
anchor             设置按钮中文字的对齐方式,相对于按钮的中心位置
background(bg)   设置按钮的背景颜色
foreground(fg)   设置按钮的前景色(文字的颜色)
borderwidth(bd)    设置按钮边框宽度
cursor             设置鼠标在按钮上的样式
command            设定按钮点击时触发的函数
bitmap             设置按钮上显示的位图
font               设置按钮上文本的字体
width            设置按钮的宽度(字符个数)
height             设置按钮的高度(字符个数)
state            设置按钮的状态
text               设置按钮上的文字
image            设置按钮上的图片
```

```python
import tkinter
# 创建一个主窗口
win = tkinter.Tk()
# 设置标题
win.title("Python-14")
# 设置窗口大小和位置
# 500x500 表示窗口大小
# +200+50 表示窗口距离电脑屏幕的左边缘和上边缘的距离
win.geometry("500x500+200+50")
button1 = tkinter.Button(win,
                         text = "退出",
                         width = 20,
                         height = 5,
                         command = win.quit
                         )
button1.pack()


def func():
    print("欢迎欢迎!")
button2 = tkinter.Button(win,
                         text = "点我有惊喜",
                         width = 30,
                         height = 20,
                         command = func
                         )
button2.pack()
# 启动主窗口
win.mainloop()
```




## 组件2 文本框(Entry)和多行文本(Text)

### 用于定义页面中文本的单行输入框

```python
#单行文本
tkinter.Entry(用于存放的父组件,属性参数...)

#多行文本
tkinter.Text(用于存放的父组件,属性参数...)
```

### 具备以下属性

```python
background(bg)      设置文本框的背景色
foreground(fg)      设置文本框的前景色
borderwidth(bd)       设置文本输入框的边框
font                  设置文本框中的字体
width               设置文本框的宽度(字符个数)
height                设置文本框的高度(字符个数),仅限于text
state               设置文本框的状态
selectbackground      选中文字时文本框的背景色
selectforeground      选中文字时文字的颜色
show                  指定文本框显示的字符,若为*,则表示为密码框
textvariable          设置文本对应的变量,可以通过修改变量改变文字显示。必须使用tkinter.IntVar() 或 tkinter.StringVar()产生的变量entry可以使用
```

```python
import tkinter
# 创建一个主窗口
win = tkinter.Tk()
# 设置标题
win.title("Python-14")
# 设置窗口大小和位置
win.geometry("500x500+250+150")
# 设置一个变量,用来接收输入控件得内容
e1 = tkinter.Variable()
# 输入框控件
# show 隐藏输入的内容
entry = tkinter.Entry(win,textvariable = e1,show = "@")
entry.pack()
# 设置输入框内默认内容
e1.set("请输入用户名")
print(e1.get())
#设置按钮提交
def func():
    print(e1.get())
button = tkinter.Button(win,text = "提交",command = func)
button.pack()
# 启动主窗口
win.mainloop()
```

```python
import tkinter

win = tkinter.Tk()
win.title("Python-14")
win.geometry("500x500+200+100")

#创建一个滚动条
scroll = tkinter.Scrollbar()
text = tkinter.Text(win,width = 100,height = 40)
#显示滚动条位置放在右侧填充满Y轴
scroll.pack(side = tkinter.RIGHT,fill = tkinter.Y)
# 文本框的显示
text.pack(side = tkinter.LEFT,fill = tkinter.Y)

#绑定滚动条和文本框
scroll.config(command = text.yview)
#绑定文本框和滚动条
text.config(yscrollcommand = scroll.set)

str = """
Christmas Day is on December 25th. It was originated in the western country, but today, this festival has been celebrated by the world. For the manufacturers, they are very happy to make this day as a shopping day. I enjoy the great atmosphere.
I had a very special Christmas day last year. I experienced the western style festival. There was a new foreign teacher taught us the lesson. She was about 50 years old and she was very kind and we all liked her. On Christmas Day, she brought us the desserts she made early in the morning. We enjoyed the home-made cakes. What's more, she invited us to came to her house and spent the day with her. Then for the first time, I ate big turkey, which was so delicious. The turkey was filled with many stuffs and the flavor was so good. After dinner, we sang songs and danced. Thanks to my foreign teacher, I experienced the American style festival. It was such funny for me. Though today many people enjoy shopping in all kinds of festivals, the meaning of these festival should be remembered. Christmas Day is on December 25th. It was originated in the western country, but today, this festival has been celebrated by the world. For the manufacturers, they are very happy to make this day as a shopping day. I enjoy the great atmosphere.
"""

text.insert(tkinter.INSERT,str)

win.mainloop()
```

```python
import tkinter
win = tkinter.Tk()
win.title("Python-14")
win.geometry("500x500+200+100")
# 创建一个输入框
entry = tkinter.Entry(win)
entry.pack()
# 创建一个文本框
text = tkinter.Text(win,width = 50,height = 20)
text.pack()

# 写一个读取文件的函数
def func():
    with open(entry.get(),"r") as f:
      content = f.read()
      text.insert(tkinter.INSERT,content)
# 写一个保存文件内容的函数
def func1():
    with open(entry.get(),"w") as f:
      # 写入的内容为 文本框内从0行0列到结束
      f.write(text.get(0.0,tkinter.END))
      
#创建两个按钮
button1 = tkinter.Button(win,text = "保存",command = func1)
button2 = tkinter.Button(win,text = "读取",command = func)
button1.pack()
button2.pack()

win.mainloop()
```



## 组件3 标签(Lebal)

### 标签用语在页面中显示文字或者图片

```python
tkinter.Label(用于存放的父组件,属性参数...)
```

### 具备以下属性

```python
anchor                设置文本相对于标签中心的位置
background(bg)            设置标签的背景色
foreground(fg)            设置标签的前景色
borderwidth(bd)         设置标签的边框宽度
width               设置标签的宽度(字符个数)
height                设置标签的高度(字符个数)
text                  设置标签中文本内容
font                  设置标签中文字的字体类型
bitmap                设置标签的现实的位图
image               设置标签中显示的图片
justify               设置标签中多行文本的对齐方式
textvariable          设置文本对应的变量,可以通过修改变量改变文字显示,必须使用tkinter.IntVar() 或者tkinter.StringVar()产生的变量
```

```python
import tkinter
# 创建一个主窗口
win = tkinter.Tk()

# 设置标题
win.title("Python-14")

# 设置窗口大小和位置
# 500x500 表示窗口大小
# +200+50 表示窗口距离电脑屏幕的左边缘和上边缘的距离
win.geometry("500x500+200+50")
"""
Label:标签空间,可以显示文本
win:主窗口
text:显示文本内容
bg:背景颜色
fg:字体颜色
font:设置字体和字体大小
wraplength:指定text中多宽之后进行换行
anchor:文本显示的位置n北 e东 s南 w西 center居中 ne se sw nw
justify:设置换行之后的对齐方式
"""
label = tkinter.Label(win,
                      text = "this is a python test",
                      bg = "red",
                      fg = "yellow",
                      font = ("黑体",26),
                      width = 5,
                      height = 10,
                      wraplength = 100,
                      anchor = "n",
                      justify = "right"
                      )
# 显示标签
label.pack()
# 启动主窗口
win.mainloop()
```



## 组件4 单选框(Radiobutton)与复选框(Checkbutton)

```python
thinter.Radiobutton(用于存放的父组件,属性参数...)
thinter.Checkbutton(用于存放的父组件,属性参数...)
```

### 具有以下属性

```python
anchor             设置组件中文字的对齐方式
background(bg)   指定组件的背景色。 
borderwidth(bd)    指定组件边框的宽度。 
bitmap             指定组件中的位图。 
font               指定组件中文本的字体。 
foreground(fg)   指定组件的前
height             指定组件的高度。 
image            指定组件中的图片。 
justify            指定组件中多行文本的对齐方式。 
text               指定组件中的文本,可以 使用“\ n” 表示换行。 
value            指定组件被选中后状态的值(单选框)
onvalue            组件勾选状态值(复选框)
offvalue         组件取消勾选状态的值(复选框)
variable         指定组件所关联的变量。需要使用tkinter. IntVar()或者tkinter. StringVar()创建的值
width            指定组件的宽度。
command            设置复选框操作的触发命令(复选框)
```

```python
# 复选框
import tkinter
win = tkinter.Tk()
win.title("Python-14")
win.geometry("500x500+200+100")

def func():
    message = ""
    if res1.get():
      message += "张三\n"
    if res2.get():
      message += "李四\n"
    if res3.get():
      message += "王五\n"
      
    # 清除text中所有内容
    text.delete(0.0,tkinter.END)
   
    # 把message写入text中
    text.insert(tkinter.INSERT,message)
   
# 判断复选框是否被选定 返回一个bool值
res1 = tkinter.BooleanVar()
# 创建一个复选框
check1 = tkinter.Checkbutton(win,text = "张三",variable = res1)
check1.pack()

res2 = tkinter.BooleanVar()
check2 = tkinter.Checkbutton(win,text = "李四",variable = res2)
check2.pack()

res3 = tkinter.BooleanVar()
check3 = tkinter.Checkbutton(win,text = "王五",variable = res3)
check3.pack()

# 创建一个文本框
text = tkinter.Text(win,width = 50,height = 20)
text.pack()
# 创建一个按钮
button = tkinter.Button(win,text = "submit",width = 10,height = 5,command = func)
button.pack()
win.mainloop()
```

```python
#单选框
import tkinter

win = tkinter.Tk()
win.title("Python-14")
win.geometry("500x500+200+100")

# 获取单选框的value
res = tkinter.StringVar()
# 定义一个函数来打印单选框的value值
def func():
    print(res.get())
   
# 创建单选框
radio1 = tkinter.Radiobutton(
    win,
    text = "张三",
    value = 1,
    variable = res,
    command = func
)
radio2 = tkinter.Radiobutton(
    win,
    text = "李四",
    value = 2,
    variable = res,
    command = func
)
radio3 = tkinter.Radiobutton(
    win,text = "王五",
    value = 3,
    variable = res,
    command = func
)
# 显示单选框
radio1.pack()
radio2.pack()
radio3.pack()

win.mainloop()
```



## 组件5 Frame 框架

```python
thinter.Menu(用于存放的父组件,属性参数...)
```

### 具有以下属性

```python
background(bg)          正常的背景颜色显示在标签和指示器后面。
borderwidth(bd)         指标周围边界的大小。默认值为2像素。
cursor               如果将此选项设置为光标名称(箭头,点等),则鼠标光标将在检查按钮上方更改为该模式。
height                  新框架的垂直尺寸。
highlightbackground   当框架没有焦点时,焦点的颜色突出显示。
highlightcolor          当框架具有焦点时,焦点突出显示的颜色。
highlightthickness      焦点亮点的厚度。
relief                  使用默认值,relief = FLAT,检查按钮不会从背景中脱颖而出。您可以将此选项设置为任何其他样式
width                   checkbutton的默认宽度取决于所显示的图像或文字的大小。你可以设置此选项的字符数和checkbutton的,总是有许多字符的空间。
```

```python
#布局
import tkinter
win = tkinter.Tk()
win.title("Pyhton-14")
win.geometry("500x500+200+100")

# 创建一个框架
frame = tkinter.Frame(win)
frame.pack()

# 左边
frm1 = tkinter.Frame(frame)
lable1 = tkinter.Label(frm1,text = "左上",bg = "red",width = 10,height = 5)
lable2 = tkinter.Label(frm1,text = "左下",bg = "yellow",width = 10,height = 5)
lable1.pack(side = tkinter.TOP)
lable2.pack(side = tkinter.TOP)
frm1.pack(side = tkinter.LEFT)
# 右边
frm2 = tkinter.Frame(frame)
lable3 = tkinter.Label(frm2,text = "右上",bg = "green",width = 10,height = 5)
lable4 = tkinter.Label(frm2,text = "右下",bg = "blue",width = 10,height = 5)
lable3.pack(side = tkinter.TOP)
lable4.pack(side = tkinter.TOP)
frm2.pack(side = tkinter.RIGHT)

win.mainloop()
```

```python
#绝对定位
import tkinter
win = tkinter.Tk()
win.geometry("500x500+200+100")
lable1 = tkinter.Label(win,text = "小红",bg = "red",width = 20,height = 10)
lable2 = tkinter.Label(win,text = "小明",bg = "green",width = 20,height = 10)
lable3 = tkinter.Label(win,text = "李雷",bg = "yellow",width = 20,height = 10)

lable1.place(x = 0,y = 0)
lable2.place(x = 370,y = 0)
lable3.place(x = 0,y = 310)

win.mainloop()
```

```python
#相对定位
import tkinter
win = tkinter.Tk()
win.title("Python-14")
win.geometry("500x500+200+100")

label1 = tkinter.Label(win,text = "小红",bg = "red")
label2 = tkinter.Label(win,text = "小明",bg = "green")
label3 = tkinter.Label(win,text = "李雷",bg = "yellow")
label1.pack(fill = tkinter.Y,side = tkinter.LEFT)
label2.pack(fill = tkinter.Y,side = tkinter.RIGHT)
label3.pack(fill = tkinter.X,side = tkinter.TOP)
label3.pack()

win.mainloop()
```

```python
#表格布局
import tkinter
win = tkinter.Tk()
win.title("Python-14")
win.geometry("500x500+200+100")

lable1 = tkinter.Label(win,text = "小红",bg = "red")
lable2 = tkinter.Label(win,text = "小黄",bg = "yellow")
lable3 = tkinter.Label(win,text = "小蓝",bg = "blue")
lable4 = tkinter.Label(win,text = "小粉",bg = "pink")
# 表格布局
lable1.grid(row = 0,column = 0)
lable2.grid(row = 0,column = 1)
lable3.grid(row = 1,column = 0)
lable4.grid(row = 1,column = 1)

win.mainloop()
```



# 事件绑定

> 之前能够触发操作的只有2个组件,一个按钮一个菜单的选项卡 command属性 设置操作对应的函数

### 鼠标事件类型

```python
<Button-1>          按下了鼠标左键      <ButtonPress-1>
<Button-2>          按下了鼠标中键      <ButtonPress-2>
<Button-3>          按下了鼠标右键      <ButtonPress-3>
<Enter>             鼠标进入组件区域
<Leave>             鼠标离开组件区域
<ButtonRelease-1>   释放了鼠标左键
<ButtonRelease-2>   释放了鼠标中键
<ButtonRelease-3>   释放了鼠标右键
<B1-Moion>          按住鼠标左键移动
<B2-Moion>          按住鼠标中键移动
<B3-Moion>          按住鼠标右键移动
<Double-Button-1>   双击鼠标左键
<Double-Button-2>   双击鼠标中键
<Double-Button-3>   双击鼠标右键
<MouseWheel>      滚动鼠标滚轮
```

### 键盘事件类型

```python
<KeyPress>               表示任何键盘按下
<KeyPress-A>               表示按下键盘A键    A可以设置为其他的按键
<Alt-KeyPress-A>         表示同时按下Alt和A键    A可以设置为其他的按键
<Control-KeyPress-A>       表示同时按下Ctrl和A键    A可以设置为其他的按键
<Shift-KeyPress-A>         表示同时按下Shift和A键    A可以设置为其他的按键
<Double-KeyPress-A>      表示双击键盘A键    A可以设置为其他的按键
<Lock-KeyPress-A>          表示开启大写之后键盘A键    A可以设置为其他的按键
<Alt-Control-KeyPress-A>   表示同时按下alt+Ctrl和A键    A可以设置为其他的按键

注意:键盘事件除了entry和text组件其他组件的事件最好绑定在主界面上
```

### 事件对象中包含的信息

```python
x,y            当前触发事件时鼠标相对触发事件的组件的坐标值
x_root,y_root    当前触发事件时鼠标相对于屏幕的坐标值
char             获取当前键盘事件时按下的键对应的字符
keycode          获取当前键盘事件时按下的键对应的的ascii码
type             获取事件的类型
num            获取鼠标按键类型123 左中右
widget         触发事件的组件
width/height   组件改变之后的大小和configure()相关
```

### 窗口和组件相关事件类型

```python
Activate         当中组件由不可以用变为可用时针对于state的变值
Deactivate       当组件由可用变为不可用时触发
Configure      当组件大小发生变化时触发
Destory          当组件销毁时触发
FocusIn          当组件获取焦点时触发 针对于Entry和Text有效
Map            当组件由隐藏变为显示时触发
UnMap            当组件由显示变为隐藏时触发
Perproty         当窗口属性发生变化时触发
```



# 事件绑定函数

### 组件.bind('事件类型',事件函数)

```python
#为一个组件绑定一个操作
```

### 组件.bind_class('组件类型','事件类型',事件函数)

```python
#为一类组件绑定一个操作
#组件类型就是创建组件的方法名例如按钮组件:Button
```

### 组件.bind_all('事件类型',事件函数)

```python
#为所有组件绑定一个操作(所有操作都会当作对主界面的操作)      
```

```python
import tkinter
win = tkinter.Tk()
win.title("Python-14")
win.geometry("500x500+200+100")

def func(event):
    print(event.x,event.y)

button = tkinter.Button(win,text = "按钮",width = 50,height = 20)
button.bind("<Triple-Button-1>",func)
button.pack()
win.mainloop()
```



# 练习

### 文件对比

```python
import sys
import difflib

# sys.argv : 获取外部运行时的命令返回一个列表
# sys.argv : 获取外部运行时的命令返回一个列表
# print(sys.argv)
#
# file1 = sys.argv
# file2 = sys.argv
# print(file1)
# print(file2)

# difflib
    # 创建比对对象HtmlDiff()生成一个html文件
    # 比对内容   make_file()
```

```python
import sys
import difflib

# sys.argv : 获取外部运行时的命令返回一个列表
# sys.argv : 获取外部运行时的命令返回一个列表
# print(sys.argv)

# difflib
    # 创建比对对象HtmlDiff()生成一个html文件
    # 比对内容   make_file()

first_path = sys.argv # 获取第一个要比对的文件名称
next_path = sys.argv# 获取第二个要比对的文件名称

# 分别读取两个文件
with open(first_path,"r") as f:
    first_list = f.readlines()
with open(next_path,"r") as f:
    next_list = f.readlines()

# 生成比对对象
diff = difflib.HtmlDiff()
html = diff.make_file(first_list,next_list)
with open("diff.html","w") as f:
    f.write(html)
```

```python
# win+Rcmd   cd到文件当前地址   
# python文件名.py文件1文件2
```



### 计算器

```python
from tkinter import *
root = Tk()
root.geometry('250x380')
root.title('计算器')
frame_show = Frame(width=300,height=150,bg='#dddddd')

#顶部区域

v = StringVar()
v.set('0')
show_label = Label(frame_show,textvariable =v, bg = 'white',width=12,height=1,font=("黑体", 20, "bold"),justify=LEFT,anchor='e')
show_label.pack(padx = 10,pady = 10)
frame_show.pack()

#是否按下了运算符
isopear = False

#操作序列
calc = []
def change(num):
    global isopear
    if isopear == False:
      if v.get() == '0':
            v.set('')
            v.set(num)
      else:
            v.set(v.get()+num)
    else:
      v.set(num)
      isopear = False

#运算
def operation(sign):
    global isopear
    global calc
    isopear = True
    calc.append(v.get())
    if sign == '+':
      calc.append('+')
    elif sign == '-':
      calc.append('-')
    elif sign == '*':
      calc.append('*')
    elif sign == '/':
      calc.append('/')
    print(calc)

def equal():
    global calc
    #获取当前界面的数值准备运算
    calc.append(v.get())
    print(calc)
    #组成运算字符串
    calcstr = ''.join(calc)
    #检测最后一位是否是运算符,是就删除
    if calcstr[-1] in '+-*/':
      calcstr = calcstr
    #print(calcstr)
    #运算操作
    result = eval(calcstr)
    #显示结果
    v.set(result)
    calc.clear()

#删除操作
def delete():
    if v.get() == '' or v.get() == '0':
      v.set('0')
      return
    else:
      num = len(v.get())
      if num > 1:
            strnum = v.get()
            strnum = strnum
            v.set(strnum)
      else:
            v.set('0')

#清空操作
def clear():
    global calc
    calc = []
    v.set('0')
    isopear = False

#正负操作
def fan():
    strnum = v.get()
    if strnum == '-':
      v.set(strnum)
    elif strnum != '-' and strnum != '0' :
      v.set('-'+strnum)

#按键区域
frame_bord = Frame(width=400,height=350,bg='#cccccc')
button_del = Button(frame_bord,text = '←',width = 5,height =1,command = delete).grid(row = 0,column = 0)
button_clear = Button(frame_bord,text = 'C',width = 5,height =1,command = clear).grid(row = 0,column = 1)
button_fan = Button(frame_bord,text = '±',width = 5,height =1,command = fan).grid(row = 0,column = 2)
button_ce = Button(frame_bord,text = 'CE',width = 5,height =1,command = clear).grid(row = 0,column = 3)
button_1 = Button(frame_bord,text = '1',width = 5,height =2,command = lambda:change('1')).grid(row = 1,column = 0)
button_2 = Button(frame_bord,text = '2',width = 5,height =2,command = lambda:change('2')).grid(row = 1,column = 1)
button_3 = Button(frame_bord,text = '3',width = 5,height =2,command = lambda:change('3')).grid(row = 1,column = 2)
button_jia = Button(frame_bord,text = '+',width = 5,height =2,command = lambda:operation('+')).grid(row = 1,column = 3)
button_4 = Button(frame_bord,text = '4',width = 5,height =2,command = lambda:change('4')).grid(row = 2,column = 0)
button_5 = Button(frame_bord,text = '5',width = 5,height =2,command = lambda:change('5')).grid(row = 2,column = 1)
button_6 = Button(frame_bord,text = '6',width = 5,height =2,command = lambda:change('6')).grid(row = 2,column = 2)
button_jian = Button(frame_bord,text = '-',width = 5,height =2,command = lambda:operation('-')).grid(row = 2,column = 3)
button_7 = Button(frame_bord,text = '7',width = 5,height =2,command = lambda:change('7')).grid(row = 3,column = 0)
button_8 = Button(frame_bord,text = '8',width = 5,height =2,command = lambda:change('8')).grid(row = 3,column = 1)
button_9 = Button(frame_bord,text = '9',width = 5,height =2,command = lambda:change('9')).grid(row = 3,column = 2)
button_cheng = Button(frame_bord,text = 'x',width = 5,height =2,command = lambda:operation('*')).grid(row = 3,column = 3)
button_0 = Button(frame_bord,text = '0',width = 5,height =2,command = lambda:change('0')).grid(row = 4,column = 0)
button_dian = Button(frame_bord,text = '.',width = 5,height =2,command = lambda:change('.')).grid(row = 4,column = 1)
button_deng = Button(frame_bord,text = '=',width = 5,height =2,command = equal).grid(row = 4,column = 2)
button_chu = Button(frame_bord,text = '/',width = 5,height =2,command = lambda:operation('/')).grid(row = 4,column = 3)
frame_bord.pack(padx = 10,pady = 10)

root.mainloop()
```

======================

帖子很长,收藏下来必然某天用得到。笔记是我自己整理并一直在使用的。有错误请反馈,谢谢。
喜欢请点击下方免费评分,谢谢
======================
还有几帖你一定会喜欢的:
Python资源大全:https://www.52pojie.cn/thread-1081229-1-1.html
Python tkinter UI指南 https://www.52pojie.cn/thread-1290751-1-1.html
原生 Javascript 实现 jQuery 的功能: https://www.52pojie.cn/thread-1084552-1-1.html
Chrome调试器Console的进阶用法 https://www.52pojie.cn/thread-1156239-1-1.html
Javascript 极限省字节(看懂混淆后的代码) https://www.52pojie.cn/thread-1056860-1-1.html
写JS必备,ESLINT配置说明 https://www.52pojie.cn/thread-1290700-1-1.html
======================

Tairraos 发表于 2020-10-25 19:58

jy02427010 发表于 2020-10-25 19:52
那发给我吧

我的笔记为什么要发给你?评分都没一个,还要做伸手党。百度合适你

Tairraos 发表于 2020-10-25 23:38

boxer 发表于 2020-10-25 23:23
不是啊, HTML写界面, python加载, 并导出接口给界面引擎用, 或者通过事件响应
IE, wke, miniblink,htmla ...

长见识了。{:1_921:} {:1_921:}

有什么工具是用python加你说的这些库写的吗?我百了下都是c库绑了个浏览器内核。如果是c库就不能跨平台了,要为每个平台打包,并且尺寸大。

象switch下载CDNSP-GUI(https://github.com/Bob123a1/CDNSP-GUI/),就是单个py文件,几十K就跑出好用的UI.

青衫桑 发表于 2020-10-25 13:32

要是配上图会更好

jy02427010 发表于 2020-10-25 14:26

弄一个PYQT5的总结教程啊

额微粒波地 发表于 2020-10-25 14:41

感谢分享

ciker_li 发表于 2020-10-25 15:27

贴这么长,挺累吧

Tairraos 发表于 2020-10-25 15:31

ciker_li 发表于 2020-10-25 15:27
贴这么长,挺累吧

笔记里帖出来的,你不喜欢可以不看,如果是讽刺就不好了。

正己 发表于 2020-10-25 15:39

最好配个图,比较直观

忆白学渣 发表于 2020-10-25 15:48

这个好啊

Tairraos 发表于 2020-10-25 15:57

本帖最后由 Tairraos 于 2020-12-12 11:28 编辑

jy02427010 发表于 2020-10-25 14:26
弄一个PYQT5的总结教程啊
QT我也有学习笔记。
但是QT要安装,别人的电脑上只有脚本是不能跑的,要编译了打包给别人用。
第二个,QT太复杂了,速成不了。笔记分享出来太大了

tk和QT一样跨平台,tk的缺点是只能做比较简单的GUI,窗体呀什么的。但对优化工具脚本体验来说已经足够了,所以,建议大家用tk比较合适。

Tairraos 发表于 2020-10-25 15:58

正己 发表于 2020-10-25 15:39
最好配个图,比较直观

代码直接帖在idle里就能跑出界面来,看图不如上手一试? (其实是Low。。。我用typora做笔记的,本并不支持图片。)
页: [1] 2 3 4 5
查看完整版本: Python tkinter UI指南