Python small exercise-GUI design

Exercise 1: Use of canvas

Test to draw straight lines, circles, semicircles, triangles and other images, or insert pictures


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()

Insert picture description here
Insert picture description here

Exercise 2: Practice three layout managers

tkinter provides three types of managers: pack, grid, and place.

1.grid layout manager

grid table layout, using table structure to organize components. The position of sub-components is determined by row and column cells, and can span rows and columns to achieve complex layouts.
Insert picture description here
Test 1: Write a simple login interface

#使用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()

Insert picture description here
Test 2: Write a simple layout of a calculator

#使用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()

Insert picture description here

2.pack layout manager

Pack adds the child components to the parent component in the order of component creation, and arranges them naturally in a vertical or horizontal direction. If you do not specify any options, the default is to add components vertically from top to bottom in the parent component.
Insert picture description here
Test: Making piano key layout

#使用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()

Insert picture description here

3.place layout manager

The place layout manager can precisely control the position of components through coordinates, which is suitable for some scenarios with more flexible layouts.
Insert picture description here
Insert picture description here
Test 1: Simply test the place component

# 测试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()

Insert picture description here
Test 2: Playing card game operation settings

# 扑克出牌

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()

Initial state
Insert picture description here
Click any card,
Insert picture description here
click again to take it back
Insert picture description here

Exercise 3: Mouse event and keyboard event usage

  The entire life cycle of a GUI application is in an event loop. It waits for the occurrence of the event and handles it accordingly. Tkinter provides a mechanism to handle related events. Handle functions can be bound to various events of each control. widget.bind(event, handler) If a related event occurs, the handler function will be triggered, and the event object event will be passed to the handler function.

Mouse and keyboard events:
Insert picture description here
Common attributes of event objects:
Insert picture description here


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()

Insert picture description here

Exercise 4: lambda expressions to pass parameters

The lambda expression defines an anonymous function, which is only suitable for simple input parameters and simple calculations to return results, which is not suitable for complex functions. The anonymous function defined by lambda also has input and output, but it has no name.
The syntax format is as follows: lambda parameter value list: expression

  • The parameter value list is the input.
  • The structure of the expression calculation is the output.
    Insert picture description here

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()

Insert picture description here

Exercise 5: Multiple event binding methods
  • Binding of component objects
  1. Binding through the command attribute (suitable for simple and no need to obtain the event object)
    Button(root,text=”login”,command=login)
  2. Binding through the bind() method (suitable for obtaining event objects)
    c1 = Canvas(); c1.bind("",drawLine)

ps:
Binding in command mode, you cannot directly obtain the event object" "
Binding in bind mode, you can obtain the event object" "

  • Binding of component classes

Call the bind_class function of the object to bind all the components of the component class to events: w.bind_class("Widget","event",eventhanler) For
example: btn01.bind_class("Button","",func)

Refer to the previous small example of playing cards:

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()
Exercise 6: OptionMenu selection items

Introduction:

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}

test:


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()

Insert picture description here

Exercise 7: Scale moving the slider

Introduction:

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)

test:


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()

Before
Insert picture description here
adjustment: After adjustment:
Insert picture description here

Exercise 8: Method test of dynamic font adjustment

Based on the failure of the above font adjustment, this part will be debugged again


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()

Button 1:
Insert picture description here
Button 2:
Insert picture description here

Exercise 9: Basic usage of color selection box

The color selection box can help us set the background color, foreground color, pen color, font color and so on.

# 颜色选择框

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()

Bring up the color selection box:
Insert picture description here
click OK to change the background color
Insert picture description here

Exercise 10: Basic usage of the file dialog

The file dialog box helps us realize the visual operation catalog and operation files. Finally, pass the file and directory information into the program. The file dialog contains the following commonly used functions:
Insert picture description here
Insert picture description here
The common values ​​of the named parameter options are as follows:
Insert picture description here

Test 1: Return the selected file name
# 文件选择框

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()

Click the button to pop up the file selection box: After
Insert picture description here
selection, the file name will be displayed on the label
Insert picture description here

Test 2: Open the specified txt file and read the content of the file to the window
# 文件选择框

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()

Test button 1:
Insert picture description here
Output file path King
Insert picture description here
Test button 2:
Insert picture description here
Output file content
Insert picture description here

Exercise 11: Simple input dialog

simpledialog (simple dialog box) contains the following commonly used functions: among the
Insert picture description here
parameters, title represents the window title; prompt is the prompt message; the named parameter kw is various options: initialvalue (initial value), minvalue (minimum value), maxvalue (maximum value).

# 颜色选择框

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()

Insert picture description here
More than 100 will warn:
Insert picture description here
Insert picture description here

Exercise 12: General message box

The messagebox (general message box) is used for simple interaction with the user. The user clicks OK and Cancel. The common functions of messagebox are listed as follows:
Insert picture description here
test code:


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()

Insert picture description here

  • ttk submodule control

The components we learned earlier are the components under the tkinter module, and the overall style is older and uglier. In order to make up for this shortcoming, the ttk component was introduced. ttk components are more beautiful and more powerful. Use Combobox to replace the original Listbox, and add LabeledScale (labeled Scale), Notebook (multi-document window), Progressbar (progress bar), Treeview (number) and other components.
There is not much
difference between using ttk components and ordinary Tkinter components , as long as you import the ttk module.

Guess you like

Origin blog.csdn.net/weixin_44751294/article/details/110236353