Python的学习心得和知识总结(十二)|Python图形用户接口编程(Graphical User Interface编程 一)
从本节开始,我们将开始新的学习和分享:360百科:GUI编程。前面写过的程序都是基于控制台的,即用户与程序的交互通过Console来完成的。
图形用户接口编程
- GUI的简介
- Python常见的GUI库
- 第一个GUI程序
- GUI编程的整体描述
- 常见组件汇总及说明
- Lable
- Options
- Button
- Entry
- Text
- GUI面向对象的应用程序开发(模板)
GUI的简介
所谓GUI(图形用户接口)是相较于命令行(DOS UNIX系列)而言的:和计算机使用的命令行界面相比,图形界面对于用户来说在视觉上更易于接受,展示效果也更加美观。
这种图形化交互界面在实现上类似于搭积木(or 拼图)游戏,一个个的组件(Widget)被组合到一起 放置到一个窗口(Window)里面,进行渲染呈现。(对于Python而言,丰富的组件足以支撑快速的实现 图形界面和用户交互)
我们大家如果学过JSP 或者 ASP等,这些组件相当于页面的button text list等。然后加上对于组件上发生事件的处理响应就构成了一个完整的程序。
Python常见的GUI库
- Tkinter(Tk interface):是Python的标准GUI库,支持扩平台的GUI程序开发。优点:适于简易图形用户界面的快速开发
- wxPython:比Tkinter更加流行和功能更强大的GUI库,类似于Windows编程的Microsoft的MFC框架。优点:适合于大型应用程序的开发
- PyQT:谈及GUI编程,我们大家都会想到QT。它是开源的GUI库,同样适用于大型图形用户接口编程。而这里的PyQT就是QT工具包标准的Python实现。当然,我们就可以直接使用QT Designer来设计和实现基于QT的GUI程序开发
OK,我们这里主要是学习Tkinter库,其中文文档在线阅读:Tk图形用户界面(GUI)和An Introduction to Tkinter
第一个GUI程序
注:上面的root.mainloop()
是主窗口的mainloop事件循环。负责监听用户的触发事件的发生,然后在发生事件后调用相应的事件处理,最后反复监测(死循环相当于)。
但是上面仅仅是一个空的主窗口,OK 下面我们来加上一些组件:
但是上面程序运行之后,弹出来的主窗口位置在于左上角。我们下面就借助于geometry('wxh±x±y')
来设置主窗口的位置:
w 是宽度,h是高度
+x 表示距屏幕左边的距离,-x表示距屏幕右边的距离
+y 表示距屏幕上边的距离,-y表示距屏幕下边的距离
示例如下:
OK,这就是GUI编程的一个简单实例,下面我们来详细看一下GUI编程的整体描述:
GUI编程的整体描述
上面也说过了 图形用户界面的设计和 “拼图游戏” 差不多,相互集成在主窗口里面的诸多组件共同组成了整个用户界面。(若是一个组件里面还可以放置组件,则其被称为容器)下面是Tkinter的GUI组件继承关系图:
1、上面的Wm:主要是用作和窗口管理器间的通信
2、Misc:所有组件的根父类
3、TopLevel:最顶层的一个弹框(不搞定它,别的都动不了)
4、Pack、Place和Grid:布局管理器(管理组件 大小 位置),合理的排布组件
5、Tk:应用程序的主窗口(一般应用程序都直接or间接使用Tk)
6、BaseWidget:所有组件的父类
7、Widget:所有组件类的父类,它继承自四个父类。所有GUI组件都有这四个父类的属性和方法
8、Frame:它是Tkinter组件的一个框架组件,表示一个虚拟长方形的区域(可以看做是一个容器,从而实现复杂的布局)。
OK,如果我们大家想看一下 类的继承层次结构
,可以在类的定义处,右键-->Diagram-->show Diagram
常见组件汇总及说明
OK,上面有我们的皇族坐镇,下面开始各个组件的详细说明:
Lable
Lable 即标签,主要用于显示静态信息 如:文本信息(也可以显示图像)。其常见属性如下:
1、width 和 height:用于指定区域大小。如果显示是文本,则以单个英文字符大小为单位(一个汉字宽度占 2个字符位置,高度和英文字符一样);如果显示是图像,则以像素为单位。默认值是根据具体显示的内容动态调整。
2、font:指定字体和字体大小,如:font = (font_name,size)
3、image:显示在 Label 上的图像,目前 tkinter 只支持.gif
格式。
4、fg(foreground)和 bg(background):前景色 背景色
5、justify:针对多行文字的对齐,可设置 justify 属性,可选值"left"、"center" 和 "right"
下面来看一下,我们使用Lable实现:一行、图像和多行:
#coding=utf-8
'''
Author :SongBaoBao
Project :MyGUI
FileName:Simple_Template.py
Currtime:2020/7/11--04:42
Commpany:Tsinghua University
MyCsdnIs:https://blog.csdn.net/weixin_43949535
MyLolLpl:Royal Never Give Up
'''
#
# 以后所有的GUI编程(OOP)的初始模板
# from tkinter import *
from tkinter import messageboxclass myApplication(Frame):"""类 Application继承了 Frame 及通过继承拥有了父类的特性;并组织整个 GUI 程序"""def __init__(self,master=None): # 定义构造函数super().__init__(master) # 调用父类的构造器,super()是代表父类的定义 而非父类对象self.master=masterself.pack() # self本身就是一个组件self.createWidget()def showMessage(self):messagebox.showinfo("Message","Your name is SongBaoBao!")def createWidget(self):"""创建窗口中的对象(创建组件),self就是这个组件容器:return:"""# ************************************** ## 创建一个Lableself.lable1=Label(self,text="你是一个小可爱!",width=16,height=2,bg="gold",fg="#5CADAD",font=("STXingkai",24))self.lable1.pack()# ************************************** ## 创建一个Lable 显示图像global myPicture # 声明成全局变量,否则本方法执行完 图像对象消失了(窗口无法显示)myPicture=PhotoImage(file="../bear.gif")self.lable2=Label(self,image=myPicture)self.lable2.pack()# ************************************** ## 创建一个Lable 显示多行文本self.lable3=Label(self,text="Royal Never Give Up\n皇族永不言败",borderwidth=2,relief="groove",justify="center",font=("STXingkai",32))self.lable3.pack()if __name__=='__main__':# 第一步:通过类的默认构造函数 来构造主窗口对象root=Tk()root.title("这是窗口标题")root.geometry('1000x800+500+250') # 距离左边500 上边250# 第二步:创建一个对象app = myApplication(master=root) # 意思就是这个app会放在root主窗口里面# 最后开启事件循环root.mainloop()
来看一下效果:
大家也注意到了在上面 创建一个Lable的时候,通过传入不同的参数实现标签的不一样的展示效果
。
Options
这些Options的设置控制了该组件的不同状态,选项参数的设置是可以有下面三种方式:
# 创建一个Lable
self.lable1 = Label(self,text="你是一个小可爱!",height=2,fg="#5CADAD",font=("STXingkai",24)) # 这样传 这些参数都被构造方法的 **kw 进行接收
self.lable1["width"]=16 # 创建对象后,使用字典索引方式([]运算符重载)
self.lable1.config(bg="gold") # 创建对象后,使用 config()方法# 注:上面三种最终都会到_configure方法上
对于上面的这个Lable组件,我们可以有两种方式来查看Options选项:
第一种:config()方法的返回值字典
mydict=self.lable1.config()print(type(mydict))for key, value in mydict.items():print('\033[1;35m',key,'\033[0m',end=":")print(value)
打印结果如下所示:
第二种:查看组件的构造函数
class Label(Widget):"""Label widget which can display text and bitmaps."""def __init__(self, master=None, cnf={}, **kw):"""Construct a label widget with the parent MASTER.STANDARD OPTIONSactivebackground, activeforeground, anchor,background, bitmap, borderwidth, cursor,disabledforeground, font, foreground,highlightbackground, highlightcolor,highlightthickness, image, justify,padx, pady, relief, takefocus, text,textvariable, underline, wraplengthWIDGET-SPECIFIC OPTIONSheight, state, width"""Widget.__init__(self, master, 'label', cnf, kw)
上面两种方式都可以看到组件Lable的诸多Option,在第二种里面有:“standard options 标准选项”和“widget-specific options 组件特定选项”
:
OK 我们将常见的选项做一个简单的汇总 如下:
Button
按钮用来执行用户的单击操作。Button 可以包含文本,也可以包含图像。按钮被单击后会自动调用对应事件所绑定的方法。
下面就来看一下,文本button和图片button的使用:
注:有时候我们会遇到一个处于灰色状态的按钮(点不动):
self.b = Button(self, text="Help", state=DISABLED)self.b.pack()
Entry
上面汇总的时候,已经提过了:Entry是一个单行输入框(用户可以输入内容)。注:当用户输入的文字长度超过Entry 组件的宽度时,文字会自动向后滚动。如果想输入多行文本,则需要使用 Text 控件。
下面来看一个实例:
上面就完美的显示了:输入框里的默认提示信息的打印
上面我们在登录点击之后,后台就得到了用户输入的相关信息(上面在输入密码的时候是明码)于是修正如下:
源代码如下:
#coding=utf-8
'''
Author :SongBaoBao
Project :MyGUI
FileName:myEntry.py
Currtime:2020/7/11--15:37
Commpany:Tsinghua University
MyCsdnIs:https://blog.csdn.net/weixin_43949535
MyLolLpl:Royal Never Give Up
'''
#
# 测试单行文本框
# from tkinter import *
from tkinter import messageboxclass myApplication(Frame):"""类 Application继承了 Frame 及通过继承拥有了父类的特性;并组织整个 GUI 程序"""def __init__(self,master=None): # 定义构造函数super().__init__(master) # 调用父类的构造器,super()是代表父类的定义 而非父类对象self.master=masterself.pack() # self本身就是一个组件self.createWidget()def showMessage(self,messageStr):print("现在登录的人的用户名:"+self.entry2.get()+" 密码是:",self.entry4.get())messagebox.showinfo("Message",messageStr)def createWidget(self):"""创建窗口中的对象(创建组件),self就是这个组件容器:return:"""# ************************************** ## 创建一个Lable 显示一行文本self.lable1 = Label(self, text="用户名:", borderwidth=2, relief="groove",justify="left", font=("STXingkai", 32),fg="#5CADAD")self.lable1.pack()# ************************************** ## 创建一个Entry 存放单行内容inputStr=StringVar() # 初始化 然后绑定(之后组件内容和inputStr变量内容保持一样)self.entry2=Entry(self,textvariable=inputStr)self.entry2.pack()inputStr.set("这里输入用户名")# ************************************** ## 创建一个Lable 显示一行文本self.lable3 = Label(self, text="密码", borderwidth=2, relief="groove",justify="left", font=("STXingkai", 32),fg="#5CADAD")self.lable3.pack()# ************************************** ## 创建一个Entry 存放单行内容inputStr2 = StringVar() # 初始化 然后绑定(之后组件内容和inputStr变量内容保持一样)self.entry4 = Entry(self, textvariable=inputStr2,show='*')self.entry4.pack()# ************************************** ## 创建一个Button 进行登录self.button5=Button(self,text="点击登录",command=lambda:self.showMessage("登录成功!"))self.button5.pack()if __name__=='__main__':# 第一步:通过类的默认构造函数 来构造主窗口对象root=Tk()root.title("这是窗口标题")root.geometry('1000x800+500+250') # 距离左边500 上边250# 第二步:创建一个对象app = myApplication(master=root) # 意思就是这个app会放在root主窗口里面# 最后开启事件循环root.mainloop()
Text
多行文本框主要是用于显示多行文本,还可以显示网页链接、图片、 HTML 页面、CSS 样式表、添加图片和添加组件等。因此,也常被当做简单的文本处理器、文本编辑器或者网页浏览器来使用。
OK,下面实现一个简单的文本编译器来详解Text特性(行开始为1,列开始为0)
首先第一点 请大家先看一下下面这个例子(然后思考一下问题所在):
上面这个插入位置 好像没有起作用 !
我们来详细看一下这个代码就会发现问题所在:在self.text1.insert(1.0,"hello宋")
结束的时候 还没有第二行,插入位置虽然为2.0 但是不起作用的。于是就直接将0123456789\nabcdefg
接在宋
的后面 于是结果如下:
此时的Text里面也就没有第三行,同理 上面的llllll
也就跟在上面一行的后面!
于是我们可以这么做:加上一行self.text1.insert(1.0,"hello\n宋")
OK,我们来把这个过程捋一捋:
1、在
self.text1.insert(1.0,"hello\n宋")
之后,实际上Text已经有两行内容
2、上面这句之后,第二行只有一个 宋 字(为2字符)。2.0, "0123456789\nabcdefg"
的意思就是在第二行的开始插入这句话。于是结束之后 新的第二行为:0123456789
,第三行为:abcdefg宋
3、于是这时候我们也有了第三行,3.3, "llllll\n"
表示在d
的位置放置"llllll\n"
。于是换行之后,新的第三行为:abcllllll
,第四行为:defg宋
好,这个小例子之后相信大家已经对Text的一些特点有了更加深入的了解!下面我们开始第二个例子(简易文本编译器):(下面是创建插件部分的内容)
def createWidget(self):"""创建窗口中的对象(创建组件),self就是这个组件容器:return:"""# ************************************** ## 创建一个Text 显示多行文本self.text1=Text(root,width=160,height=120,bg="gold",fg="#5CADAD",font=(72))self.text1.pack()self.text1.insert(1.0,"hello\n宋baobao")# ************************************** ## 创建多个Button 存放多个内容Button(self, text="插入文本", command = lambda:self.insertText("hello","world")).pack(side="left")Button(self, text="返还文本函数1", command=lambda: self.returnText1(1.1,2.1)).pack(side="left")Button(self, text="返还文本函数2", command=self.returnText2).pack(side="left")Button(self, text="增加一个图片", command=lambda: self.addPicture("../bear.gif")).pack(side="left")Button(self, text="增加一个按钮", command=lambda: self.addButton("这是一个按钮")).pack(side="left")Button(self, text="tag控制文本", command=self.setTag).pack(side="left")
最开始的效果就是:
1、插入文本函数:插入一个你喜欢的文本字符串
注:现在我的光标放在“宋”
后面,结果如下:
2、返还文本函数1:一个区域内的文本
3、返还文本函数2:Text全部的文本
4、增加一个图片
注:它是在Text的最后面做的增加(我这里若是多次添加图片 显示不出来)
5、增加一个按钮
注:在光标后面添加的按钮
6、通过tag控制文本
点击上面的下划线链接之后:(是由webShow(self,event)
实现的)
上面这个简单的小程序源码如下:
#coding=utf-8
'''
Author :SongBaoBao
Project :MyGUI
FileName:myText.py
Currtime:2020/7/10--9:43
Commpany:Tsinghua University
MyCsdnIs:https://blog.csdn.net/weixin_43949535
MyLolLpl:Royal Never Give Up
'''
#
# 测试多行文本框 Text
#
from tkinter import *
import webbrowser
from tkinter import messageboxclass myApplication(Frame):"""类 Application继承了 Frame 及通过继承拥有了父类的特性;并组织整个 GUI 程序"""def __init__(self,master=None): # 定义构造函数super().__init__(master) # 调用父类的构造器,super()是代表父类的定义 而非父类对象self.master=masterself.pack() # self本身就是一个组件self.createWidget()# ************************************** ## 插入文本函数:插入一个你喜欢的文本字符串def insertText(self,message1,message2):self.text1.insert(INSERT,message1) # 意思是:在光标所在的地方插入message1self.text1.insert(END,message2) # 意思是:在光标所在的地方插入message2# ************************************** ## 返还文本函数1def returnText1(self,str1,str2):print(self.text1.get(str1,str2))# ************************************** ## 返还文本函数2def returnText2(self):print(self.text1.get(1.0,END))# ************************************** ## 增加一个图片def addPicture(self,path):global mypictureself.mypicture=PhotoImage(file=path)self.text1.image_create(END,image=self.mypicture)# ************************************** ## 增加一个按钮def addButton(self,text):button1=Button(self.text1,text=text)self.text1.window_create(INSERT,window=button1)# ************************************** ## 打开一个链接def webShow(self,event):webbrowser.open("https://blog.csdn.net/weixin_43949535")# ************************************** ## 设置相关标签def setTag(self):# 清理掉Text全部数据self.text1.delete(1.0,END)# 插入一些文本信息self.text1.insert(1.0,"皇族永不言败\nRNG加油!\n这是一个链接!")# 设置第一个标签self.text1.tag_add("皇族",1.0,1.12)self.text1.tag_config("皇族",background="gold",font=("STXingkai",12))# 设置第二个tagself.text1.tag_add("link",3.0,3.12)self.text1.tag_config("link",underline=True)self.text1.tag_bind("link","<Button-1>",self.webShow)def createWidget(self):"""创建窗口中的对象(创建组件),self就是这个组件容器:return:"""# ************************************** ## 创建一个Text 显示多行文本self.text1=Text(root,width=160,height=120,bg="gold",fg="#5CADAD",font=(72))self.text1.pack()self.text1.insert(1.0,"hello\n宋baobao")# ************************************** ## 创建多个Button 存放多个内容Button(self, text="插入文本", command = lambda:self.insertText("hello","world")).pack(side="left")Button(self, text="返还文本函数1", command=lambda: self.returnText1(1.1,2.1)).pack(side="left")Button(self, text="返还文本函数2", command=self.returnText2).pack(side="left")Button(self, text="增加一个图片", command=lambda: self.addPicture("../bear.gif")).pack(side="left")Button(self, text="增加一个按钮", command=lambda: self.addButton("这是一个按钮")).pack(side="left")Button(self, text="tag控制文本", command=self.setTag).pack(side="left")if __name__=='__main__':# 第一步:通过类的默认构造函数 来构造主窗口对象root=Tk()root.title("这是窗口标题")root.geometry('1000x800+500+250') # 距离左边500 上边250# 第二步:创建一个对象app = myApplication(master=root) # 意思就是这个app会放在root主窗口里面# 最后开启事件循环root.mainloop()
GUI面向对象的应用程序开发(模板)
注:这个自从进入GUI编程之后,下面的代码示例(OOP思想)可以作为将来这一类的程序开发的最初模板:
#coding=utf-8
'''
Author :SongBaoBao
Project :MyGUI
FileName:Simple_Template.py
Currtime:2020/7/11--04:42
Commpany:Tsinghua University
MyCsdnIs:https://blog.csdn.net/weixin_43949535
MyLolLpl:Royal Never Give Up
'''
#
# 以后所有的GUI编程(OOP)的初始模板
# from tkinter import *
from tkinter import messageboxclass myApplication(Frame):"""类 Application继承了 Frame 及通过继承拥有了父类的特性;并组织整个 GUI 程序"""def __init__(self,master=None): # 定义构造函数super().__init__(master) # 调用父类的构造器,super()是代表父类的定义 而非父类对象self.master=masterself.pack() # self本身就是一个组件self.createWidget()def showMessage(self):messagebox.showinfo("Message","Your name is SongBaoBao!")def createWidget(self):"""创建窗口中的对象(创建组件),self就是这个组件容器:return:"""# ************************************** ## 创建一个buttonself.button1=Button(self)self.button1["text"]="点击一下"self.button1.pack() # 通过布局管理器放到窗口里面self.button1["command"]=self.showMessage# ************************************** ## 创建一个退出buttonself.quitButton1=Button(self,text="退出",command=root.destroy)self.quitButton1.pack()if __name__=='__main__':# 第一步:通过类的默认构造函数 来构造主窗口对象root=Tk()root.title("这是窗口标题")root.geometry('500x300+500+250') # 距离左边500 上边250# 第二步:创建一个对象app = myApplication(master=root) # 意思就是这个app会放在root主窗口里面# 最后开启事件循环root.mainloop()
Python的学习心得和知识总结(十二)|Python图形用户接口编程(Graphical User Interface编程 一)相关推荐
- Oracle的学习心得和知识总结(二十五)|Oracle数据库Real Application Testing之真实应用测试概述白皮书
目录结构 注:提前言明 本文借鉴了以下博主.书籍或网站的内容,其列表如下: 1.参考书籍:<Oracle Database SQL Language Reference> 2.参考书籍:& ...
- PostgreSQL的学习心得和知识总结(二十四)|CentOS环境 配置生成coredump程序崩溃内存转储文件及gdb调试core文件
目录结构 注:提前言明 本文借鉴了以下博主.书籍或网站的内容,其列表如下: 1.使用GDB分析core dump文件,点击前往 2.详解coredump,点击前往 3.PostgreSQL数据库仓库链 ...
- HTML的学习心得和知识总结(二)|HTML基础和高级标签汇总
目录结构 HTML基础和高级标签汇总 文章快速说明索引 HTML 的基础标签 HTML 的高级标签 文章快速说明索引 学习目标: 可视化和部分交互功能的前端开发内容的学习:HTML CSS JavaS ...
- C++的学习心得和知识总结(十六)|基于EasyX实现小甲鱼Python飞机大战项目(C++版)
目录结构 注:提前言明 本文借鉴了以下博主.书籍或网站的内容,其列表如下: 1.小甲鱼Python项目 – 飞机大战 2.本文使用的掩码图生成工具 自动生成遮罩图的程序,点击前往 3.EasyX官方链 ...
- C++的学习心得和知识总结(十八)|基于EasyX实现 2048游戏 项目(C/C++版)
目录结构 注:提前言明 本文借鉴了以下博主.书籍或网站的内容,其列表如下: 1.网络热门游戏 2048,点击前往 2.EasyX官方链接,点击前往 3.中国色谱 颜色代码对照表(RGB多用于easyX ...
- 【飞桨/百度领航团/零基础Python】学习心得
[飞桨/百度领航团/零基础Python]学习心得 课程链接:https://aistudio.baidu.com/aistudio/course/introduce/7073 初识python Pyt ...
- python学生信息管理系统心得体会-Python的学习心得
Python的学习心得 首先很庆幸自己选到了这门个性化选修课,可能是我个人比较认为这门课程所用的语言很特别很奇妙,老师也很有趣,能让我们更好的了解Python这门课程真正的用途.在学习Python这门 ...
- python自学需要哪些基础知识-零基础学Python应该学习哪些入门知识及学习步骤安排...
众所周知,Python以优雅.简洁著称,入行门槛低,可以从事Linux运维.Python Web网站工程师.Python自动化测试.数据分析.人工智能等职位!就目前来看,Python岗位人才缺口高达4 ...
- python心得体会-终于懂得python基础学习心得
为了提高模块加载的速度,每个模块都会在__pycache__文件夹中放置该模块的预编译模块,命名为module.version.pyc,version是模块的预编译版本编码,一般都包含Python的版 ...
- python自学步骤-零基础学Python应该学习哪些入门知识及学习步骤安排
众所周知,Python以优雅.简洁著称,入行门槛低,可以从事Linux运维.Python Web网站工程师.Python自动化测试.数据分析.人工智能等职位!就目前来看,Python岗位人才缺口高达4 ...
最新文章
- 【自动驾驶】10.百度Apollo平台 事件通信机制
- 轻松搞定日志的可视化(第一部分)
- 借助云开发轻松实现后台数据批量导出丨实战
- [原创]windows server 2012 AD架构 试验 系列 – 15解决AD复制冲突
- 虚拟按键自己触发的java代码_在SystemUI添加虚拟按键
- android nv21图片格式,Android -- 将NV21图像保存成JPEG
- iClip mac如何自定义声音?iClip剪切板管理软件更改声音的方法
- nginx 域名跳转
- ISO27001体系的价值(详解)
- PHP微信公众号授权登录
- 王小九用计算机弹桥边姑娘,抖音最火歌曲是哪首?QQ音乐开放平台《桥边姑娘》让“野狼”靠边站...
- 智能宠物饲养系统设计
- app上架360手机助手流程
- python 频数统计_日常答疑:Python实现分类频数统计
- Xshell的Sessions存放目录
- 找出字符串中第一个不重复的字符
- 【What if 系列】全球雪封
- [每日100问][2011-9-06]iphone开发笔记,今天你肿了么
- openCV中watershed的使用
- 黄金斗士原生android,28日京东开售 联想黄金斗士S8正式发布
热门文章
- 编译原理实验-用FLEX自动构造词法分析程序
- 用python批量发送短信_Python批量发短信
- CSDN博客成长记录
- Ethernet/IP以太网接M12 X-Coded 协议:port1(Ethernet连接)
- DBLink应用速成
- 将一个大写英文字母转换为小写输出 (12 分) - PTA
- Java JUC包的学习文章整理以及整体结构功能概述
- 数据结构C语言般卷纸真题,数据结构(C语言版)考研真题(A卷)
- 【学习笔记】通过雷达获取某一角度的距离信息
- html显示千分位及小数位,使用CSS格式化数字(小数位,千位分隔符等)