目录
代码演示
经典GUI面向编程
常见控件
控件对象属性设置方法
lable标签
输入控件Entry
Text多行文本框
单(复)选框
画布Canvas
布局管理器
grid布局管理器
pack布局管理器
place布局管理器
事件对象
鼠标和键盘事件
event对象常用属性
Tkinter
tkinter (Tk interface)是Python的标准GUI库,支持跨平台的GUI程序开发。tkinter 适合小型的GUI程序编写,特别适合初学者学习GUI编程。
Python GUI 编程(Tkinter) | 菜鸟教程
Python Tkinter-Python 手册 - Python学习网
tkinter —— Tcl/Tk 的 Python 接口 — Python 3.10.1 文档
Python Qt图像界面编程_北冥有鱼的博客-CSDN博客
wxPython
wxPython是比较流行的GUI库,适合大型应用程序开发,功能强于tkinter,整体设计框架类似于MFC(Microsoft Foundation Classes微软基础类库)。
代码演示
from tkinter import * from tkinter import messagebox root = Tk() # 创建窗口对象 root.title('窗口1') # 定义窗口的标题 root.geometry('500x300+300+200') # 定义窗口显示大小和显示位置 but1 = Button(root) # 创建一个按钮对象 but1['text'] = '点我☞' but1.pack() def click(event): name = '《节妇吟·寄东平李司空师道》' text = ''' 《节妇吟·寄东平李司空师道》 ——唐·张籍 君知妾有夫,赠妾双明珠。 感君缠绵意,系在红罗襦。 妾家高楼连苑起,良人执戟明光里。 知君用心如日月,事夫誓拟同生死。 还君明珠双泪垂,恨不相逢未嫁时。 ''' messagebox.showinfo(name, text) # 参数:弹窗标题,内容 but1.bind('<1>', click) root.mainloop() # 调用mainloop()组件,进行事件循环
主窗口位置和大小:通过geometry('wx±x±y')进行设置。w为宽度, h为高度。+x表示距屏幕左边的距离; -x 表示距屏幕右边的距离; +y表示距屏幕上边的距离;-y表示距屏幕下边的距离。
# tk.py
from tkinter import *
from tkinter import messagebox
from tk import shici
class App(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.createWidget()
def createWidget(self):
'''
创建组件
:return:
'''
# 创建一个按钮组件
but1 = Button(self)
but1['text'] = '点我☞'
but1['command'] = self.shici
but1.pack()
def shici(self):
text = shici.shici['《节妇吟·寄东平李司空师道》']
messagebox.showinfo('《节妇吟·寄东平李司空师道》', '《节妇吟·寄东平李司空师道》\n' + text)
if __name__ == '__main__':
root = Tk()
root.title('demo')
root.geometry('500x300+300+200')
t = App(master=root)
root.mainloop()
t.createWidget()
# shici.py
shici = {
'《节妇吟·寄东平李司空师道》':'\t\t\t——唐·张籍\n君知妾有夫,赠妾双明珠。\n感君缠绵意,系在红罗襦。\n妾家高楼连苑起,良人执戟明光里。'
'\n知君用心如日月,事夫誓拟同生死。\n还君明珠双泪垂,恨不相逢未嫁时。'
}
设置组件属性控制组件的各种状态,如:宽度、高度、颜色、位置等。设置的三种方法:
1.创建对象时,使用关键字参数:fd = Button(self, fg="red", bg= "blue")
2.创建对象后,使用字典索引方式:fd["fg"] = "red" ; fd["bg"] = "blue"
3.创建对象后,使用config0方法:fd.config(fg="red", bg= "blue")
标签属性
1. width,height:用于指定区域大小,如果显示是文本,则以单个英文字符大小为单位(一个汉字占2个字符位置);如果显示是图像,则以像素为单位。默认值是根据具体显示的内容动态调整。
2.font:指定字体和字体大小,如:font=(font_name,size)
3. image:显示在Label上的图像,目前tkinter只支持gif格式。
4.fg和bg:fg (foreground) :前景色、bg (background) :背景色
5. justify:针对多行文字的对齐,可设置justify属性,可选值"left"、"center" or "riaht"
from tkinter import * class App(Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.pack() self.createWidget() def createWidget(self): # 1、创建一个退出按钮 butQuit = Button(self, text='退 出', command=root.destroy) butQuit.pack(side='left') # 2、创建Lable组件 Label(self, text='学习使我快乐\n不死不休\n不眠不止', width=50, height=8, bg='red', fg='blue', font=('华文新魏', 12)).pack() # 3、图片显示 global photo # 将photo声明成全局变量。如果是局部变量,本方法执行完毕后,图像对象销毁,窗口显示不出图像 photo = PhotoImage(file='./img/logo.png') lable_img = Label(image=photo) lable_img.pack() if __name__ == '__main__': root = Tk() root.title('demo') root.geometry('500x300+300+200') t = App(master=root) root.mainloop() t.createWidget()
Entry用来接收一行字符串的控件。
如果用户输入的文字长度长于Entry控件的宽度时,文字会自动向后滚动。
如果想输入多行文本,需要使用Text 控件。from tkinter import * from tkinter import messagebox class App(Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.pack() self.createWidget() def createWidget(self): Label(self, text='用户名', font=('华文新魏', 15)).pack() password = Label(self, text='密 码', font=('华文新魏', 15)) ''' StringVar变量绑定到指定的组件 StringVar变量的值发生变化,组件内容也变化; 组件内容发生变化,StringVar变量的值也发生变化 ''' v1 = StringVar() self.um = Entry(self, textvariable=v1) self.um.pack() password.pack() v2 = StringVar() self.pd = Entry(self, textvariable=v2, show='·') self.pd.pack() Button(self, text='登 录', bg='#33ccff', command=self.login).pack() def login(self): username = self.um.get() password = self.pd.get() if username == 'jbb' and password == '123456': messagebox.showinfo('欢迎登录', '恭喜你登录成功!') else: messagebox.showinfo('欢迎登录', '对不起,您输入的用户名或密码错误,请重新登陆') if __name__ == '__main__': root = Tk() root.title('demo') root.geometry('500x800+300+200') t = App(master=root) root.mainloop() t.createWidget()
Text(多行文本框)主要用于显示多行文本,还可以显示网页链接,图片, HTML页面,甚至CSS样式表,添加组件等。因此,也常被当做简单的文本处理器、文本编辑器或者网页浏览器来使用。比如IDLE就是Text组件构成的。
''' 经典GUI程序——面向对象编程 ''' from tkinter import * import webbrowser class App(Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.pack() self.createWidget() def createWidget(self): # 多行文本框 ''' indexes (索引)是用来指向Text组件中文本的位置,Text的组件索引也是对应实际字符之间的位置。行号以1开始,列号以0开始 ''' self.w1 = Text(self, width=50, height=12, bg='#ccccb3') self.w1.pack() self.w1.insert(1.0, '名句:\n') self.w1.insert(2.2, '好风凭借力,\n送我上青云') Button(self, text='插入内容', command=self.insertText).pack(side='left') Button(self, text='获取内容', command=self.returnText).pack(side='left') Button(self, text='插入图片', command=self.addImg).pack(side='left') Button(self, text='新增控件', command=self.addWidget).pack(side='left') Button(self, text='搜 索', command=self.testText).pack(side='left') def insertText(self): self.w1.insert(INSERT, '\n\t\t薛宝钗') # INSERT表示在光标处插入内容 self.w1.insert(END, '\n\t\t——《红楼梦》词句') # END表示在末尾插入 def returnText(self): print(self.w1.get(1.0, END)) # 参数:获取文本内容的位置(起始坐标) def addImg(self): global photo photo = PhotoImage(file='img/logo.png') self.w1.image_create(END, image=photo) def addWidget(self): bt = Button(self.w1, text='newWidget') self.w1.window_create(END, window=bt) def testText(self): self.w1.delete(1.0, END) self.w1.insert(INSERT, '12345\nabcde\n百度一下\n呵呵呵!') self.w1.tag_add('百度一下', 3.0, 3.4) self.w1.tag_config('百度一下', background='yellow', foreground='red', underline=True, font=('华文新魏', 15)) self.w1.tag_bind('百度一下', '<1>', self.webshow) def webshow(self, event): webbrowser.open('http://www.baidu.com') if __name__ == '__main__': root = Tk() root.title('demo') root.geometry('500x300+300+200') t = App(master=root) root.mainloop() t.createWidget()
单选框
def createWidget(self): # 单选框 Label(self, text='性别:').pack(side='left') self.v = StringVar() self.v.set('1') # 设置默认选择值 self.r1 = Radiobutton(self, text='男', value='1', variable=self.v).pack(side='left') self.r2 = Radiobutton(self, text='女', value='0', variable=self.v).pack(side='left') Button(self, text='确定', command=self.confirm).pack(side='left') def confirm(self): xb = '男' if self.v.get() == '1' else '女' messagebox.showinfo('性别选择结果', '你选择的性别是:%s' % xb)
复选框
def createWidget(self): # 复选框 Label(self, text='爱好:').pack(side='left') self.hobby1 = IntVar() self.hobby2 = IntVar() self.c1 = Checkbutton(self, text='旅游', variable=self.hobby1, onvalue=1, offvalue=0).pack(side='left') self.c1 = Checkbutton(self, text='读书', variable=self.hobby2, onvalue=1, offvalue=0).pack(side='left') Button(self, text='确定', command=self.cof).pack(side='left') def cof(self): ah1, ah2 = self.hobby1.get(), self.hobby2.get() if ah1 == 1: messagebox.showinfo('爱好', '说走就走\n\n快乐尽在脚下') elif ah2 == 1: messagebox.showinfo('爱好', '皓首穷经\n\n学不可须臾而离也') else: messagebox.showinfo('你的爱好是啥?', '呜呼哀哉!\n\n一个没有灵魂的人生')
def createWidget(self): self.canvas = Canvas(self,width = 500,height = 200,bg = 'yellow') self.canvas.pack() self.canvas.create_line(10,10,30,30,50,100) # 画直线,每两组为一个点,形成点和点的连接形成线 self.canvas.create_rectangle(40,60,90,90) # 画矩形 self.canvas.create_oval(50,50,150,150) # 画(椭)圆 global photo photo = PhotoImage(file='img/logo.png') self.canvas.create_image(200,200,image = photo) # 添加图片
一个GUI应用程序必然有大量的组件,tkinter提供的布局管理器可组织、管理在父组件中子组件的布局方式。tkinter 提供了三种管理器: pack、 grid、 place。
grid表格布局,采用表格结构组织组件。子组件的位置由行和列的单元格来确定,并且可以跨行和跨列,从而实现复杂的布局。
pack按照组件的创建顺序将子组件添加到父组件中,按照垂直或者水平的方向自然排布。如果不指定任何选项,默认在父组件中自顶向下垂直添加组件。pack是代码量最少,最简单的一种,可以用于快速生成界面。
place布局管理器可以通过坐标精确控制组件的位置,适用于一些布局更加灵活的场景。
一个GUI应用整个生命周期都处在一个消息循环(event loop)中。它等待事件的发生,并作出相应的处理。
Tkinter提供了用以处理相关事件的机制。处理函数可被绑定给各个控件的各种事件。
widget.bind(event, handler)
如果相关事件发生,handler函数会被触发,事件对象event会传递给handler 函数。
from tkinter import * root = Tk() root.title() root.geometry() c = Canvas(root, width=100, height=200, bg='yellow') c.pack() def eve(event): print(event.x, event.y) c.bind('<1>', eve) root.mainloop()