0%

Python图形界面(GUI)程序设计

tkinter是python内置的一个模块,用它可以快速地设计开发简单的python图形界面程序。

在windows下就是一个窗口应用程序。

一、tkinter创建应用程序窗口:

例:如下代码创建了一个名为root的窗口(标题、大小、位置等默认)

1
2
3
4
5
import tkinter # 导入模块

root=tkinter.Tk() # 创建主窗口

root.mainloop() # 进入消息循环

如下代码创建了一个名为win的窗口(标题、大小、位置指定)

1
2
3
4
5
6
7
from tkinter import * # 导入模块

win=Tk() # 创建主窗口
win.title("Demo") # 设置标题
win.geometry('400x400+200+20') #设置窗口大小和位置

win.mainloop() # 进入消息循环

二、tkinter提供了一些常用组件(Widget),用于在窗口内显示不同形式的内容。

  1. Label组件:用于显示指定文字或图片

显示文本:

1
2
3
4
5
6
7
8
label=Label(win,text='要显示的文本内容',fg='red',bg='blue',font=('黑体',48,bold))
# win 父窗体
# text 要显示的文本内容
# fg 字体颜色 bg 背景色
# width:标签宽 heitht:标签高
# justify:文字对齐方式
# anchor:标签在窗体中的位置,center中间,n北,e东,s南,w西
label.pack() # 将标签显示在窗体中

显示图片:

1
2
3
photo=PhotoImage(file="brick.png") # 获取png图片文件或gif图片
label=Label(win,image=photo) # 显示在标签上
label.pack() # 在窗体中显示

要处理其它类型的图片需要安装第三方库:pip install Pillow

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import os
from tkinter import *
from PIL import Image,ImageTk

root=Tk()
root.title('Demo')
root.attributes("-topmost",1) # 窗口置顶
root.resizable(width=False,height=False) # 固定窗口大小

image_file=Image.open("timg.jpg")
photo=ImageTk.PhotoImage(image_file)
label=Label(root,image=photo)
label.pack()
# 设置图标
ico_path="sa2.ico"
if os.path.exists(ico_path):
root.iconbitmap(ico_path)

root.mainloop()
  1. Entry组件:用于数据输入或显示(单行)
1
2
3
4
5
6
7
e=Variable() # 邦定变量
entry=Entry(win,textvariable=e) # 创建输入框
entry.pack() # 显示在窗体中
# 取值:e.get() 或者:entry.get()
# 设置值:e.set()
# 密文显示:show='*'
# 设置只读:state='readonly'
  1. Text组件:用于多行文本输入或显示
1
2
3
4
text=Text(win,width=30,height=4)
text.pack()
content='''If there is anyone out there who still doubts that America is a place where all things are possible, who still wonders if the dream of our founders is alive in our time, who still questions the power of our democracy, tonight is your answerIt’s the answer told by lines that stretched around schools and churches in numbers this nation has never seen, by people who waited three hours and four hours, many for the first time in their lives, because they believed that this time must be different, that their voices could be that difference.'''
text.insert(INSERT,content)
1
2
3
4
5
6
7
8
9
10
11
12

scroll = tkinter.Scrollbar() #创建滚动条
text = tkinter.Text(win, width=50, height=8)

scroll.pack(side=tkinter.RIGHT, fill=tkinter.Y) #side放到窗体的那一侧 fill填充
text.pack(side=tkinter.LEFT, fill=tkinter.Y)
# 滚动条和文本框关联
scroll.config(command=text.yview)
text.config(yscrollcommand=scroll.set)

content = '''If there is anyone out there who still doubts that America is a place where all things are possible, who still wonders if the dream of our founders is alive in our time, who still questions the power of our democracy, tonight is your answerIt’s the answer told by lines that stretched around schools and churches in numbers this nation has never seen, by people who waited three hours and four hours, many for the first time in their lives, because they believed that this time must be different, that their voices could be that difference.'''
text.insert(tkinter.INSERT, content)
  1. Button组件:用于创建按钮执行指定程序
1
2
button=Button(win,text='退出',command=win.destroy) # 创建一个退出按钮
button.pack()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import tkinter

# 定义按钮执行函数
def func():
if label['text']!='':
label['text']=''
button1['text']='显示'
else:
label['text']='Hello'
button1['text']='隐藏'

win = tkinter.Tk()
win.title("Demo")
win.geometry("400x300+200+20")

label=tkinter.Label(win,text='',font=('Arial',40),fg='red')
label.pack()
#创建按钮
button1 = tkinter.Button(win, text="显示", command=func, width=10, height=2)
button1.pack()

button2 = tkinter.Button(win, text="关闭", command=win.destroy)
button2.pack()

win.mainloop()
  1. 更多组件自行百度

三、小练习

  1. 数字时钟:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from tkinter import *
import time

def show():
now = time.strftime("%H:%M:%S")
label.configure(text=now)
root.after(1000, show)

root = Tk()
root.title('数字时钟')
label = Label(text="", font=('Helvetica', 48), fg='red')
label.pack()

show()
root.mainloop()
  1. 移动字幕:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    from tkinter import *

    root = Tk()
    root.title("滚动字幕")
    root.geometry("500x240+100+100")

    show_str = "江苏省昆山中学欢迎你!"
    pos =500

    def run():
    global pos
    show_lb.place(x=pos, y=100)
    pos=pos-1
    if pos<-len(show_str)*26:
    pos=root.winfo_width()
    show_lb.after(18,run)

    show_lb = Label(root, text=show_str)
    show_lb.config(font=('楷体',20))
    show_lb.config(fg='red')

    run()
    root.mainloop()
  2. 随机(按学号)点名:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    from tkinter import *
    import random

    data=list(range(1,56))
    stop_show=True

    def show():
    if stop_show:
    return
    num=random.choice(data)
    show_label.config(text=num)
    root.after(50,show)

    def start(event):
    global stop_show
    stop_show=not stop_show
    show()

    root=Tk()
    root.title('随机点名')
    root.resizable(0,0)
    root.geometry('200x80')

    show_label=Label(root,text='888',font=('Arial',48,'bold'),fg='red')
    show_label.pack()

    root.bind('<Button-1>',start)

    root.mainloop()
  3. 简单加法计算器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from tkinter import *

app=Tk()
app.title('加法计算器')

frame=Frame(app)
frame.pack(padx=10,pady=10)

v1=StringVar()
v2=StringVar()
v3=StringVar()

def test(content):
return content.isdigit()

testCMD=app.register(test)

e1=Entry(frame,width=10,textvariable=v1,validate='key',validatecommand=(testCMD,'%P'))
e1.grid(row=0,column=0)

Label(frame,text='+').grid(row=0,column=1)

e2=Entry(frame,width=10,textvariable=v2,validate='key',validatecommand=(testCMD,'%P'))
e2.grid(row=0,column=2)

Label(frame,text='=').grid(row=0,column=3)

e3=Entry(frame,width=10,textvariable=v3,state='readonly')
e3.grid(row=0,column=4)

def calc():
result=int(v1.get())+int(v2.get())
v3.set(str(result))

Button(frame,text='计算',width=10,command=calc).grid(row=1,column=2,pady=10)

app.mainloop()
  1. 打字速度测试:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from tkinter import *
import time

begin=0
stop=0
zf=0
def start():
global zf ,begin
if button1['text']=='开始':
button1['text']='结束'
text.delete(1.0,"end")
text.focus()
begin=time.time()
else:
stop=time.time()
button1.focus()
button1['text']='开始'
contents=text.get(1.0,"end")
zf=len(contents)
if zf==1:
zf=0
ys=stop-begin
speed=round(zf/ys*60,2)
text.insert(INSERT,"\n\n本次用时:{}秒\n".format(ys))
text.insert(INSERT,"速度:{}字符/分钟!".format(speed))

win=Tk()
win.title('打字速度测试')
win.geometry("400x400+200+200")
win.resizable(0,0)

text=Text(win,width=50,height=20)
text.pack(pady=20)

button1=Button(win,text="开始",command=start,width=10,height=2,default='normal')
button1.pack()

win.mainloop()
  1. 无窗口标题栏数字时钟:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    from tkinter import *
    import time

    root=Tk()
    root.title('数字时钟')
    root.geometry("-0+0")
    root.resizable(0,0)
    root.overrideredirect(True)
    time_lbl=Label(text="",font=('Helvetica',48,'bold'),fg='red') # Helvetica,Arial
    time_lbl.pack()

    stop_show=False

    def show():
    if stop_show==True:
    return
    now=time.strftime("%H:%M:%S")
    time_lbl.configure(text=now)
    root.after(1000,show)

    def right_click(event):
    time.sleep(0.002)
    root.destroy()
    time_lbl.bind('<ButtonRelease-3>',right_click)

    def mouse_enter(event):
    global stop_show
    stop_show=True
    time_lbl.bind('<Enter>',mouse_enter)

    def mouse_leave(event):
    global stop_show
    stop_show=False
    show()
    time_lbl.bind('<Leave>',mouse_leave)

    def left_click(event):
    global stop_show
    stop_show=not stop_show
    show()
    time_lbl.bind('<Button-1>',left_click)

    show()
    root.mainloop()