python小练习--GUI设计

简介: python小练习--GUI设计

练习1:canvas画布的使用


测试画直线,圆形,半圆,三角形等图像,或者插入图片

from tkinter import *
from tkinter import messagebox
#定义坐标位置
lineposition = ((30,50),(300,100),(20,50))
rectposition = ((50,50),(100,100))
ovalposition = ((150,50),(250,150))
arcposition = ((350,50),(250,150))
coorposition = ((100,100),(50,150),(150,150),(80,200),(120,200))
class Application(Frame):
    def __init__(self,master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.TestCanvas()
    def TestCanvas(self):
        canvas = Canvas(self, width = 500, height = 350)
        canvas["bg"] = "blue"
        canvas.pack()
  #画直线
        line = canvas.create_line(lineposition)
        #画矩形
        rect = canvas.create_rectangle(rectposition)
        #画圆形
        oval = canvas.create_oval(ovalposition)
        #画四分一圆形
        arc = canvas.create_arc(arcposition)
        #画多边形
        coor1 = canvas.create_polygon(coorposition)
        coor2 = canvas.create_polygon(200,200,400,200,300,300)
  #插入图画
        global photo
        photo = PhotoImage(file="photo/pngphoto/小黄人.png")
        canvas.create_image(380,250,image=photo)
Clichong = Tk()
Clichong.geometry("600x400+100+200")
Clichong.title("GUI设计测试")
app = Application(master=Clichong)
app.mainloop()

image.png

image.png


练习2:练习三个布局管理器


tkinter 提供了三种管理器:pack、grid、place。


1.grid 布局管理器

grid 表格布局,采用表格结构组织组件。子组件的位置由行和列的单元格来确定,并且可以跨行和跨列,从而实现复杂的布局。

image.png

测试1:写一个简单的登录界面

#使用grid布局
from tkinter import *
from tkinter import messagebox
class Application(Frame):
    def __init__(self,master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.Mytest()
    def Mytest(self):
        lb1 = Label(self,text="用户名:")
        lb1.grid(row=0,column=0)
        et1 = Entry(self,show="*")
        et1.grid(row=0,column=1)
        bt1 = Button(self,width=5,height=1,text="登录")
        bt1.grid(row=1,column=1,sticky="es")    # sticky控制好方位
Clichong = Tk()
Clichong.geometry("600x400+100+200")
Clichong.title("GUI设计测试")
app = Application(master=Clichong)
app.mainloop()

image.png


测试2:写一个计算器的简单布局

#使用grid布局
from tkinter import *
from tkinter import messagebox
#定义好按钮上面text内容
btnumber = (("MC","M+","M-","MR"),\
            ("C","±","+","*"),\
            (7,8,9,"-"),\
            (4,5,6,"+"),\
            (1,2,3,"="),\
            (0,"."))
class Application(Frame):
    def __init__(self,master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.Mytest()
    def Mytest(self):
        Entry(self).grid(row=0,column=0,columnspan=4,pady=10,sticky="nsew")
        print((list(enumerate(btnumber))))
        for rows,datainfo in enumerate(btnumber):
            for nums,singledatainfo in enumerate(datainfo):
                #对于等号与点号需要做特殊在处理
                if singledatainfo == "=":
                    Button(self,text=singledatainfo).grid(row=rows+1,column=nums,rowspan=2,sticky="nsew")
                elif singledatainfo == ".":
                    Button(self, text=singledatainfo).grid(row=rows + 1, column=nums, columnspan=2, sticky="nsew")
                else:
                    Button(self,text=singledatainfo).grid(row=rows+1,column=nums,sticky="nsew")
Clichong = Tk()
Clichong.geometry("140x220+100+200")
Clichong.title("GUI设计测试")
app = Application(master=Clichong)
app.mainloop()

image.png


2.pack 布局管理器

pack 按照组件的创建顺序将子组件添加到父组件中,按照垂直或者水平的方向自然排布。如果不指定任何选项,默认在父组件中自顶向下垂直添加组件。

image.png

测试:制作钢琴按键布局

#使用grid布局
from tkinter import *
from tkinter import messagebox
btstring = ("伴奏1","伴奏2","伴奏3","旋律1","旋律2")
Clichong = Tk()
Clichong.geometry("500x240+300+300")
Clichong.title("钢琴键")
# 思路,这里我们需要定义两个pack,一个放按钮,另外一个放置钢琴键。而这两个pack都在Clichong这个背景上面
# 放置按钮
pianobt = Frame(Clichong)
pianobt.pack(pady=15)
for bttext in btstring:
    Button(pianobt,text=bttext,width=5,height=1).pack(side="left",padx=10)
# 放置钢琴键
pianoky = Frame(Clichong)
pianoky.pack(pady=10)
for btpiano in range(0,11):
    Button(pianoky,width=5,height=10,bg="black" if btpiano%2==0 else "white").pack(side="left")
# 一定要设置循环,不然无法实现
Clichong.mainloop()

image.png


3.place布局管理器

place 布局管理器可以通过坐标精确控制组件的位置,适用于一些布局更加灵活的场景。

image.png


测试1:简单测试place组件

# 测试place布局
from tkinter import *
Clichong = Tk()
Clichong.geometry("400x200+400+300")
Clichong["bg"] = "blue"
# 放置一个黄色的方框
fm1 = Frame(Clichong,bg="yellow",width=100,height=100)
fm1.place(x=30,y=35)
# 放置一个绿色的方框
fm2 = Frame(Clichong,bg="green",width=100,height=100)
fm2.place(x=270,y=35)
# 放置三个按钮
Button(fm1,text="bt1",bg="green").place(relx=0.3,rely=0.7)
Button(fm2,text="bt2",bg="yellow").place(relx=0.7,rely=0.3)
Button(Clichong,text="bt",bg="white").place(width=60,height=30,relx=0.45,rely=0.4)
Clichong.mainloop()

image.png


测试2:扑克牌游戏出牌操作设置

# 扑克出牌
from tkinter import *
Clichong = Tk()
Clichong.geometry("600x400+300+300")
# 图像处理
myphoto = [PhotoImage(file="photo/puke/puke"+str(pukenumber+1)+".gif")for pukenumber in range(10)]
mypuke = [Label(Clichong,image=myphoto[i])for i in range(10)]
# 放置扑克牌
for i in range(10):
    mypuke[i].place(x=50+40*i,y=130)
# 触发事件的操作函数
def pukeoutfunction(event):
    print(event.widget.winfo_geometry())    # 打印geometry信息
    print(event.widget.winfo_y())           # 打印y坐标
    # 如果y坐标在底下,则出牌
    if event.widget.winfo_y() == 130:
        event.widget.place(y=80)
    # 如果y坐标已出,则收牌
    else:
        event.widget.place(y=130)
# 对label事件点击的绑定出牌操作
mypuke[1].bind_class("Label","<Button-1>",pukeoutfunction)
Clichong.mainloop()


初始状态

image.png

点击任意一张牌

image.png

再次点击则收回来

image.png


练习3:鼠标事件和键盘事件用法


 一个 GUI 应用整个生命周期都处在一个消息循环 (event loop) 中。它等待事件的发生,并作出相应的处理。Tkinter 提供了用以处理相关事件的机制. 处理函数可被绑定给各个控件的各种事件。widget.bind(event, handler)如果相关事件发生, handler 函数会被触发, 事件对象event 会传递给 handler 函数.


鼠标和键盘事件:

image.png

event 对象常用属性:

image.png

from tkinter import *
Clichong = Tk()
Clichong.geometry("600x400+300+300")
bt1 = Button(Clichong,bg="blue",text="bt1").place(x=50,y=120,width=50,height=20)
#lb1 = Label(Clichong,bg="pink").place(x=300,y=100,width=100,height=30)
c1 = Canvas(Clichong,width=50,height=50,bg="pink")
c1.place(x=50,y=20)
c2 = Canvas(Clichong,width=200,height=200,bg="orange")
c2.place(x=120,y=20)
# 打印相关信息,测试event 对象常用属性
def mouseTest(event):
    print("鼠标左键单击位置(相对于父容器):{0},{1}".format(event.x,event.y))
    print("鼠标左键单击位置(相对于屏幕):{0},{1}".format(event.x_root,event.y_root))
    print("事件绑定的组件:{0}".format(event.widget))
    print("event.type:{0}".format(event.type))
    print("event.width:{0},event.height:{1}".format(event.width,event.height))
penfont=2         # 设置画笔的粗细
def mouseDrag(event):
    # 不断的画圆,看上去像是画笔,但是event.x+var加大了就知道是个圆
    c2.create_oval(event.x, event.y, event.x+penfont, event.y+penfont)
# 键盘任意按键触发事件,打印按下的键盘键,测试event 对象常用属性
def keyboardTest(event):
    print("按键keycode:{0}\n按键char:{1}\n按键keysym:{2}\n".format(event.keycode,event.char,event.keysym))
# 按键A/a测试
def keyboardTest_A(event):
    print("your press A/a")
def keyboardTest_DoubleA(event):
    print("your press A/a twice times")
def keyboardTest_CtrlA(event):
    print("your press ctrl+A/a")
# 进入c2组件区域测试
def enterTest(event):
    print("event_x:{0},event_y:{1}".format(event.x_root,event.y_root))
# 点击触发事件
c1.bind("<Button-1>",mouseTest)
# 拖动触发事件
c2.bind("<B1-Motion>",mouseDrag)
# 键盘触发事件,一个个测试
# 一般来说,键盘的按键都是绑定主界面
Clichong.bind("<KeyPress>",keyboardTest)
Clichong.bind("<KeyPress-a>",keyboardTest_A)
Clichong.bind("<KeyPress-A>",keyboardTest_A)
Clichong.bind("<Double-KeyPress-a>",keyboardTest_DoubleA)
Clichong.bind("<Control-KeyPress-a>",keyboardTest_CtrlA)
# 鼠标指针进入某一组件区域测试
c2.bind("<Enter>",enterTest)
Clichong.mainloop()

image.png


练习4:lambda 表达式实现传参


lambda 表达式定义的是一个匿名函数,只适合简单输入参数,简单计算返回结果,不适合功能复杂情况。lambda 定义的匿名函数也有输入、也有输出,只是没有名字。

语法格式如下:lambda 参数值列表:表达式


  • 参数值列表即为输入。
  • 表达式计算的结构即为输出。

image.png

from tkinter import *
Clichong = Tk()
Clichong.geometry("270x100")
def MyTest(str1,str2):
    print(str1,"make friend with",str2)
# 使用lambda关键字可以实现传递多个参数操作
Button(Clichong,text="bt1",command=lambda :MyTest("Clichong","Lawrence")).pack()
t1 = lambda x,y:x**y
t2 = lambda :MyTest("A","B")
print("t1(2,3):",t1(2,3),"\n","MyTest(A,B)",t2)
Clichong.mainloop()

image.png


练习5:多种事件绑定方式


  • 组件对象的绑定
  1. 通过 command 属性绑定(适合简单不需获取 event 对象)

Button(root,text=”登录”,command=login)

  1. 通过 bind()方法绑定(适合需要获取 event 对象)


c1 = Canvas(); c1.bind(“”,drawLine)

ps:

command方式绑定,不能直接获取event 对象" "

bind方式绑定,可以获取 event 对象" "


  • 组件类的绑定

调用对象的 bind_class 函数,将该组件类所有的组件绑定事件:w.bind_class(“Widget”,”event”,eventhanler)

比如:btn01.bind_class(“Button”,””,func)


参考前面扑克出牌的小例子:

from tkinter import *
Clichong = Tk()
Clichong.geometry("600x400+300+300")
myphoto = [PhotoImage(file="photo/puke/puke"+str(pukenumber+1)+".gif")for pukenumber in range(10)]
mypuke = [Label(Clichong,image=myphoto[i])for i in range(10)]
for i in range(10):
    mypuke[i].place(x=50+40*i,y=130)
def pukeoutfunction(event):
    print(event.widget.winfo_geometry())    
    print(event.widget.winfo_y())         
    if event.widget.winfo_y() == 130:
        event.widget.place(y=80)
    else:
        event.widget.place(y=130)
# 对label事件点击的绑定出牌操作,bind_class直接绑定label这整一类
mypuke[1].bind_class("Label","<Button-1>",pukeoutfunction)
Clichong.mainloop()


练习6:OptionMenu 选择项


介绍:

class OptionMenu(Menubutton):
    """OptionMenu which allows the user to select a value from a menu."""
    def __init__(self, master, variable, value, *values, **kwargs):
        """Construct an optionmenu widget with the parent MASTER, with
        the resource textvariable set to VARIABLE, the initially selected
        value VALUE, the other menu values VALUES and an additional
        keyword argument command."""
        kw = {"borderwidth": 2, "textvariable": variable,
              "indicatoron": 1, "relief": RAISED, "anchor": "c",
              "highlightthickness": 2}


测试:

from tkinter import *
Clichong = Tk()
Clichong.geometry("400x300+300+300")
# 设置变量,方便回去选择项获取的内容,与其他空间类型操作
opmfirstvar = StringVar()
opmfirstvar.set("蔬菜面")
opm1 = OptionMenu(Clichong,opmfirstvar,"蔬菜面","兰州拉面","豚骨拉面","地狱拉面")
opm1.place(x=50,y=30,width=120,height=40)
def ShowLabel():
    print(opmfirstvar.get())
bt1 = Button(Clichong,width=3,command=ShowLabel).place(x=50,y=100)
Clichong.mainloop()

image.png


练习7:Scale移动滑块


介绍:

class Scale(Widget):
    """Scale widget which can display a numerical scale."""
    def __init__(self, master=None, cnf={}, **kw):
        """Construct a scale widget with the parent MASTER.
        Valid resource names: activebackground, background, bigincrement, bd,
        bg, borderwidth, command, cursor, digits, fg, font, foreground, from,
        highlightbackground, highlightcolor, highlightthickness, label,
        length, orient, relief, repeatdelay, repeatinterval, resolution,
        showvalue, sliderlength, sliderrelief, state, takefocus,
        tickinterval, to, troughcolor, variable, width."""
        Widget.__init__(self, master, 'scale', cnf, kw)


测试:

from tkinter import *
Clichong = Tk()
Clichong.geometry("400x300")
lb1 = Label(Clichong,text="Clichong",width=10,height=2,font=("宋体",20))
lb1.pack()
# label不支持以下的操作:TypeError: 'NoneType' object does not support item assignment
# lb1["font"] = ("宋体",20)
# 通过函数传递当前值
def mytest(value):
    print(value)
    newFont = ("黑体", value)
    lb1.config(font=newFont)
sc1 = Scale(Clichong,from_=10,to=100,length=300,width=30,command=mytest)
# 组件Scale可以支持如下操作
sc1["orient"] = HORIZONTAL
sc1.pack()
Clichong.mainloop()


未调整前:

image.png

调整之后:

image.png


练习8:字体动态调整的方法测试


基于以上字体调整失败,此部分再次进行调试

from tkinter import *
Clichong = Tk()
Clichong.geometry("400x300")
lb1 = Label(Clichong,text="Clichong",width=10,height=2,font=("宋体",20))
lb1.pack()
# 经测试,以下两种动态调整字体的方法都可以
def func1():
    lb1["font"] = ("黑体", 40)
def func2():
    lb1.config(font=("黑体",30))
bt1 = Button(Clichong,command=func1).pack(side="left")
bt2 = Button(Clichong,command=func2).pack(side="left")
Clichong.mainloop()


按钮1:

image.png

按钮2:

image.png


练习9:颜色选择框基本用法


颜色选择框可以帮助我们设置背景色、前景色、画笔颜色、字体颜色等等。

# 颜色选择框
from tkinter import *
from tkinter.colorchooser import *
Clichong = Tk()
Clichong.geometry("400x300")
def mytest():
    # 设置初始选择的颜色是绿色,颜色框标题是"My color"
    cr = askcolor(color="green",title="My color")
    # 得出的结果是((128.5, 255.99609375, 255.99609375), '#80ffff')
    print(cr)
    # 设置背景颜色,以下两种方法均可
    Clichong["bg"] = cr[1]
    Clichong.config(bg = cr[1])
Button(Clichong,text="选择背景色",command=mytest).pack()
Clichong.mainloop()


调出颜色选择框:

image.png

image.png

点击确定更换背景色

image.png


练习10:文件对话框基本用法


文件对话框帮助我们实现可视化的操作目录、操作文件。最后,将文件、目录的信息传入到程序中。文件对话框包含如下一些常用函数:

image.png

image.png

命名参数 options 的常见值如下:

image.png


测试1:返回选择好的文件名

# 文件选择框
from tkinter import *
from  tkinter.filedialog import *
Clichong = Tk()
Clichong.geometry("400x300")
def mytest():
    askfile = askopenfilename(title="My File")
    lb1["text"] = askfile
Button(Clichong,command=mytest).pack()
lb1 = Label(Clichong,width=40,height=3,bg="green")
lb1.pack()
Clichong.mainloop()


点击按钮弹出文件选择框:

image.png

选择好后在label显示文件名

image.png


测试2:打开指定 txt 文件,并读出文件内容到窗口

# 文件选择框
from tkinter import *
from  tkinter.filedialog import *
Clichong = Tk()
Clichong.geometry("400x300")
def mytest1():
    askfile = askopenfilename(title="My File")
    lb1["text"] = askfile
def mytest2():
    with askopenfile(title="File") as fd:
        lb2.config(text=fd.read())
Button(Clichong,command=mytest1).pack(side="left")
Button(Clichong,command=mytest2).pack(side="left")
lb1 = Label(Clichong,width=40,height=3,bg="pink")
lb1.pack()
lb2 = Label(Clichong,width=40,height=10,bg="blue")
lb2.pack()
Clichong.mainloop()


测试按钮1:

image.png

输出文件路劲

image.png

测试按钮2:

image.png

输出文件内容

image.png


练习11:简单输入对话框


simpledialog(简单对话框)包含如下常用函数:

image.png

参数中,title 表示窗口标题;prompt 是提示信息;命名参数kw 为各种选项:initialvalue(初始值)、minvalue(最小值)、maxvalue(最大值)。

# 颜色选择框
from tkinter import *
from tkinter.simpledialog import *
Clichong = Tk()
Clichong.geometry("400x300")
lb1 = Label(Clichong,width=40,height=3,bg= "green")
lb1.pack()
# Button(Clichong,text="选择背景色",command=mytest).pack()
getstr = askinteger(title="about age",prompt="input your age",initialvalue=0,minvalue=0,maxvalue=100)
lb1.config(text=getstr)
Clichong.mainloop()

image.png

超过100会警告:

image.png

image.png


练习12:通用消息框


messagebox(通用消息框)用于和用户简单的交互,用户点击确定、取消。如下列出了 messagebox 的常见函数:

image.png

测试代码:

from tkinter import *
from tkinter.messagebox import *
Clichong = Tk()
Clichong.geometry("400x300")
# box1 = askokcancel(Clichong,"你是男的女的")
# box2 = askquestion(title="问题1",message="你是男的女的")
# box3 = askyesnocancel(title="问题1",message="你是男的女的")
# box4 = showinfo(title="问题1",message="你是男的女的")
box5 = showerror(title="问题1",message="你是男的女的")
Clichong.mainloop()

image.png


  • ttk 子模块控件

我们再前面学的组件是 tkinter 模块下的组件,整体风格较老较丑。为了弥补这点不足,推出了 ttk 组件。ttk 组件更加美观、功能更加强大。使用 Combobox 替代了原来的Listbox 、 新 增 了 LabeledScale( 带 标 签 的 Scale) 、Notebook(多文档窗口)、Progressbar(进度条)、Treeview(数)等组件。

使用 ttk 组件与使用普通的 Tkinter 组件并没有多大的

区别,只要导入 ttk 模块即可。


目录
相关文章
|
10月前
|
设计模式 SQL 人工智能
Python设计模式:从代码复用到系统架构的实践指南
本文以Python为实现语言,深入解析23种经典设计模式的核心思想与实战技巧。通过真实项目案例,展示设计模式在软件开发中的结构化思维价值,涵盖创建型、结构型、行为型三大类别,并结合Python动态语言特性,探讨模式的最佳应用场景与实现方式,帮助开发者写出更清晰、易维护的高质量代码。
563 1
|
10月前
|
设计模式 人工智能 算法
Python设计模式:从代码复用到系统架构的实践指南
本文探讨了电商系统中因支付方式扩展导致代码臃肿的问题,引出设计模式作为解决方案。通过工厂模式、策略模式、单例模式等经典设计,实现代码解耦与系统扩展性提升。结合Python语言特性,展示了模块化、装饰器、适配器等模式的实战应用,并延伸至AI时代的设计创新,帮助开发者构建高内聚、低耦合、易维护的软件系统。
472 0
|
API C++ 开发者
PySide vs PyQt:Python GUI开发史诗级对决,谁才是王者?
PySide 和 PyQt 是 Python GUI 开发领域的两大利器,各有特色。PySide 采用 LGPL 协议,更灵活;PyQt 默认 GPL,商业使用需授权。两者背后团队实力雄厚,PySide 得到 Qt 官方支持,PyQt 由 Riverbank Computing 打造。API 设计上,PySide 简洁直观,贴近原生 Qt;PyQt 增加 Pythonic 接口,操作更高效。性能方面,两者表现优异,适合不同需求的项目开发。选择时可根据项目特点与开源要求决定。
1280 20
|
测试技术 开发者 Python
Python(GUI)之活动积分记录表
本文介绍了一套使用Python的Tkinter库构建的学生活动积分记录系统。该系统允许教师选择班级和学生,输入加分分数及原因,并将数据保存至文件,旨在简化学生积分管理流程,提升教学效率。
538 130
|
10月前
|
设计模式 人工智能 算法
python 设计模式
工厂模式是一种创建型设计模式,通过定义创建对象的接口,将实例化延迟到子类,实现对象创建与使用的分离。它包括简单工厂模式、工厂方法模式和抽象工厂模式,适用于不同复杂度的对象创建场景,提高系统灵活性和可扩展性。
173 4
|
设计模式 机器学习/深度学习 前端开发
Python 高级编程与实战:深入理解设计模式与软件架构
本文深入探讨了Python中的设计模式与软件架构,涵盖单例、工厂、观察者模式及MVC、微服务架构,并通过实战项目如插件系统和Web应用帮助读者掌握这些技术。文章提供了代码示例,便于理解和实践。最后推荐了进一步学习的资源,助力提升Python编程技能。
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
设计模式 开发者 Python
Python编程中的设计模式应用与实践感悟####
本文作为一篇技术性文章,旨在深入探讨Python编程中设计模式的应用价值与实践心得。在快速迭代的软件开发领域,设计模式如同导航灯塔,指引开发者构建高效、可维护的软件架构。本文将通过具体案例,展现设计模式如何在实际项目中解决复杂问题,提升代码质量,并分享个人在实践过程中的体会与感悟。 ####
|
设计模式 算法 搜索推荐
Python编程中的设计模式:优雅解决复杂问题的钥匙####
本文将探讨Python编程中几种核心设计模式的应用实例与优势,不涉及具体代码示例,而是聚焦于每种模式背后的设计理念、适用场景及其如何促进代码的可维护性和扩展性。通过理解这些设计模式,开发者可以更加高效地构建软件系统,实现代码复用,提升项目质量。 ####
|
数据可视化 开发者 Python
Python GUI开发:Tkinter与PyQt的实战应用与对比分析
【10月更文挑战第26天】本文介绍了Python中两种常用的GUI工具包——Tkinter和PyQt。Tkinter内置于Python标准库,适合初学者快速上手,提供基本的GUI组件和方法。PyQt基于Qt库,功能强大且灵活,适用于创建复杂的GUI应用程序。通过实战示例和对比分析,帮助开发者选择合适的工具包以满足项目需求。
1217 7

推荐镜像

更多