Python 升级之路 ( Lv19 ) GUI 编程

开发 后端
今天我们将深入学习 GUI 图形界面编程 tkinter, 了解基础组件的使用方式。

今天我们将深入学习GUI图形界面编程tkinter, 了解基础组件的使用方式。

tkinter基础组件

在登上天维巨兽身上的时候, 了不起大吃一惊. 作为堪比一个岛屿的存在, 这个生物的身上好像蕴藏着无数的奥秘. 可是刚一下来迎接他们的不是鲜花和掌声, 而是一把匕首. GBK教信徒蜂拥而至, 由于大家事先都知道这些信徒是被控制的, 因此都特意留手. 尽量都将其击晕, 然后由奥菲利亚通过使用净化魔法来解决. 花费了近一天的时间, 才将近百名被控制的信徒解救成功. 然后在恢复意识的信徒的带领下, 了不起进入到了神殿外围的核心地区. 这里有GBL的大祭司和大神官, 也是奥菲利亚昔日的朋友...


Label 标签

Label(标签)主要用于显示文本信息,也可以显示图像。

常用属性:

  • width,height: 用于指定区域大小 如果显示是文本,则以单个英文字符大小为单位(一个汉字宽度占 2 个字符位置,高度和英文字符一样);如果显示是图像,则以像素为单位。默认值是 根据具体显示的内容动态调整
  • font: 指定字体和字体大小. 如:font = (font_name,size)
  • image: 显示在 Label 上的图像,目前 tkinter 只支持 gif 格式
  • fg 和 bg: fg(foreground):前景色、bg(background):背景色
  • justify: 针对多行文字的对齐,可设置 justify 属性,可选值"left", "center" or "right"

实操代码:

"""测试 Label 组件的基本用法,使用面向对象的方式"""
from tkinter import *


class Application(Frame):

    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.createWidget()

    def createWidget(self):
        """创建组件"""
        self.label01 = Label(self, text="点击label", width=10, height=2, bg="black", fg="white")
        self.label01["text"] = "第一个Label"
        self.label01.config(fg="red", bg="green")
        self.label01.pack()

        self.label02 = Label(self, text="第二个Label", width=10, height=2, bg="blue", fg="white", font=("黑体", 30))
        self.label02.pack()

        # 显示图像
        global photo    # 把 photo 声明成全局变量. 如果是局部变量,本方法执行完毕后,图像对象销毁,窗口显示不出图像
        photo = PhotoImage(file="111.gif")
        self.label03 = Label(self, image=photo)
        self.label03.pack()  # 在父小部件中打包一个小部件

        self.label04 = Label(self, text="第一行\n 第二行\n 第三行", borderwidth=5, relief="groove", justify="right")
        self.label04.pack()


if __name__ == "__main__":
    root = Tk()
    root.geometry("600x600+810+330")
    root.title("测试Label")
    app = Application(master=root)
    root.mainloop()

注意:

  • Label(标签)主要用于显示文本信息,也可以显示图像
  • pack 按照组件的创建顺序将子组件添加到父组件中,按照垂直或者水平的方向自然排布 如果不指定任何选项,默认在父组件中自顶向下垂直添加组件. pack 是代码量最少最简单的一种,可以用于快速生成界面.

Options 选项详解

通过学习 Label 组件,我们发现可以通过 Options 设置组件的属性,从而控制组件的各种状态. 比如:宽度、高度、颜色、位置等等。

可以通过以下三种方式设置 Options 选项,这在各种 GUI 组件中用法都一致:

  • 创建对象时,使用可变参数fred = Button(self, fg="red", bg="blue")
  • 创建对象后,使用字典索引方式
fred["fg"] = "red"
fred["bg"] = "blue"
  • 创建对象后,使用 config()方法 fred.config(fg="red", bg="blue")

如何查看组件的 Options 选项?

  • 可以通过打印 config()方法的返回值,查看 Options 选项 print(fred.config())
  • 通过在 IDE 中,ctrl+鼠标左键 即可进入组件对象的构造方法,进入到方法内观察:

上面代码中有:“standard options 标准选项”和“widget-specific options 组件特定选项”. 我们将常见的选项汇总如下:

Button 按钮

Button(按钮)用来执行用户的单击操作. Button 可以包含文本,也可以包含图像 按钮被单击后会自动调用对应事件绑定的方法. 相关属性参数介绍见上面Options 选项详解部分图片。

实操代码:

"""
Button(按钮)用来执行用户的单击操作
Button 可以包含文本,也可以包含图像。按钮 被单击后会自动调用对应事件绑定的方法
"""
from tkinter import *
from tkinter import messagebox


class Application(Frame):
    def __init__(self, master):
        super().__init__(master)  # super()代表的是父类的定义, 而不是父类的对象
        self.master = master
        self.pack()
        self.createWidget()

    def createWidget(self):
        """创建组件"""
        self.btn01 = Button(root, text="登录", width=4, height=1, anchor=NE, command=self.login)
        self.btn01.pack()

        global photo
        photo = PhotoImage(file="111.gif")
        self.btn02 = Button(root, image=photo, command=self.login)
        self.btn02.pack()
        self.btn02.config(state="disabled")  # 设置按钮为禁用

    def login(self):
        messagebox.showinfo("智慧终端学习系统", "登录成功!欢迎开始学习!")


if __name__ == '__main__':
    root = Tk()
    root.title("测试Button")
    root.geometry("400x400+200+300")
    app = Application(master=root)
    root.mainloop()

运行结果:

利用 lambda 表达式实现传参

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

语法格式如下:

lambda 参数值列表:表达式

lambda 表达式的参数值列表可以为如下内容

实操代码:

from tkinter import Tk, Button

root = Tk()
root.geometry("270x50")


def mouseTest1():
    print("command 方式,简单情况:不涉及获取 event 对象,可以使用")


def mouseTest2(a,b):
    print("a={0},b={1}".format(a,b))


Button(root, text="测试 command1", command=mouseTest1).pack(side="left")
"""
lambda 定义的匿名函数也有输入、也有输出,只是没有名字。语法格式如下: lambda 参数值列表:表达式 参数值列表即为输入。 表达式计算的结构即为输出。
"""
Button(root, text="测试 command2", command=lambda: mouseTest2("实参1传入", "实参2传入")).pack(side="left")
root.mainloop()

结果展示:

Entry 单行文本框

Entry 用来接收一行字符串的控件. 如果用户输入的文字长度长于 Entry 控件的宽度时, 文字会自动向后滚动 如果想输入多行文本, 需要使用 Text 控件.

Entry构造函数如下图,  相关属性参数介绍见上面Options 选项详解部分图片:

实操代码:

"""
Entry 用来接收一行字符串的控件。如果用户输入的文字长度长于 Entry 控件的宽度时,
文字会自动向后滚动。如果想输入多行文本, 需要使用 Text 控件。
"""
# 【示例】Entry 单行文本框实现简单登录界面
from tkinter import *
from tkinter import messagebox


class Appliaction(Frame):
    def __init__(self, master):
        super().__init__(master)
        self.master = master
        self.pack()
        self.createWidget()

    def createWidget(self):
        """创建登录界面的组件"""
        self.label01 = Label(self, text="用户名")
        self.label01.pack()

        # StringVar 变量绑定到指定的组件
        # StringVar 变量的值发生变化,组件内容也变化;
        # 组件内容发生变化,StringVar 变量的值也发生变化
        v1 = StringVar()
        self.entry01 = Entry(self, textvariable=v1)
        self.entry01.pack()
        v1.set("admin")
        print(v1.get())
        print(self.entry01.get())

        # 创建密码框
        self.btn02 = Label(self, text="密码")
        self.pack()

        v2 = StringVar()
        self.entry02 = Entry(self, textvariable=v2, show="*")
        self.entry02.pack()

        Button(self, text="登录", command=self.login).pack()

    def login(self):
        title = "智慧终端学习系统"
        username = self.entry01.get()
        pwd = self.entry02.get()

        print("去数据库对比密码")
        print("用户名" + username)
        print("密码" + pwd)
        if username == "TimePause" and pwd == "123456":
            messagebox.showinfo(title, "登陆成功! 欢迎开始学习!")
        else:
            messagebox.showinfo(title, "登录失败, 用户名密码错误")


if __name__ == "__main__":
    root = Tk()
    root.title("智慧终端学习系统")
    root.geometry("400x130+200+300")
    app = Appliaction(master=root)
    root.mainloop()

结果展示:

Text 多行文本框

Text(多行文本框)的主要用于显示多行文本,还可以显示网页链接, 图片, HTML 页面, 甚至 CSS 样式表,添加组件等因此,也常被当做简单的文本处理器、文本编辑器或者网 页浏览器来使用。比如 IDLE 就是 Text 组件构成的。

Text 构造函数如下图,  相关属性参数介绍见上面Options 选项详解部分图片:

实操代码:

"""
Text(多行文本框)的主要用于显示多行文本,还可以显示网页链接, 图片, HTML 页面, 甚至 CSS 样式表,添加组件等。
因此,也常被当做简单的文本处理器、文本编辑器或者网 页浏览器来使用。比如 IDLE 就是 Text 组件构成的。
"""
from tkinter import *
import webbrowser


class Application(Frame):
    def __init__(self, master=None):   # 这里相当于java中定义了一个带参构造. master指代的是一个形参, 为后面创建类的对象时使用
        super().__init__(master)  # super()代表的是父类的定义,而不是父类对象
        self.master = master
        self.pack()
        self.createWidget()

    def createWidget(self):
        self.w1 = Text(root, width=40, height=12, bg="gray")  # 宽度 20 个字母(10 个汉字),高度一个行高
        self.w1.pack()
        self.w1.insert(1.0, "0123456789\nabcdefg")
        self.w1.insert(2.3, "锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦\n")

        Button(self, text="重复插入文本 ", command=self.insertText).pack(side="left")
        Button(self, text="返回文本", command=self.returnText).pack(side="left")
        Button(self, text="添加图片", command=self.addImage).pack(side="left")
        Button(self, text="添加组件", command=self.addWidget).pack(side="left")
        Button(self, text="通过 tag 精确控制文本 ", command=self.testTag).pack(side="left")

    def insertText(self):
        self.w1.insert(INSERT, ' 测试插入 ')    # INSERT 索引表示在光标处插入
        self.w1.insert(END, '测试尾插')         # END 索引号表示在最后插入
        self.w1.insert(1.8, "测试指定位置插入")     # Indexes(索引)是用来指向 Text 组件中文本的位置,Text 的组件索引也是对应实际字符之间的位置

    def returnText(self):
        print(self.w1.get(1.2, 1.6))
        print("所有文本内容:\n" + self.w1.get(1.0, END))  # 核心:行号以 1 开始 列号以 0 开始

    def addImage(self):
        global photo
        self.photo = PhotoImage(file="111.gif")
        self.w1.image_create(END, image=self.photo)

    def addWidget(self):
        b1 = Button(self.w1, text='创建一个新组件')  # 在 text 创建组件的命令
        self.w1.window_create(INSERT, window=b1)

    def webshow(self):
        webbrowser.open("http://www.baidu.com")

    def testTag(self):
        self.w1.delete(1.0, END)
        self.w1.insert(INSERT, "good good study,day day up!\n 测试 baidu\n Tag标签\n 精准控制文本")
        self.w1.tag_add("good", 1.0, 1.9)
        self.w1.tag_config("good", background="yellow", foreground="red")
        self.w1.tag_add("baidu", 4.1, 4.3)
        self.w1.tag_config("baidu", underline=True)
        self.w1.tag_bind("baidu", "<Button-1>", self.webshow)


if __name__ == '__main__':
    root = Tk()
    root.title("测试多行文本text")
    root.geometry("450x300+200+300")
    app = Application(master=root)
    root.mainloop()

结果展示:

Radiobutton 单选按钮

Radiobutton 控件用于选择同一组单选按钮中的一个, 可以显示文本,也可以 显示图像。

实操代码:

"""测试 Radiobutton 组件的基本用法,使用面向对象的方式"""
from tkinter import Frame, Radiobutton, Button, messagebox, Tk, StringVar


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

    def createWidget(self):     # 定义组件
        self.v1 = StringVar()
        self.v1.set("F")

        self.r1 = Radiobutton(self, text="男性", value="M", variable=self.v1)     # 定义单选框
        self.r2 = Radiobutton(self, text="女性", value="F", variable=self.v1)
        self.r1.pack(side="left")
        self.r2.pack(side="left")

        Button(self, text="确定", command=self.confirm).pack(side="left")

    def confirm(self):
        messagebox.showinfo("测试", "选择性别" + self.v1.get())   # 定义弹窗信息


if __name__ == '__main__':
    root = Tk()
    root.geometry("400x50+200+300")
    app = Application(root)
    root.mainloop()

结果展示:

Checkbutton 复选按钮

Checkbutton 控件用于选择多个按钮的情况.  可以显示文本,也可以显示图像。

实操代码:

"""测试 Checkbutton 组件的基本用法,使用面向对象的方式"""
from tkinter import Frame, IntVar, Checkbutton, Button, messagebox, Tk


class Application(Frame):
    # 创建构造方法
    def __init__(self, master=None):
        super().__init__(master)
        self.pack()
        self.createWidget()

    # 创建组件, 创建复选框并设置属性.
    def createWidget(self):
        self.codeHobby = IntVar()
        self.videoHobby = IntVar()

        self.c1 = Checkbutton(self, text="敲代码", variable=self.codeHobby, onvalue=1, offvalue=0)
        self.c2 = Checkbutton(self, text="看视频", variable=self.videoHobby, onvalue=1, offvalue=0)
        self.c1.pack(side="left")
        self.c2.pack(side="left")

        # 创建确定按钮并创建对象的提示框
        self.b = Button(self, text="确定", command=self.showInfo).pack(side="left")  # 这里command传入的是方法的对象

    def showInfo(self):
        if self.codeHobby.get() == 1 and self.videoHobby.get() == 1:
            messagebox.showinfo("提示框", "既爱看视频又爱学习, 来我这里学编程吧")
        elif self.codeHobby.get() == 1:       # IntVar需要调用get方法才能获得
            messagebox.showinfo("提示框", "你这个人爱学习编程啊, 学python吧")
        elif self.videoHobby.get() == 1:
            messagebox.showinfo("提示框", "你这个人比较爱看视频啊, 少看点")
        else:
            messagebox.showinfo("提示框", "啥都不爱啊, 随便选一个作为你的爱好吧")


# 启动方法以及相关组件信息
if __name__ == "__main__":
    root = Tk()
    root.geometry("400x50+200+300")
    app = Application(root)
    root.mainloop()

结果展示:

canvas 画布

canvas(画布)是一个矩形区域,可以放置图形、图像、组件等。

实操代码:

import random
from tkinter import Frame, Canvas, PhotoImage, Button, Tk


class Application(Frame):
    # 1. 初始化
    def __init__(self, master=None):
        super().__init__(master)
        self.pack()
        self.createWidget()

    def createWidget(self):
        # 2. 组件相关
        self.canvas = Canvas(self, width=300, height=200, bg="green")
        self.canvas.pack()
        # 画一条线
        line = self.canvas.create_line(10, 10, 30, 20, 40, 50)
        # 画矩形
        reat = self.canvas.create_rectangle(50, 50, 100, 100)
        # 画椭圆, 前后一对坐标为椭圆的边界矩形左上角和底部右下角
        oval = self.canvas.create_oval(50, 50, 100, 100)

        global photo
        photo = PhotoImage(file="111.gif")
        self.canvas.create_image(250, 250, image=photo)

        Button(self, text="来画10个矩形", command=self.draw10rect).pack(side="left")

    def draw10rect(self):
        for i in range(0, 10):
            x1 = random.randrange(int(self.canvas["width"]) / 2)
            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)


if __name__ == "__main__":
    root = Tk()
    root.geometry("400x300+200+300")
    app = Application(root)
    root.mainloop()

结果展示:

不同于之前的信徒, 大主教和大祭司实力更加强大, 而且被控制的程度更深. GSC事先进行了分工: 由导师GSC对付大主教, 而了不起对付大祭司. 而当面对真正的强者时, GSC才真正认真起来. 开启名为杀意波动的领域, 只见很大一片区域内, 包括了不起和大祭司所在的区域, 处在领域内的敌人行动明显变得迟缓, 并且眼神中的疯狂仿佛被压制了不少. 了不起赶紧抓住机会, 使用起最近学习到的突刺技能, 在奥菲利亚的增幅下, 命中领主. 大祭司受伤之后, 开始疯狂的召唤GBK教徒, 向其冲去. 然而在导师领域和奥菲利亚的增幅下, 不一会便将这些教徒击晕. 了不起毫不畏惧,步步为营. 近身战结合远程法术, 花费半天时间终于将其在丝血时击晕. 最后在奥菲利亚的净化魔法的帮助下, 大主教和大祭司都恢复了意识. 而他们脱口而出的第一句话, 便让了不起惊掉下巴...  

之间他们苏醒之后, 脱口而出的第一句话便是: 伟大的教主大人, 请原谅我等所犯下的罪行...什么? 原来了不起拯救的红发少女是GBK的教主. 在他们三者沟通完毕后, 奥菲利亚也略显歉意地向了不起解释道, 由于之前得知阿拉德大陆上的人都比较奸诈的, 担心我们图谋不轨, 因此没说明其真正身份. 在帮助大祭司和大神官接触控制之后, 明白了我们的伟人, 于是说明情况并请求我们的原谅. 而了不起的心里也有震惊中慢慢恢复, 在原谅了她之后便回到GBK外围住所从长记忆...而了不起由于这两天参与的高强度战斗与大批量敌人的遭遇, 竟然从lv17升到了lv20.

责任编辑:赵宁宁 来源: Python技术
相关推荐

2024-12-23 16:00:00

GUI编程tkinter

2024-12-23 14:54:47

2017-06-12 17:54:45

Python编程

2019-10-24 09:29:13

编程Python程序

2012-12-28 13:35:37

网络无线网络

2015-07-28 17:11:00

编程技术提升

2023-11-30 15:02:34

Python

2023-11-27 19:42:56

Python GUI编程

2009-09-08 14:30:57

CCNA认证考试

2016-10-31 20:13:41

大数据数据分析

2024-04-28 09:28:49

2019-07-23 18:15:26

技术大数据数据库

2021-08-31 15:56:06

编程技能开发

2009-06-10 18:18:43

Java GUI用户界面

2023-05-09 08:24:13

PythonTkinterGUI编程

2023-07-31 22:02:17

客服订单详情

2009-03-10 10:49:28

2018-07-05 08:51:02

Linux 系统 数据

2014-07-26 15:11:20

WOT2014自动化运维

2023-11-22 18:58:33

广告计费系统
点赞
收藏

51CTO技术栈公众号