python-使用Tkinter进行GUI程序设计(参考课本实现的案例中介绍用处)

Turtle不能创建图形用户界面
类定义中 def drive(selef,distance) 方法中self参数得问题,例如:xxx takes 2 positional arguments but 3 were given

1 简单案例:按钮

from tkinter import *
window=Tk()
label=Label(window,text="welcome to python")
button=Button(window,text="click me")
label.pack()
button.pack()#打包
window.mainloop()#创建循环,直到关闭主窗口

在这里插入图片描述

2 按钮一些功能

关于按钮更多函数

from tkinter import *
#回调函数,或处理器
def processOn():
    print("On button is clicked")
def processCancel():
    print("Cancel button is clicked")
window=Tk()

# command
# 按钮关联的函数,当按钮被点击时,执行该函数
# activebackground
# 当鼠标放上去时,按钮的背景色
# activeforeground
# 当鼠标放上去时,按钮的前景色
# bg
# 按钮的背景色
# fg
# 按钮的前景色(按钮文本的颜色)

btOk=Button(window,text="On",fg="green",command=processOn(),height=10,width="10",bg="black",activebackground="red")
btCancel=Button(window,text="Cancel",fg="yellow",command=processCancel(),height=10,width="10",bg="black",activeforeground="red")
btOk.pack()
btCancel.pack()
window.mainloop()#创建循环,直到关闭主窗口

在这里插入图片描述

3 小构件类

可以window.title(" ")
在这里插入图片描述在这里插入图片描述

更多
或者查看这个的更多内容
通过 widget[“propertyName”]=newPropertyName来改变属性
在这里插入图片描述

widget["text"]="newText"# 改变控键显示文字
widget["cursor"]="plus"#改变鼠标光标
widget["justify"]=LEFT #改变对齐方式

IntVar ,StringVar,DoubleVar 为 输入域(文本域)输入值的对象类型

3.1 输入输出框

from tkinter import *

class WidgeDemo:
    def __init__(self):
        window = Tk()

        window.title("widgets demo ")

        '''
        add a check button and a radio button to frame1
        '''
        frame1=Frame(window)
        frame1.pack()

        self.v1=IntVar()# 和Checkbutton联系
        cbtBox=Checkbutton(frame1,text="Bold",
                           variable=self.v1,
                           command=self.processCheck)
        self.v2=IntVar()
        rbRed=Radiobutton(frame1,text="Red",bg="red",
                          variable=self.v2,value=1,
                          command=self.processRadiobutton)
        rbYello=Radiobutton(frame1,text="Yellow",bg="yellow",
                            variable=self.v2,value=2,
                            command=self.processRadiobutton)


        # 调整规格
        cbtBox.grid(row=1,column=1)
        rbRed.grid(row=1,column=2)
        rbYello.grid(row=1,column=3)

        '''
        # add a label ,an entry,a button and a message to frame2
        '''
        frame2=Frame(window)
        frame2.pack()
        label=Label(frame2,text="Enter your name")
        self.name=StringVar()   #获取名字变量
        entryName=Entry(frame2,textvariable=self.name)#输入框
        btGetName=Button(frame2,text="Get Name",command=self.processGetNameButton)
        message=Message(frame2,text="It is a widgets demo")

        #调整
        label.grid(row=1,column=1)
        entryName.grid(row=1,column=2)
        btGetName.grid(row=1,column=3)
        message.grid(row=1,column=4)

        #add text
        text=Text(window)
        text.pack()
        text.insert(END ,"Tip\nThe best way to learn Tkinker is to read\n")
        text.insert(END,"我是菜鸟码农,在努力中\n")
        text.insert(END,"中国加油,武汉加油\n")
        window.mainloop()

    def processCheck(self):
        print("Check button is "+("checked " if self.v1.get()== 1 else "unchecked"))
    def processRadiobutton(self):
        print("Red" if self.v2.get()==1 else "Yellow")

    def processGetNameButton(self):
        print("your name is "+self.name.get())


WidgeDemo() #create 对象

在这里插入图片描述
稍微改动后:

  #add text
        self.text=Text(window)
        self.text.pack()
        self.text.insert(END ,"信息如下:\n")
        window.mainloop()

 def processGetNameButton(self):
        print("your name is "+self.name.get())
        self.text.insert(END ,"Your name is "+self.name.get()+"\n")

在这里插入图片描述

3.2 动态改变标签

from tkinter import *

class ChangeLabelDemo:
    def processButton(self):
        self.lbl["text"]=self.msg.get()
    def processRadiobutton(self):
        if self.v1.get()=="R":
            self.lbl["fg"]="red"
        elif self.v1.get()=='Y':
            self.lbl["fg"]="yellow"

    def __init__(self):
        window = Tk()
        window.title("Change Label Demo")

        #add  label to frame
        frame1=Frame(window)
        frame1.pack()
        self.lbl=Label(frame1,text="Python is funny",bg="black",fg="white")
        self.lbl.pack()

        #Add a lable ,entry,button,two radiobutton to frame2
        frame2=Frame(window)
        frame2.pack()
        label=Label(frame2,text="Enter text: ")
        self.msg=StringVar()
        entry=Entry(frame2,textvariable=self.msg)
        btChange=Button(frame2,text="Change text",command=self.processButton)

        self.v1=StringVar()
        rbRed=Radiobutton(frame2,text="Red",
                          bg="red",variable=self.v1,
                          value="R",command=self.processRadiobutton)
        rbYellow=Radiobutton(frame2,text="Yellow",
                             bg="yellow",variable=self.v1,
                             value="Y",command=self.processRadiobutton)


        label.grid(row=1,column=1)
        entry.grid(row=1,column=2)
        btChange.grid(row=1,column=3)
        rbRed.grid(row=1,column=4)
        rbYellow.grid(row=1,column=5)
        window.mainloop()

ChangeLabelDemo()


在这里插入图片描述

4 画布

from tkinter import *

class CanvasDemo:
    def displayRect(self):
        self.canvas.create_rectangle(10,10,190,90,tags="rect")
    def displayOval(self):
        # (x1,y1,x2,y2)
        self.canvas.create_oval(10,10,190,90,fill="red",tags="oval")
    def displayArc(self):#弧线
        '''
            以(x1,y1)(x2,y2)为对角线画个矩形,中间画个椭圆,以start-》extent度数旋转
        '''
        # 默认为 extent=90
        self.canvas.create_arc(10,10,190,90,start=0,extent=45,width=8,fill="red",tags="arc")
    def displayPolygon(self):#多边形  x1,y1,x2,y2
        self.canvas.create_polygon(10,10,190,90,30,90,tags="polygon")
    def displayLine(self):
        self.canvas.create_line(10,90,190,90,fill="yellow",tags="line")
        self.canvas.create_line(10,90,190,10,width=9,arrow="last",activefill="red",tags="line")#鼠标接触就变红色,arrow+create_line画一条有箭头线段
        # arrow参数还可以为first,end ,both
    def displayString(self):
        self.canvas.create_text(60,40,text="This is a string.",font="Times 10 bold underline",tags="string")
    def clearCanvas(self):
        self.canvas.delete("rect","oval","arc","polygon","line","string")

    def __init__(self):
        window = Tk()
        #create a window 200*100(单位是象素)横轴为x轴,竖轴为y轴
        window.title("Canvas Demo")

        self.canvas=Canvas(window,width=200,height=100,bg="white")
        self.canvas.pack()

         # place buttons in frame
        frame=Frame(window)
        frame.pack()

        btRectangle=Button(frame,text="Rectangle",command=self.displayRect)
        btOval=Button(frame,text="Oval",command=self.displayOval)
        btArc=Button(frame,text="Arc",command=self.displayArc)
        btPolygon=Button(frame,text="Polygon",command=self.displayPolygon)
        btLine=Button(frame,text="Line",command=self.displayLine)
        btString=Button(frame,text="String",command=self.displayString)
        btClear=Button(frame,text="Clear",command=self.clearCanvas)

        btRectangle.grid(row=1,column=1)
        btOval.grid(row=1,column=2)
        btArc.grid(row=1,column=3)
        btPolygon.grid(row=1,column=4)
        btLine.grid(row=1,column=5)
        btString.grid(row=1,column=6)
        btClear.grid(row=1,column=7)

        window.mainloop()

CanvasDemo()


在这里插入图片描述

5 几何管理器

(Python GUI)对pack(几何管理器)与grid(网格管理器)的理解

5.1 网格管理器

from tkinter import *

class GridManangerDemo:

    def __init__(self):
        window = Tk()
        window.title("Grid Manager Demo")

        message=Message(window,text="Enter your firstName and lastName")
        message.grid(row=1,column=1,rowspan=3,columnspan=2)#拓展为32Label(window,text="First Name").grid(row=1,column=3)
        Entry(window).grid(row=1,column=4,padx=1,pady=1)

        # padx , pady :填充单元格中水平方向和竖直方向上的可选空间
        # ipadx是每个widget的内部间隔
        # padx 是每个widget的外部间隔

        Label(window,text="Last Name").grid(row=2,column=3)
        Entry(window).grid(row=2,column=4)

        Button(window,text="Get Name").grid(row=3,column=4,padx=5,pady=5,sticky=E)
        #sticky表示按钮位置方向,东西南北,EWSN,NW,NE,SW,SE
        # sticky=E,和Entry对齐

        window.mainloop()

GridManangerDemo()


在这里插入图片描述

5.2 包管理器

from tkinter import *

class PackManagerDemo:

    def __init__(self):
        window = Tk()
        window.title("PackManagerDemo")
        Label(window,text="Green",bg="green").pack(side =RIGHT)
        Label(window,text="Blue",bg="blue").pack(side=LEFT,fill=BOTH,expand=1)
        Label(window,text="Red",bg="red").pack(side=BOTTOM,fill=BOTH)
        # fill=BOTH,X,Y :填充2个方向或水平或竖直方向的空间
        # expand分配额外的空间给小构件开给你
        # side=LEFT,RIGHT,TOP,BOTTOM,默认为TOP
        window.mainloop()

PackManagerDemo()


在这里插入图片描述

5.3 位置管理器

from tkinter import *

class PlaceManagerDemo:

    def __init__(self):
        window = Tk()
        window.title("Place ManagerDemo")

        Label(window,text="Blue",bg="Blue").place(x=20,y=30)
        Label(window,text="Red",bg="red").place(x=50,y=50)
        Label(window,text="Green",bg="Green").place(x=80,y=70)

        window.mainloop()

PlaceManagerDemo()

在这里插入图片描述
由于不兼容因素,避免使用位置管理器

5.4 实例:贷款计算器

from tkinter import *

class LoanCalculator:

    def __init__(self):
        window = Tk()
        window.title("Loan Calculator")
        Label(window,text="Annual Interest Rate").grid(row=1,column=1,sticky=W)
        Label(window,text="Number of Years").grid(row=2,column=1,sticky=W)
        Label(window,text="Loan Amount").grid(row=3,column=1,sticky=W)
        Label(window,text="Monthly Payment").grid(row=4,column=1,sticky=W)
        Label(window,text="Total Payment").grid(row=5,column=1,sticky=W)

        self.annualInterestRate=StringVar()
        Entry(window,textvariable=self.annualInterestRate,
              justify=RIGHT).grid(row=1,column=2)
        

        self.numberOfYears=StringVar()
        Entry(window,textvariable=self.numberOfYears,
              justify=RIGHT).grid(row=2,column=2)

        self.loanAmount=StringVar()
        Entry(window,textvariable=self.loanAmount,
              justify=RIGHT).grid(row=3,column=2)

        self.monthlyPaymentVar=StringVar()
        lblMonthlyPayment=Label(window,textvariable=self.monthlyPaymentVar).grid(row=4,column=2,sticky=E)

        self.totalPaymentVar=StringVar()
        lblTotalPayment=Label(window,textvariable=self.totalPaymentVar).grid(row=5,column=2,sticky=E)

        btComputerPayment=Button(window,text="Computer Payment",command=self.computePayment).grid(row=6,column=2,sticky=E)

        window.mainloop()

    def  computePayment(self):
        monthlyPayment=self.getMonthlyPayment(
            float(self.loanAmount.get()),
            float(self.annualInterestRate.get())/1200,
            int(self.numberOfYears.get()))

        self.monthlyPaymentVar.set(format(monthlyPayment,"10.2f"))

        totalPayment=float(self.monthlyPaymentVar.get()) * 12 * int(self.numberOfYears.get())
        self.totalPaymentVar.set(format(totalPayment,"10.2f"))


    def getMonthlyPayment(self,loanAmount,monthlyInterestRate,numberOfYears):
        monthlyPayment=monthlyInterestRate*loanAmount/(1-1/(1+monthlyInterestRate)**(numberOfYears*12))
        return monthlyPayment




LoanCalculator()


在这里插入图片描述
总结:
包管理器(pack())把小构件一个挨着一个放在一起或一个在另一个的顶部
网格管理器(grid())放在网格中
位置管理器放在绝对位置

6.1 显示图像

from tkinter import *

from PIL import ImageTk

class ImageDemo:

    def __init__(self):
        window = Tk()
        window.title("ImageDemo")
        # tkinter中PhotoImage只能打开gif文件,还不是仅仅改个后缀就完事的那种。而要打开的是一个.jpg文件。
        # 所以改用了ImageTk.PhotoImage
        #create Image objects
        firstImage=ImageTk.PhotoImage(file = "C:/Users/Lenovo/Desktop/1.jpg")
        secondImage=ImageTk.PhotoImage(file="C:/Users/Lenovo/Desktop/2.jpg")
        smileImage=ImageTk.PhotoImage(file="C:/Users/Lenovo/Desktop/3.gif")
        dragonImage=ImageTk.PhotoImage(file="C:/Users/Lenovo/Desktop/4.gif")
        circleImage=ImageTk.PhotoImage(file="C:/Users/Lenovo/Desktop/circle.gif")


        # frame to contain label and canvas
        frame1=Frame(window)
        frame1.pack()
        Label(frame1,image=firstImage).pack(side=LEFT)
        canvas=Canvas(frame1)
        canvas.create_image(90,50,image=secondImage)
        canvas["width"]=200
        canvas["height"]=100
        canvas.pack(side=LEFT)

        frame2=Frame(window)
        frame2.pack()
        Button(frame2,image=smileImage).pack(side=LEFT)
        Radiobutton(frame2,image=dragonImage).pack(side=LEFT)
        Checkbutton(frame2,image=circleImage).pack(side=LEFT)

        window.mainloop()
ImageDemo()


在这里插入图片描述

6.2 自己实现的图片显示和关闭+网上看到的压缩图片算法

from tkinter import *
from PIL import Image, ImageTk
from IPython.terminal.pt_inputhooks import tk


class ImageDemo:
    #对一个pil_image对象进行缩放,让它在一个矩形框内,还能保持比例
    def resize( self,w_box, h_box, pil_image): #参数是:要适应的窗口宽、高、Image.open后的图片
        w, h = pil_image.size #获取图像的原始大小
        f1 = 1.0*w_box/w
        f2 = 1.0*h_box/h
        factor = min([f1, f2])#选择最小的缩小比例,使得图形成比例变小
        width = int(w*factor)
        height = int(h*factor)
        return pil_image.resize((width, height), Image.ANTIALIAS)

    def displayImage(self):

        self.filePath=self.filePathVar.get()
        w_box = 110    # 期望图像显示的大小(窗口大小)
        h_box = 250
        # pil_image =  Image.open(r'C:/Users/Lenovo/Desktop/1.jpg')    #以一个PIL图像对象打开  【调整待转图片格式】
        pil_image = Image.open( self.filePath)    #以一个PIL图像对象打开  【调整待转图片格式】
        pil_image_resized = self.resize( w_box, h_box, pil_image)    #缩放图像让它保持比例,同时限制在一个矩形框范围内  【调用函数,返回整改后的图片】

        self.imageItem = ImageTk.PhotoImage(pil_image_resized)    # 把PIL图像对象转变为Tkinter的PhotoImage对象  【转换格式,方便在窗口展示】

        self.canvas.create_image(w_box,h_box,image=self.imageItem, tags="Image")

    def __init__(self):
        window = Tk()
        window.title("ImageDemo")
        self.canvas = Canvas(window,width=180,height=400)
        self.canvas.pack()
        frame = Frame(window)
        frame.pack()
        self.filePathVar=StringVar()

        Entry(frame,textvariable=self.filePathVar,justify=LEFT,width=40).grid(row=1,column=1)
        btOn = Button(frame, text="显示图片", command=self.displayImage,).grid(row=2, column=1,sticky=W)
        # Python3 tkinter基础 Canvas delete 删除画布中的所有图形
        btDelete = Button(frame, text="关闭图片", command=(lambda x=ALL: self.canvas.delete(x))).grid(row=2, column=2,sticky=E)
        window.mainloop() #创建事件循环直到关闭主窗口

ImageDemo()

# 测试案例:C:/Users/Lenovo/Desktop/1.jpg

在这里插入图片描述

7.1 菜单

from tkinter import *
from PIL import ImageTk
class MenuDemo:
    def add(self):
        self.v3.set( eval(self.v1.get())+eval(self.v2.get())  )
    def subtract(self):
        self.v3.set(eval(self.v1.get())-eval(self.v2.get()) )
    def multiply(self):
        self.v3.set(eval(self.v1.get())*eval(self.v2.get()) )
    def divide(self):
        self.v3.set(eval(self.v1.get())/eval(self.v2.get()) )

    def __init__(self):
        window=Tk()
        window.title("Menu Demo")

        #create a menu bar
        menubar=Menu(window)
        window.config(menu=menubar) # display the menu bar 将菜单栏添加到菜单

        #create a pull-down menu,and add it to the menu bar
        operationMenu =Menu(menubar,tearoff=0) 
        # tearoff=0表示菜单不能移出窗口,不然会移出
        # 设置菜单标签
        menubar.add_cascade(label="Operation",menu=operationMenu)

        operationMenu.add_command(label="Add",command=self.add)
        operationMenu.add_command(label="Subtract",command=self.subtract)
        operationMenu.add_command(label="Multiply",command=self.multiply)
        operationMenu.add_command(label="Divide",command=self.divide)

        # create more pull-down menus
        exitMenu=Menu(window,tearoff=0)
        menubar.add_cascade(label="Exit",menu=exitMenu)
        exitMenu.add_command(label="Quit",command=window.quit)

        # add a tool bar frame0
        frame0=Frame(window)
        frame0.grid(row=1,column=1,sticky=W)

        #create images
        plusImage=ImageTk.PhotoImage(file = "C:/Users/Lenovo/Desktop/plus.png")
        minusImage=ImageTk.PhotoImage(file = "C:/Users/Lenovo/Desktop/minus.png")
        multiplyImage=ImageTk.PhotoImage(file = "C:/Users/Lenovo/Desktop/multiply.png")
        divideImage=ImageTk.PhotoImage(file = "C:/Users/Lenovo/Desktop/divide.png")

        Button(frame0,image=plusImage,command=self.add).grid(row=1,column=1,sticky=W)
        Button(frame0,image=minusImage,command=self.subtract).grid(row=1,column=2)
        Button(frame0,image=multiplyImage,command=self.multiply).grid(row=1,column=3)
        Button(frame0,image=divideImage,command=self.divide).grid(row=1,column=4)

        # add buttons to frame1
        frame1=Frame(window)
        frame1.grid(row=2,column=1,pady=10)  #pady=?

        Label(frame1,text="Number1").pack(side=LEFT)
        self.v1=StringVar()
        Entry(frame1,width=5,textvariable=self.v1,justify=RIGHT).pack(side=LEFT)
        Label(frame1,text="Number2").pack(side=LEFT)
        self.v2=StringVar()
        Entry(frame1,width=5,textvariable=self.v2,justify=RIGHT).pack(side=LEFT)
        Label(frame1,text="Result").pack(side=LEFT)
        self.v3=StringVar()
        Entry(frame1,width=5,textvariable=self.v3,justify=LEFT).pack(side=LEFT)

        # add button to frame2
        frame2=Frame(window)
        frame2.grid(row=3,column=1,pady=10,sticky=E)
        Button(frame2,text="Add",command=self.add).pack(side=LEFT)
        Button(frame2,text="Subtract",command=self.subtract).pack(side=LEFT)
        Button(frame2,text="Multiply",command=self.multiply).pack(side=LEFT)
        Button(frame2,text="Divide",command=self.divide).pack(side=LEFT)

        mainloop()

MenuDemo()

在这里插入图片描述

7.2 弹出菜单

(上下文菜单,没有菜单栏浮现屏幕任何一个地方)

from tkinter import *
from PIL import ImageTk
class MenuDemo:
    
    def add(self):
        self.v3.set( eval(self.v1.get())+eval(self.v2.get())  )
    def subtract(self):
        self.v3.set(eval(self.v1.get())-eval(self.v2.get()) )
    def multiply(self):
        self.v3.set(eval(self.v1.get())*eval(self.v2.get()) )
    def divide(self):
        self.v3.set(eval(self.v1.get())/eval(self.v2.get()) )

    def popup(self,event):
        self.operationMenu.post(event.x_root,event.y_root)
    def popup1(self,event):
        self.exitMenu1.post(event.x_root,event.y_root)
    def __init__(self):
        window=Tk()
        window.title("Menu Demo")

        #create a menu bar
        menubar=Menu(window)
        window.config(menu=menubar) # display the menu bar 将菜单栏添加到菜单

        #create a pull-down menu,and add it to the menu bar

        window.bind("<Button-1>",self.popup)
        self.operationMenu=Menu(window,tearoff=0)
        self.operationMenu.add_command(label="Add",command=self.add)
        self.operationMenu.add_command(label="Subtract",command=self.subtract)
        self.operationMenu.add_command(label="Multiply",command=self.multiply)
        self.operationMenu.add_command(label="Divide",command=self.divide)

        # create more pull-down menus
        exitMenu=Menu(window,tearoff=0)
        menubar.add_cascade(label="Exit",menu=exitMenu)
        exitMenu.add_command(label="Quit",command=window.quit)

        window.bind("<Button-3>",self.popup1)
        self.exitMenu1=Menu(window,tearoff=0)
        self.exitMenu1.add_command(label="Quit",command=window.quit)

        # add a tool bar frame0
        frame0=Frame(window)
        frame0.grid(row=1,column=1,sticky=W)

        #create images
        plusImage=ImageTk.PhotoImage(file = "C:/Users/Lenovo/Desktop/plus.png")
        minusImage=ImageTk.PhotoImage(file = "C:/Users/Lenovo/Desktop/minus.png")
        multiplyImage=ImageTk.PhotoImage(file = "C:/Users/Lenovo/Desktop/multiply.png")
        divideImage=ImageTk.PhotoImage(file = "C:/Users/Lenovo/Desktop/divide.png")

        Button(frame0,image=plusImage,command=self.add).grid(row=1,column=1,sticky=W)
        Button(frame0,image=minusImage,command=self.subtract).grid(row=1,column=2)
        Button(frame0,image=multiplyImage,command=self.multiply).grid(row=1,column=3)
        Button(frame0,image=divideImage,command=self.divide).grid(row=1,column=4)

        # add buttons to frame1
        frame1=Frame(window)
        frame1.grid(row=2,column=1,pady=10)  #pady=?

        Label(frame1,text="Number1").pack(side=LEFT)
        self.v1=StringVar()
        Entry(frame1,width=5,textvariable=self.v1,justify=RIGHT).pack(side=LEFT)
        Label(frame1,text="Number2").pack(side=LEFT)
        self.v2=StringVar()
        Entry(frame1,width=5,textvariable=self.v2,justify=RIGHT).pack(side=LEFT)
        Label(frame1,text="Result").pack(side=LEFT)
        self.v3=StringVar()
        Entry(frame1,width=5,textvariable=self.v3,justify=LEFT).pack(side=LEFT)

        # add button to frame2
        frame2=Frame(window)
        frame2.grid(row=3,column=1,pady=10,sticky=E)
        Button(frame2,text="Add",command=self.add).pack(side=LEFT)
        Button(frame2,text="Subtract",command=self.subtract).pack(side=LEFT)
        Button(frame2,text="Multiply",command=self.multiply).pack(side=LEFT)
        Button(frame2,text="Divide",command=self.divide).pack(side=LEFT)

        mainloop()

MenuDemo()

右击效果右击效果
主要代码是

window.bind("<Button-3>",self.popup1)  
self.exitMenu1=Menu(window,tearoff=0)         
 self.exitMenu1.add_command(label="Quit",command=window.quit)
 def popup1(self,event):
        self.exitMenu1.post(event.x_root,event.y_root)

8 鼠标、按钮事件和绑定

函数详细
事件的描述格式为:<[modifier-]-type[-detail]>

8.1 事件

在这里插入图片描述
当3次单击鼠标i键是发生
在这里插入图片描述在这里插入图片描述

8.2 属性

在这里插入图片描述

8.3 实例1 :按键和鼠标

from tkinter import *
class MouseKeyEventDemo:
    def processMouseEvent(self,event):
        print("clicked at widget's",event.x,event.y)
        print("Position at the screen's ",event.x_root,event.y_root)
        print("which button of mouse is clicked?",event.num)
        print("which widget is operated?",event.widget)

    def processKeyEvent(self,event):
        print("keysym?(键符号--字符)",event.keysym)
        print("char?(字母符号)",event.char)
        print("keycode?(统一码)",event.keycode)
        print("which widget is operated?",event.widget)

    def __init__(self):
        window=Tk()
        window.title("Event Demo")
        canvas=Canvas(window,height=500,width=500)
        canvas.pack()

        #bind with<Button-1> event
        # canvas.bind("<Button-2>",self.processMouseEvent)
        canvas.bind("<B1-Motion>",self.processMouseEvent)
        canvas.bind("<Key>",self.processKeyEvent)
        canvas.focus_set()# 设置焦点,获取鼠标焦点
        window.mainloop()
MouseKeyEventDemo()

移动后:
在这里插入图片描述
按键:
在这里插入图片描述

8.4 圆的半径动态变换

规则: 左击半径变小,右击变大

from tkinter import *
import tkinter.messagebox
class EnlargeShrinkCircle:
        def __init__(self):
                self.radius=50
                window=Tk()
                window.title("Control Circle Demo")
                self.canvas=Canvas(window,width=200,height=200)
                self.canvas.pack()
                self.canvas.create_oval(100-self.radius,100-self.radius,100+self.radius,100+self.radius,tags="Circle")
                window.bind("<Button-1>",self.decreaseCircle)
                window.bind("<Button-3>",self.increaseCircle)
                
                window.mainloop()
        def increaseCircle(self,event):
                if  self.radius<100:
                        self.canvas.delete("Circle")
                        self.radius+=2
                        self.canvas.create_oval(100-self.radius,100-self.radius,100+self.radius,100+self.radius,tags="Circle")
                else :
                        tkinter.messagebox.showwarning("警告","圆的半径已到达最大值,不能溢界")
               
        def decreaseCircle(self,event):
                if  self.radius>2:
                        self.canvas.delete("Circle")
                        self.radius-=2
                        self.canvas.create_oval(100-self.radius,100-self.radius,100+self.radius,100+self.radius,tags="Circle")
                else:
                        tkinter.messagebox.showwarning("警告","圆的已到达最小值,不能溢界")
EnlargeShrinkCircle()

在这里插入图片描述

9 动画

9.1存在一个问题的动画

from tkinter import *
class AnimationDemo:
        def __init__(self):
                window=Tk()
                window.title("Animation Demo")
                width=250       #width of the canvas
                canvas=Canvas(window, bg="white",width=300,height=50)
                canvas.pack()

                x=0
                canvas.create_text(x,30,text="This is a moving message.",tags="text")
                dx=3
                while True:
                        canvas.move("text",dx,0)
                        canvas.after(100)#Sleep
                        canvas.update()#Update canvas 重新显示画板
                        if x<width:
                                x+=dx
                        else:
                                x=0
                                canvas.delete("text")
                                canvas.create_text(x,30,text="This is a moving message.",tags="text")
                window.mainloop()
                 #关闭窗口时, draw() 还在跑, 但canvas已经没有了,出现”tkinter.TclError: invalid command name ".!canvas"的错误,可以通过按钮来控制关闭canvas,不报错
AnimationDemo()

在这里插入图片描述

9.2 改进的动画

from tkinter import *
class AnimationDemo:
        def stop(self):
                self.isStopped=True
        def Resume(self):
                self.isStopped=False
                self.Animation()
        def Faster(self):
                if self.SleepTime>5:
                        self.SleepTime-=20
        def Slower(self):
                        self.SleepTime+=20


        def __init__(self):
                self.window=Tk()
                self.window.title("Animation Demo")
                self.width=250       #width of the canvas
                self.canvas=Canvas(self.window, bg="white",width=300,height=50)
                self.canvas.pack()

                frame=Frame(self.window)
                frame.pack()
                btStop=Button(self.window,text="Stop",font=("华文新魏",20),command=self.stop).pack(side=LEFT)
                btResume=Button(self.window,text="Resume",font=("华文新魏",20),command=self.Resume).pack(side=LEFT)
                btFaster=Button(self.window,text="Faster",font=("华文新魏",20),command=self.Faster).pack(side=LEFT)
                btSlower=Button(self.window,text="Slower",font=("华文新魏",20),command=self.Slower).pack(side=LEFT)
                btQuit=Button(self.window,text="Quit",font=("华文新魏",20),command=self.window.quit).pack(side=LEFT)
                self.isStopped=False
                self.x=0
                self.SleepTime=100
                self.dx=3
                self.canvas.create_text(self.x,30,text="This is a moving message.",tags="text")
                self.Animation()
                self.window.mainloop()

        def Animation(self):
                while not self.isStopped:
                        self.canvas.move("text",self.dx,0)
                        self.canvas.after(self.SleepTime)
                        self.canvas.update()
                        if self.x< self.width:
                                self.x+=self.dx
                        else:
                                self.x=0
                                self.canvas.delete("text")
                                self.canvas.create_text(self.x,30,text="This is a moving message.",tags="text")

AnimationDemo()

在这里插入图片描述

可以通过stop后点击x或quit按钮关闭,不会出现错误

10 滚动条

from tkinter import *
class ScollText:
    def __init__(self):
        window=Tk()
        window.title("Scoll Text")

        frame1=Frame(window)
        frame1.pack()

        scrollbar=Scrollbar(frame1)
        scrollbar.pack(side=RIGHT,fill=Y)
        text=Text(frame1,width=40,height=10,wrap=WORD,yscrollcommand=scrollbar.set)
        text.pack()
        scrollbar.config(command=text.yview)# create a event loop
        window.mainloop()
ScollText()

在这里插入图片描述

11 标准对话框 Messagebox

import tkinter.messagebox
import tkinter.simpledialog
tkinter.messagebox.showinfo("showinfo","This is a info msg")
tkinter.messagebox.showwarning("showwarning","This is a warning")
tkinter.messagebox.showerror("showerror","This is an error")
isYes=tkinter.messagebox.askyesno("askyesno","Continue?")
print(isYes)
isOK=tkinter.messagebox.askokcancel("askokcancel","Ok?")
print(isOK)
isYesNoCancel=tkinter.messagebox.askyesnocancel("askyesnocancel","Yes,No,Cancel?")# True,False,None
print(isYesNoCancel)
name=tkinter.simpledialog.askstring("askstring","Enter your name")
age=tkinter.simpledialog.askinteger("askinteger","Enter your age")
weight=tkinter.simpledialog.askfloat("askfloat","Enter your weight")
print("Name=",name," Age=",age," Weight=",weight)


发布了162 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44001521/article/details/104563200