Python中Tkinter知识点总结

目录

一、导入模块

二、类的写法

三、各组件的功能

1.Button

2.Label

3.Entry

4.Text && Tag

5.RadioButton && CheckButton

6.Canvas

7.布局管理器

①grid

②pack

③place 

8.Event 

9.OptionMenu && Scale 

10.Color && file choose frame

11.Simpledialog && messagebox

 12.Menu

四、实战演练

1.NoteBook

2.DrawingPad


一、导入模块

python中提供tkinter模块进行GUI设计,使用时直接按照import tkinter 或者 import tkinter as tk导入即可。

二、类的写法

类的写法思路应包括:

①导入模块

②类的实现(包括master参数的传入和组件的创建)

③主界面的设置(包括大小、标题、循环等)

具体代码如下:

from tkinter import *

class Application(Frame):    #继承Frame
    def __init__(self,master=None):    #传入master参数
        super().__init__(master)
        self.pack()        #界面布局,可以更改
        self.creatWidge()

    def creatWidge(self):    #创建组件
        pass

root = Tk()    #设置主界面
root.geometry("500x300+450+250")    #设置大小
root.title("一个经典程序GUI的类的写法")    #设置标题
Application(master=root)

root.mainloop()    # 界面循环

三、各组件的功能

tkinter模块中提供多种组件,如下图所示:

 下面文章将介绍主要的几种组件。

1.Button

Button初始化传入参数为:def __init__(self, master=None, cnf={}, **kw)

这意味着需要给Button传入一个master参数。

如果需要对Button属性进行设置,则需要引入Options选项的概念,我们可以通过三种方式设置Options选项,这在各种GUI组件中用法都一致。

①创建对象是,使用命名参数(关键字参数)

fred = Button(self,fg="red",bg="blue")

②创建对象之后,使用字典索引方式

fred["fg"] = "red"

③创建对象后,使用config()方法

fred.coonfig(fg="red",bg="blue")

各种Options选项如下:

 

 对Button属性设置完成之后需要再调用pack()方法将其进行布局。

 以下为一种实例:

    def creatWidge(self):
        self.btn01 = Button(self)
        self.btn01["text"] = "ButtonOne"
        self.btn01.pack()
        self.btn01["command"] = self.ButtonOne
        self.btnQuit = Button(self,text="退出",command=root.destroy)
        self.btnQuit.pack()

    def ButtonOne(self):
        tk.messagebox.showinfo("Title","Content")    
        #需要在tkinter模块中导入messagebox

2.Label

Label的常用属性如下所示:

Label的具体配置过程与Button类似。

应注意Label中image参数无法直接传入图片路径,应配合PhotoImage函数使用,具体实例如下:

    def creatWidge(self):
        self.label01 = Label(self, text="The Cat", width=10, height=2,
                             bg="blue", fg="white",font=("黑体",30),anchor=W)
        self.label01.pack()
        self.photo1 = PhotoImage(file="imgs/cat.png")
        self.label02 = Label(self,image=self.photo1)
        self.label02.pack()

image参数也可以传入Button中。

3.Entry

Entry用来传入用户输入的字符串,内容需要使用StringVar()来保存在一个变量中,可以通过set方法设置初始值,然后传入到textvariable里面。

以下是一个实例:

    def creatWidge(self):
        self.NameLable = Label(self,text="用户名")
        self.NameLable.pack()
        v1 = StringVar()
        v1.set("admin")
        self.NameEntry = Entry(self,textvariable=v1)
        self.NameEntry.pack()
        # print(v1.get());print(self.NameEntry.get())   打印输入框内的值
        self.PasswordLable = Label(self,text="密码")
        self.PasswordLable.pack()
        v2 = StringVar()
        self.PasswordEntry = Entry(self,textvariable=v2,show="*")
        self.PasswordEntry.pack()
        self.Login = Button(self,text="登录",command=self.login)
        self.Login.pack()

    def login(self):
        if  self.NameEntry.get() == "Chen" and  self.PasswordEntry.get() == "123456":
            messagebox.showinfo("系统", "登录成功!")
        else:
            messagebox.showinfo("系统", "登录失败!用户名或密码错误!")

4.Text && Tag

Text是多行文本框,可以用来给用户进行文本输入,具体功能如下面的例子所示:

    def creatWidge(self):
        self.text1 = Text(self,width=70,height=30,bg="gray")
        self.text1.pack()
        self.text1.insert(1.0,"请输入文字...",)      #1行0列插入一段文字(Text从1行0列开始)
        Button(text="重复插入文本",command=self.insertText).pack(side="left")
        Button(text="返回文本", command=self.returnText).pack(side="left")
        Button(text="添加图片", command=self.addImage).pack(side="left")
        Button(text="添加组件", command=self.addWidget).pack(side="left")
        Button(text="通过tag精确控制文本", command=self.textTag).pack(side="left")

    def insertText(self):
        self.text1.insert(INSERT,' Chen ')      #INSERT表示在光标处插入
        self.text1.insert(END,'[cat]')          #END表示在文本最后插入

    def returnText(self):
        print(self.text1.get(1.2,1.5))
        print(self.text1.get(1.0,END))      #打印全部内容

    def addImage(self):
        self.photo = PhotoImage(file="imgs/cat.png")
        self.text1.image_create(END,image=self.photo)       #添加图片

    def addWidget(self):
        b1 = Button(text="Button")
        self.text1.window_create(INSERT,window=b1)      #添加按钮

    def textTag(self):
        self.text1.delete(1.0,END)      #删除全部内容
        self.text1.insert(INSERT,"There is no word!\n面向CSDN编程!\n百度一下,你就知道!")
        self.text1.tag_add("word",1.12,1.16)     # 添加一个tag,tag名称为word
        self.text1.tag_config("word",background="yellow",foreground="red")     # 对tag进行配置
        self.text1.tag_add("baidu",3.0,3.4)
        self.text1.tag_config("baidu",underline=True)       #添加下划线
        self.text1.tag_bind("baidu","<Button-1>",self.webshow)      # 对tag进行绑定

    def webshow(self,event):
        webbrowser.open("http://www.baidu.com")     #需要用到webbrowser模块

5.RadioButton && CheckButton

RadioButton是单选按钮,CheckButton是多选按钮,都需要一个变量储存内容,具体功能如下面例子所示:

    def creatWidge(self):
        self.v1 = StringVar()
        self.v1.set("M")
        self.v2 = IntVar()
        self.v3 = IntVar()
        self.Radio1 = Radiobutton(text="男性",value="M",variable=self.v1)     #单选按钮配置
        self.Radio2 = Radiobutton(text="女性", value="F", variable=self.v1)
        self.Radio1.pack(side="left");self.Radio2.pack(side="left")
        Button(text="确认",command=self.confirm_one).pack(side="left")
        self.Check1 = Checkbutton(text="敲代码",variable=self.v2,onvalue=1,offvalue=0)     #多选按钮配置
        self.Check2 = Checkbutton(text="睡觉",variable=self.v3,onvalue=1,offvalue=0)
        self.Check1.pack(side="right");self.Check2.pack(side="right")
        Button(text="确认",command=self.confirm_two).pack(side="right")

    def confirm_one(self):
        messagebox.showinfo("Confirm","性别为:"+self.v1.get())

    def confirm_two(self):
        if self.v2.get()==1:
            messagebox.showinfo("Confirm","赶紧敲代码!")
        if self.v3.get()==1:
            messagebox.showinfo("Confirm","碎觉碎觉~")
        elif self.v2.get()!=1:
            messagebox.showinfo("Confirm","为什么什么都不选?")

6.Canvas

Canvas用于图形绘制,具体功能如下面例子所示:

    def creatWidge(self):
        self.canvas = Canvas(self,width=300,height=200,bg="gray")
        self.canvas.pack()
        line = self.canvas.create_line(10,10,30,20,40,50)   # 画一条折线
        rect = self.canvas.create_rectangle(50,50,100,100)  # 画一个矩形
        oval = self.canvas.create_oval(50,50,100,100)    # 画一个椭圆
        self.photo = PhotoImage(file="imgs/Reimu.png")
        self.canvas.create_image(120,170,image=self.photo)      #导入一个图片
        Button(self,text="画十个矩形",command=self.draw10Rect).pack(side="left")
    def draw10Rect(self):
        for i in range(10):
            x1 = random.randrange(int(self.canvas["width"])/2)      #生成一个0到width的数字
            y1 = random.randrange(int(self.canvas["height"])/2)
            x2 = x1 + random.randrange(int(self.canvas["width"]) / 2)
            y2 = y1 + random.randrange(int(self.canvas["height"]) / 2)
            self.canvas.create_rectangle(x1,y1,x2,y2)

7.布局管理器

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

①grid

grid表格布局,采用表格结构组织组件,子组件的位置由行和列的单元格来确定,grid方法提供的选项如下所示:

具体实例如下:

    def creatWidge(self):
        btnText = (("MC","M+","M-","MR"),
                   ("C","±","/","×"),
                   (7,8,9,"-"),
                   (4,5,6,"+"),
                   (1,2,3,"="),
                   (0,"."))         #计算器内容
        Entry().grid(row=0,column=0,columnspan=4,pady=10)
        for rindex,r in enumerate(btnText):     #enumerate(btnText)将btnText变成枚举对象
            for cindex,c in enumerate(r):
                if c == "=":
                    Button(text=c, width=2).grid(row=rindex + 1, column=cindex, sticky=NSEW,rowspan=2)
                elif c == 0:
                    Button(text=c, width=2).grid(row=rindex + 1, column=cindex, sticky=EW,columnspan=2)
                elif c == ".":
                    Button(text=c, width=2).grid(row=rindex + 1, column=cindex+1, sticky=EW)
                else:
                    Button(text=c,width=2).grid(row=rindex+1,column=cindex,sticky=EW)

                                                         

②pack

pack是最简单的布局管理器,只能实现水平或者垂直的布局,pack方法提供的选项如下:

具体实例如下:

root = Tk();root.geometry("700x200")

f1 = Frame(root); f1.pack()
f2 = Frame(root); f2.pack()

btnText = ("流行风","中国风","日本风","重金属","轻音乐")
for txt in btnText:
    Button(f1,text=txt).pack(side="left",padx="10")

for i in range(13):
    Label(f2,width=5,height=10,borderwidth=1,relief="solid",
          bg="black" if i%2==0 else "white").pack(side="left",padx=2)

root.mainloop()

③place 

place位置管理器,可以通过像素控制组件位置,place方法提供的选项如下:

具体实例如下:

    def creatWidge(self):
        self.photos = [PhotoImage(file=f"imgs/puke/puke{i+1}.png") for i in range(10)]
        self.pukes = [Label(root,image=self.photos[i]) for i in range(10)]
        for i in range(10):
            self.pukes[i].place(x=10+i*40,y=50)
        self.pukes[0].bind_class("Label","<Button-1>",self.chupai)  # 为所有的Label增加事件处理

    def chupai(self,event):
        if event.widget.winfo_y() == 50:
            event.widget.place(y=30)
        else:
            event.widget.place(y=50)

 

8.Event 

Event常用事件:

具体实例如下:

root = Tk();root.geometry("530x300")
c1 = Canvas(root,width=200,height=200,bg="blue")
c1.pack()

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

def testDrag(event):
    c1.create_oval(event.x,event.y,event.x+1,event.y+1)

def keyboardTest(event):
    print("键的keycode:{0},键的char:{1},键的keysym:{2}".format(event.keycode,event.char,event.keysym))

def press_a_test(event):
    print("press a")
def release_a_test(event):
    print("release a")

c1.bind("<Button-1>",mouseTest)
c1.bind("<B1-Motion>",testDrag)
root.bind("<KeyPress>",keyboardTest)
root.bind("<KeyPress-a>",press_a_test)
root.bind("<KeyRelease-a>",release_a_test)
root.mainloop()

9.OptionMenu && Scale 

OptionMenu 和 Scale 分别为选择菜单和滑条,具体例子如下:

root = Tk();root.geometry("200x100")
v = StringVar()
v.set("选项一")
om = OptionMenu(root,v,"选项一","选项二","选项三","选项四")
om["width"] = 10
om.pack()

def test1():
    print("你的选项是:",v.get())

def test2(value):
    # Scale滑动时自动传入value参数
    newFont=("宋体",value)
    a.config(font=newFont)

s1 = Scale(root,from_=10,to=50,length=200,tickinterva=5,orient=HORIZONTAL,command=test2)
# orient默认为垂直,加上HORIZONTAL为水平
s1.pack()
a = Button(root,text="确定",command=test1)
a.pack()
root.mainloop()

10.Color && file choose frame

Color choose frame需要导入tkinter.colorchooser模块,file choose frame需要导入tkinter.filedialog模块,filedialog模块函数和命名参数如下:

  

具体例子如下:

root = Tk();root.geometry("600x400+500+200")

def test1():
    s1 = askcolor(color="red",title="选择背景颜色")
    # s1的形式为:((0.0,0.0,255.99609375),'#0000ff')
    root.config(bg=s1[1])

def test2():
    f = askopenfilename(title="上传文件",initialdir="Chen")
    show["text"] = f

def test3():
    with askopenfile(title="上传文件",filetypes=[("文本文件","txt")]) as f:
        show["text"] = f.read()

Button(root,text="选择背景颜色",command=test1).pack()
Button(root,text="选择编辑的文件",command=test2).pack()
Button(root,text="选择读取的文本文件",command=test3).pack()
show = Label(root,width=40,height=3,bg="green")
show.pack()
root.mainloop()

11.Simpledialog && messagebox

Simledialog需要导入tkinter.simpledialog模块,messagebox需要导入tkinter.messagebox模块。

simpledialog常用函数如下:

messagebox常用函数如下:

 具体实例如下:

root = Tk();root.geometry("400x100+500+300")
def test1():
    a = askinteger(title="输入年龄",prompt="请输入年龄",initialvalue=18,minvalue=1,maxvalue=100)
    # askstring、askfloat框使用方法一样
    show["text"]=a

Button(root,text="你多大了?",command=test1).pack()
show = Label(root,width=40,height=3,bg="green")
show.pack()
a1 = showinfo(title="学习pyhton",message="零基础学习python")
root.mainloop()

 12.Menu

通过Menu组件我们可以建立主菜单和快捷菜单,具体例子如下:

    def creatWidge(self):
        # 创建主菜单栏
        menubar = Menu(root)
        # 创建子菜单栏
        menuFile = Menu(menubar)
        menuEdit = Menu(menubar)
        menuHelp = Menu(menubar)
        # 将子菜单添加到主菜单栏
        menubar.add_cascade(label="文件(F)",menu=menuFile)
        menubar.add_cascade(label="编辑(E)",menu=menuEdit)
        menubar.add_cascade(label="帮助(H)",menu=menuHelp)
        # 添加菜单项
        menuFile.add_command(label="新建",accelerator="ctrl+n",command=self.test)
        menuFile.add_command(label="打开",accelerator="ctrl+o",command=self.test)
        menuFile.add_command(label="保存",accelerator="ctrl+s",command=self.test)
        menuFile.add_separator() # 添加分割线
        menuFile.add_command(label="退出",accelerator="ctrl+q",command=self.test)
        # 将主菜单加到根窗口
        root.config(menu=menubar)
        # 文本编辑区
        self.textpad = Text(root,width=50,height=30)
        self.textpad.pack()
        # 创建上下菜单
        self.contextMenu = Menu(root)
        self.contextMenu.add_command(label="背景颜色",command=self.test)
        # 右键绑定事件
        root.bind("<Button-3>",self.createContextMenu)

    def test(self):
        pass

    def createContextMenu(self,event):
        # 菜单在鼠标右键单击的坐标处显示
        self.contextMenu.post(event.x_root,event.y_root)

四、实战演练

1.NoteBook

from tkinter import *

class Application(Frame):
    def __init__(self,master=None):
        super().__init__(master)
        self.master = master
        self.textpad = None
        self.pack()
        self.creatWidge()

    def creatWidge(self):
        # 创建主菜单栏
        menubar = Menu(root)
        # 创建子菜单栏
        menuFile = Menu(menubar)
        menuEdit = Menu(menubar)
        menuHelp = Menu(menubar)
        # 将子菜单添加到主菜单栏
        menubar.add_cascade(label="文件(F)",menu=menuFile)
        menubar.add_cascade(label="编辑(E)",menu=menuEdit)
        menubar.add_cascade(label="帮助(H)",menu=menuHelp)
        # 添加菜单项
        menuFile.add_command(label="新建",accelerator="ctrl+n",command=self.test)
        menuFile.add_command(label="打开",accelerator="ctrl+o",command=self.test)
        menuFile.add_command(label="保存",accelerator="ctrl+s",command=self.test)
        menuFile.add_separator() # 添加分割线
        menuFile.add_command(label="退出",accelerator="ctrl+q",command=self.test)
        # 将主菜单加到根窗口
        root.config(menu=menubar)
        # 文本编辑区
        self.textpad = Text(root,width=50,height=30)
        self.textpad.pack()
        # 创建上下菜单
        self.contextMenu = Menu(root)
        self.contextMenu.add_command(label="背景颜色",command=self.test)
        # 右键绑定事件
        root.bind("<Button-2>",self.createContextMenu)

    def test(self):
        pass

    def createContextMenu(self,event):
        # 菜单在鼠标右键单击的坐标处显示
        self.contextMenu.post(event.x_root,event.y_root)

if __name__ == '__main__':
    root = Tk()
    root.geometry("300x300+450+200")
    root.title("Test")
    app = Application(master=root)

    root.mainloop()

2.DrawingPad

from tkinter import *
from tkinter.colorchooser import *

# 窗口的宽度和高度
win_width = 900
win_height = 500
# 画布背景颜色
bgcolor = "black"

class Application(Frame):
    def __init__(self,master=None):
        super().__init__(master)
        self.fgcolor="#ff0000"
        self.lastDraw = 0       # 用于删除未完成的直线
        self.startDrawFlag = False      # 用于定位直线开始位置
        self.pack()
        self.creatWidge()

    def creatWidge(self):
        # 创建绘画区
        self.drawpad = Canvas(root,width=win_width,height=win_height*0.9,bg=bgcolor)
        self.drawpad.pack()
        # 创建按钮
        btn_start = Button(root,text="开始",name="start")
        btn_start.pack(side="left",padx="30")
        btn_pen = Button(root,text="画笔",name="pen")
        btn_pen.pack(side="left",padx="30")
        btn_rect = Button(root,text="矩形",name="rect")
        btn_rect.pack(side="left",padx="30")
        btn_clear = Button(root,text="清屏",name="clear")
        btn_clear.pack(side="left",padx="30")
        btn_eraser = Button(root,text="橡皮擦",name="eraser")
        btn_eraser.pack(side="left",padx="30")
        btn_line = Button(root,text="直线",name="line")
        btn_line.pack(side="left",padx="30")
        btn_arrowLine = Button(root,text="箭头",name="arrowLine")
        btn_arrowLine.pack(side="left",padx="30")
        btn_color = Button(root,text="画笔颜色",name="color")
        btn_color.pack(side="left",padx="30")
        # 事件处理
        btn_pen.bind_class("Button","<1>",self.eventManager)
        self.drawpad.bind("<ButtonRelease-1>",self.stopDraw)
        # 增加快捷键
        root.bind("<Control-r>", lambda event: self.myColor())

    def eventManager(self,event):
        name =event.widget.winfo_name()
        if name == "line":
            self.drawpad.bind("<B1-Motion>",self.myline)
        elif name == "arrowLine":
            self.drawpad.bind("<B1-Motion>",self.myarrowLine)
        elif name == "rect":
            self.drawpad.bind("<B1-Motion>", self.myRect)
        elif name == "pen":
            self.drawpad.bind("<B1-Motion>",self.myPen)
        elif name == "eraser":
            self.drawpad.bind("<B1-Motion>",self.myEraser)
        elif name == "clear":
            self.drawpad.delete("all")
        elif name == "color":
            self.myColor()

    def stopDraw(self,event):
        self.startDrawFlag = False      # 重新定位直线初始位置
        self.lastDraw = 0       # 防止生成的直线被删除

    def startDraw(self,event):
        self.drawpad.delete(self.lastDraw)  # 删除未完成的直线
        if not self.startDrawFlag:
            # 定位直线的初始位置
            self.startDrawFlag = True
            self.x = event.x
            self.y = event.y

    def myline(self,event):
        self.startDraw(event)
        self.lastDraw = self.drawpad.create_line(self.x,self.y,event.x,event.y,fill=self.fgcolor)

    def myarrowLine(self,event):
        self.startDraw(event)
        self.lastDraw = self.drawpad.create_line(self.x,self.y,event.x,event.y,fill=self.fgcolor,arrow=LAST)

    def myRect(self,event):
        self.startDraw(event)
        self.lastDraw = self.drawpad.create_rectangle(self.x,self.y,event.x,event.y,outline=self.fgcolor)

    def myPen(self,event):
        self.startDraw(event)
        self.drawpad.create_line(self.x,self.y,event.x,event.y,fill=self.fgcolor)
        self.x = event.x
        self.y = event.y

    def myEraser(self,event):
        self.startDraw(event)
        self.drawpad.create_rectangle(self.x-4, self.y-4, event.x+4, event.y+4, fill=bgcolor)
        self.x = event.x
        self.y = event.y

    def myColor(self):
        c = askcolor(color=self.fgcolor, title="选择画笔颜色")
        self.fgcolor = c[1]

if __name__ == '__main__':
    root = Tk()
    root.geometry(f"{win_width}x{win_height}+300+150")
    root.title("Canvas")
    app = Application(master=root)
    root.mainloop()

  • 8
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值