草庐IT

可视化界面Tkinter编写你的小程序

南风知我意。。 2023-07-10 原文

可视化界面Tkinter编写小程序

引言

本文将会介绍 Tkinter 模块的使用。Tkinter 模块是 Python 的标准 Tk GUI 工具包的接口。其中Tkinter 是唯一一个 Python 内置的标准库,虽然它做出来的 GUI 看上去比较不美观,但鉴于它可在多平台运行(Windows、Linux、macOS),因此我们可以用它来开发一些简单的小程序;而且tk中使用的组件使用的是系统自带的组件,所以看起来比较自然。

一、制作第一个基于tkinter的小应用

Tkinter GUI 的最根本的元素是 窗口。窗口会包含所有其他的 GUI 的元素,如:Textlabelbutton等,这些都被称作 widgets(小组件)。作为第一个例子,我们首先创建一个 窗口(设置窗口的属性)。代码如下:

import tkinter as tk

def get_window():
    window = tk.Tk()                    #实例化一个窗口
    window.title("我的第一个tk应用!")   #修改窗口的标题
    window.geometry("260x100")          #设置窗口的宽260x高100,注意是x
    tk.mainloop()                       #监听事件的发生,如点击、按键、按钮等。必选项
if __name__ == '__main__':				#下面调用的函数在其他文件不会运行,仅在本文件执行
    get_window()

1.1 给自己的应用加个小图标

这里tkinter库添加图标有三种方式,①利用PhotoImage和iconphoto方法,②使用iconbitmap方法,③使用tk.call和PhotoImage方法。注意:PhotoImage仅支持GIF、PNG和PGM/PPM文件格式。iconbitmap仅支持ico格式。具体代码如下:

import tkinter as tk

class FirstApplication(object):						 #定义一个继承object基类的FirstApplication类
    def __init__(self):                              #初始化魔法方法,运行时优先执行
        self.window = tk.Tk()                             #实例化一个窗口
        self.window.title("我的第一个tk应用!")           #修改窗口的标题
        self.window.geometry("260x100")                   #设置窗口高和宽

    def set_icon1(self):                                  #The first way
        ima = tk.PhotoImage(file="pic.png")
        self.window.iconphoto(False,ima)         #若第一个参数为True,则该图像在所有的顶层都可见

    def set_icon2(self):                                   #The second way
        self.window.iconbitmap("sheep.ico")                #图片格式只能为ico

    def set_icon3(self):                                  #The third way
        self.window.tk.call('wm', 'iconphoto', self.window._w, tk.PhotoImage(file='pic.png'))

    def play(self):
        # self.set_icon2()
        # self.set_icon3()
        self.set_icon1()                             #Use different ways to set icon for window
        tk.mainloop()                                #监听事件的发生,如点击、按键、按钮等。必选项
if __name__ == '__main__':
    st = FirstApplication()                          #实例化
    st.play()                                        #调用play函数开始运行

二、tkinter的常用组件介绍

2.1 Label(标签)介绍

Label 可以用来显示文本和图片。通过 Label widget 显示的内容是无法被用户修改的,这个只是用来作为显示。
在默认情况下,Label widgets 会以系统默认的颜色来进行显示字体颜色和背景颜色,但是我们可以对标签进行编辑:修改(bg)背景颜色、(fg)文本颜色、标签大小–宽和高、标签的位置。

2.1.1 设置文本标签并设置属性

代码如下:

import tkinter as tk

class FirstApplication(object):
    def __init__(self):                              #初始化魔法方法,运行时优先执行
        self.window = tk.Tk()                             #实例化一个窗口
        self.window.title("我的第一个tk应用!")           #修改窗口的标题
        self.window.geometry("300x100")                   #设置窗口高和宽
        self.window.iconbitmap("sheep.ico")

    def get_label(self):
        label = tk.Label(master=self.window,text="hello world!",height=2,
                         width=12,bg="pink",fg="red",font="10px")  #这里设置一个标签,设置属性
        label.pack(side="left",padx=5,pady=5)   #这里side="left"指标签靠左,如right\top\bottom;还可使用tk.RIGHT\tk.LEFT\tk.BOTTOM\tk.TOP
        
    def play(self):
        self.get_label()
        tk.mainloop()                                #监听事件的发生,如点击、按键、按钮等。必选项
if __name__ == '__main__':
    st = FirstApplication()                          #实例化
    st.play()                                        #调用play函数开始运行


标签中常用部分参数解释:

master: 这里指标签对象所在的父容器。如果为空或为window,则在第一层窗口中,若为frame框,则在frame框中。
text: 指标签的文本信息
height: 指标签的高度
width: 指标签的宽度
bg(background): 指标签背景颜色
fg(foreground):前景颜色–改变的是字体颜色
borderwidth: 指边框宽度
font:指字体的大小 ,px可选
padx:指文本距离标签框的横向距离
pady:指文本距离标签框的纵向距离

2.1.2 设置图片标签

代码如下,自己替换对应函数的代码即可运行:

    def get_label(self):
        photo = tk.PhotoImage(file="pic.gif")   
        label2 = tk.Label(master=self.window,image =photo)   #设置标签图片
        label2.suiji = photo    #注意这里需要重新赋值,suiji可以为任意,汉字也可以,这算程序的bug吧,哈哈,设置完就可以看得到图片了
        label2.pack(side="left")

2.1.4 使用PIL库设置图片标签

注意,如果没有PIL,则需要安装对应的库:pip install Pillow,为什么使用PIL,因为PIL支持的图片格式更多,支持30多种。代码如下:

import tkinter as tk
from PIL import Image,ImageTk   #多导了一个PIL库

class FirstApplication(object):
    def __init__(self):                              #初始化魔法方法,运行时优先执行
        self.window = tk.Tk()                             #实例化一个窗口
        self.window.title("我的第一个tk应用!")           #修改窗口的标题
        self.window.geometry("300x100")                   #设置窗口高和宽

    def get_label(self):
        ima = Image.open(fp="pic.jpg")
        imag = ImageTk.PhotoImage(ima)
        lab = tk.Label(image=imag)
        lab.image = imag          #这里仍然需要重新赋值,经过测试,lab.X(X可以为任意变量)都能得到照片
        lab.pack()
        self.window.iconphoto(False,imag)   #而且这种方式也能给窗口设置图片,,,,
    def get_label1(self):    #第二种方式
        ima = Image.open(fp="pic.jpg")
        global imag   #设置imag为全局变量,即可显示图片
        imag = ImageTk.PhotoImage(ima)
        lab = tk.Label(image=imag)
        lab.pack()

    def play(self):
        self.get_label()
        #self.get_label1()
        tk.mainloop()                                #监听事件的发生,如点击、按键、按钮等。必选项
if __name__ == '__main__':
    st = FirstApplication()                          #实例化
    st.play()                                        #调用play函数开始运行

如下图所示,也可以给窗口设置图片。

2.1.4 一次性生成多个标签图片

代码如下,替换对应的代码即可:

    def get_label(self):
        img_list=["pic.jpg","pic.jpg","pic.jpg"]
        for i,j in enumerate(img_list):   #这里i=列表的下标,j=列表的图片
            ima = Image.open(fp=j).resize((100,100))   #这里可加resize重新调整图片大小,记得里面是一个元组。
            imag = ImageTk.PhotoImage(ima)
            lab = tk.Label(image=imag)
            lab.哈哈 = imag
            lab.grid(row=0,column=i)   #这里是标签位置的另外一种方法,具体是把窗口分成多个单元格,这里表示第一行,第I列。

2.1.5 设置位图标签

代码如下,直接替换对应的函数即可,想一次性生成很多个位图标签也可以按照上面的方法:

    def get_label(self):
        label3 = tk.Label(bitmap = "warning")   #bitmap可以为error、warning、info、hourglass、questhead、question、gray12、gray25、gray50、gray75等
        label3.pack()

2.1.6 补充:获取或重置标签的属性

有时候我们想要修改定义好的标签属性,我们应该怎么操作呢?下面这种方法也许可以解决你的问题。具体代码如下:

import tkinter as tk

win = tk.Tk()
lab1 = tk.Label(text = "hello")
lab1["padx"] = "30"
lab1["bg"] = "red"   #还可以直接通过重新赋值方式改变组件的属性:颜色、大小、内容
print(lab1["text"])
lab1.pack()
win.mainloop()

输出标签文本:hello

2.2 Button(按钮)介绍

Button 可以用来显示可点击的按钮。其中button里面的command命令参数可以绑定对应的函数(即点击Button可以触发一个事件);其中button还可以直接使用button.bind()方法绑定函数和按键。其中button按钮的参数和label标签的参数基本一样。下面我简单介绍这两种使用方法。

2.2.1 使用Button的command触发事件

代码如下:

import tkinter as tk

class ButtonClass(object):

    def __init__(self):
        self.win = tk.Tk()
        self.win.geometry("300x100")
        self.win.title("按钮学习")

    def fun(self,*args):
        self.btn1["text"] = "已经被点击"
        self.btn1["fg"] = "red"
        pass
    def get_button(self):
    # 这里使用了command参数来绑定函数,点击按钮则触发fun函数
        self.btn1 = tk.Button(text="确认",bg = "blue",fg="white",command =self.fun)
        self.btn1.pack(ipady = 10,pady=10)

    def play(self):
        self.get_button()
        self.win.mainloop()
if __name__ == '__main__':
    btn = ButtonClass()
    btn.play()

2.2.2 使用bind方法绑定按键触发事件

可以绑定鼠标右键(Button-1)、滚轮(Button-2)、左键(Button-3)来触发事件。

    def get_button(self):
        self.btn1 = tk.Button(text="确认",bg = "blue",fg="white")
        self.btn1.pack(ipady = 10,pady=10)
        self.btn1.bind("<Button-1>",self.fun)

2.3 Entry(单行文本输入框)介绍

用户可以在文本框输入内容、删除内容或获取内容,同样的是,创建文本输入框跟创建按钮和标签的方法相似。一般文本输入框和标签一起搭配使用。

2.3.1 创建我的第一个输入框

输入内容mick。

import tkinter as tk

class App(object):
    
    def __init__(self):
        self.win = tk.Tk()
        self.win.geometry("300x100")
        self.win.title("单行文本输入框学习")

    def single_box(self):
        lab = tk.Label(text = "Name:",fg="black")
        lab.pack(side="left")
        ent = tk.Entry(width = 10,bg="white",fg="red")
        ent.pack(side="left")

    def play(self):
        self.single_box()
        self.win.mainloop()
if __name__ == '__main__':
    a = App()
    a.play()

2.3.2 内容写入、内容删除、内容获取

具体请看代码:

import tkinter as tk

class App(object):

    def __init__(self):
        self.win = tk.Tk()
        self.win.geometry("300x100")
        self.win.title("单行文本输入框学习")

    def get_name(self,*args):     #获取文本框输入端的内容
        self.ent.delete(0,tk.END)    #这里表示删除全部的内容,delete(first, last=None)
        self.ent.insert(0,"hello world")   #指定位置插入内容:insert(index, string)
        name = self.ent.get()              #取到文本:get(index1, index2=None)可以取范围
        print(name)

    def single_box(self):
        lab = tk.Label(text = "Name:",fg="black")
        lab.pack(side="left")
        self.ent = tk.Entry(width = 10,bg="white",fg="red")
        self.ent.pack(side="left")
        btn1 = tk.Button(text = "输出",bg="blue")
        btn1.bind("<Button-1>",self.get_name)    #这里绑定函数
        btn1.pack(side="left")


    def play(self):
        self.single_box()
        self.win.mainloop()
if __name__ == '__main__':
    a = App()
    a.play()

2.4 Text(多行文本)介绍

具体用法和单行文本一样,只有些许差异。

get(index1, index2=None) 用法get(1.0,2.0) 表示取第一行开头到第二行开头之前
delete(first, last=None) 同上,也可以删除指定范围
insert(index, string) 在某个位置插入字符串

简单的例子:

    def get_name(self,*args):     #获取文本框输入端的内容
        self.txt.delete(1.0,tk.END)    #这里表示删除全部的内容,delete(first, last=None)
        self.txt.insert(1.0,"hello world")   #指定位置插入内容:insert(index, string)
        name = self.txt.get(1.0,1.2)              #取到文本get(index1, index2=None)
        print(name)

    def mul_box(self):
        lab = tk.Label(text = "Name:",fg="black")
        lab.pack(side="left")
        self.txt = tk.Text(width = 10,height=5,bg="white",fg="red")
        self.txt.pack(side="left")
        btn1 = tk.Button(text = "输出",bg="blue")
        btn1.bind("<Button-1>",self.get_name)
        btn1.pack(side="left")

    def play(self):
        self.mul_box()
        self.win.mainloop()

2.5 Frame(内嵌框)介绍

Frame 组件是用来组织我们在一个应用中的组件布局,意思是我们可以用多个frame框来构建界面,就像HTML5里面的DIV布局,什么元素在哪个位置一目了然。

2.5.1 构建我的第一个内嵌框

调整 Frame 的外观的方法:设置relief 和borderwidth参数

tk.FLAT: 没有边框效果(默认值)
tk.SUNKEN: 创建下沉效果
tk.RAISED: 创建凸起效果
tk.GROOVE:创建带凹槽的边框效果
tk.RIDGE: 创建脊状效果

        def get_frm(self):
        frm = tk.Frame(master=self.win,bg="blue",width=100,height=100,relief=tk.SUNKEN,borderwidth=5)
        frm.pack()
        lab = tk.Label(master=frm,text = "我的第一个frame框",fg="black",bg="white")
        lab.pack(side="left")

2.6 LabelFrame(标签内嵌框)介绍

这个内嵌框可以在内嵌框的左上角显示一个文本,可以让别人理解这个frame框是用来干嘛的。有什么作用。

    def get_frm(self):
        frm = tk.LabelFrame(master=self.win,text="Hi jack!",bg="white",width=100,height=100,relief=tk.SUNKEN,borderwidth=5)
        frm.pack()
        lab = tk.Label(master=frm,text = "我的第一个frame框",fg="black",bg="white")
        lab.pack(side="left")

2.7 comboxlist(下拉框)介绍

现实生活中,我们往往需要搭配不同的选项来进行增删改查,这时不同的选项我们就可以放到下拉框里面。

2.7.1 制作我的第一个下拉框

     def select_box(self):
        comboxlist = ttk.Combobox(self.win,width=5)  # 实例化一个下拉框
        comboxlist["values"] = ("1", "2", "3", "4")   #设置下拉框的选项
        comboxlist.current(0)  # 选择第一个
        comboxlist.pack()

2.7.2 获取下拉框的值

    def get_value(self,*args):
        print(self.cmb.get())

    def select_box(self):
        cmb = ttk.Combobox(self.win,width=5)  # 实例化一个下拉框
        cmb["values"] = ("1", "2", "3", "4")   #设置下拉框的选项
        cmb.current(0)  # 选择第一个
        cmb.pack()
        self.cmb = cmb
        cmb.bind("<<ComboboxSelected>>",self.get_value)

2.8 Checkbutton(复选框)介绍

    def mul_check_box(self):
        c_show = tk.Checkbutton(master=self.win, text="😄", variable="",
                             onvalue="RGB", offvalue="L", fg="blue")
        c_show.pack(side="top")
        c_show = tk.Checkbutton(master=self.win, text="😪", variable="",
                                onvalue="RGB", offvalue="L", fg="blue")
        c_show.pack(side="top")

2.8.1 获取复选框的选中状态

    def get_words(self,*args):
        print(self.var.get())
        
    def mul_check_box(self):
        var=tk.IntVar()        #定义一个bool的变量,选中则为0,未选中则为1
        self.var =var
        c_show = tk.Checkbutton(master=self.win, text="hello", variable=var,
                             onvalue=1, offvalue=0, fg="blue")
        c_show.pack(side="top")
        c_show.bind("<Button-1>",self.get_words)  

2.9 Radiobutton(单选框)介绍和获取选中状态

    def get_words(self,*args):
        try:
            print(self.var.get())   #这里做了异常捕获,防止取消选中时返回错误
        except:
            pass

    def single_check_box(self):
        self.var = tk.IntVar()
        r_show = tk.Radiobutton(master=self.win, text="One", variable=self.var)
        r_show.pack(anchor=tk.W)   #锚点
        r_show.bind("<Button-1>",self.get_words)

有关锚点的参数,请参照:python tkinter中的锚点(anchor)

2.10 Listbox 介绍

在窗口添加一个列表

        def fun1(self):
        lb_show = tk.Listbox( bg="white", height=4, width=20,fg="red")
        lb_show.pack(side="top")
        for item in ["Chinese", "Math", "English", "France"]:
            lb_show.insert(tk.END, item)

2.11 Scrollbar(滚动栏)介绍

    def fun1(self):
        s_show = tk.Scrollbar(master=self.win)
        s_show.pack(side=tk.RIGHT, fill=tk.Y)  #右边Y 轴填满
        lb_show1 = tk.Listbox(master=self.win, fg="red", height=5, width=20)
        lb_show1['yscrollcommand'] = s_show.set  #这里设置后滚动栏和列表绑定
        lb_show1.pack(side="right")
        for item in ["1", "2", "3", "4", "5", "6", "7"]:
            lb_show1.insert(tk.END, item)

2.11 Scale(比例)介绍

    def fun1(self):
        sc_show = tk.Scale(master=self.win, from_=0, to=100,borderwidth=2)
        sc_show.pack(side="right")

2.12 Spinbox介绍

参考文章:Tkinter 组件详解之Spinbox

    def fun1(self):
        sb_show = tk.Spinbox(master=self.win, from_=0, to=10)
        sb_show.pack(side="left"

三 、参考文档

Python GUI 工具 tkinter 介绍
其他布局方法:place(),grid()方法参考这篇文章。写的很详细。

有关可视化界面Tkinter编写你的小程序的更多相关文章

  1. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  2. ruby - Ruby 中的波形可视化 - 2

    我即将开始一个将录制和编辑音频文件的项目,我正在寻找一个好的库(最好是Ruby,但会考虑Java或.NET以外的任何库)以进行实时可视化波形。有人知道我应该从哪里开始搜索吗? 最佳答案 要流入浏览器的数据量很大。Flash或Flex图表可能是唯一能提高内存效率的解决方案。Javascript图表往往会因大型数据集而崩溃。 关于ruby-Ruby中的波形可视化,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

  3. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  4. 微信小程序通过字典表匹配对应数据 - 2

    前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立

  5. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  6. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  7. ruby-on-rails - 如何为空白字段编写 rspec? [Rails3.1] - 2

    我使用rails3.1+rspec和factorygirl。我对必填字段(validates_presence_of)的验证工作正常。我如何让测试将该事实用作“成功”而不是“失败”规范是:describe"Addanindustrywithnoname"docontext"Unabletocreatearecordwhenthenameisblank"dosubjectdoind=Factory.create(:industry_name_blank)endit{shouldbe_invalid}endend但是我失败了:Failures:1)Addanindustrywithnona

  8. ruby-on-rails - 尝试为 Rails 中的用户名验证编写 REGEX - 2

    我正在尝试用Ruby(Rails)编写一个正则表达式,以便用户名的字符仅包含数字和字母(也没有空格)。我有这个正则表达式,/^[a-zA-Z0-9]+$/,但它似乎没有用,我在Rails中收到一个错误,说“The如果正则表达式使用多行anchor(^或$),这可能会带来安全风险。您是要使用\A和\z,还是忘记添加:multiline=>true选项?"我的user.rb模型中此实现的完整代码是:classUser我做错了什么以及如何修复此正则表达式,使其仅对数字和字母有效而不对空格有效?谢谢。 最佳答案 简短回答:使用/\A[a-z

  9. ruby-on-rails - 如何编写跨模型、 Controller 和 View 的 Rails mixin - 2

    为了减少我的小Rails应用程序中的代码重复,我一直致力于将我的模型之间的通用代码放入它自己的单独模块中,到目前为止一切顺利。模型的东西相当简单,我只需要在开头包含模块,例如:classIso这工作正常,但是现在,我将有一些Controller和View代码,这些代码也将在这些模型之间通用,到目前为止,我有这个用于我的可发送内容:#Thisisamodulethatisusedforpages/formsthatarecanbe"sent"#eitherviafax,email,orprinted.moduleSendablemoduleModeldefself.included(kl

  10. ruby - 在不添加 "end"的情况下编写 Ruby 的任何方法? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭11年前。Ruby是一种美丽的语言,但有一个我讨厌写很多次的关键词“结束”。有什么方法可以写出简洁的代码而不用每次都写“end”吗?

随机推荐