Python的门面担当

在大多数时候,我们都在黑黢黢的控制台里执行 Python 脚本。这看起来很酷很 GEEK。但对于部分场景下的用户来说,这样就不大美观和人性化了:我们需要交互更方便的图形化产品,也就是 GUI(图形用户界面,Graphical User Interface)。

Python 有很多可实现 GUI 的库,在之前的文章中有过一个整理:如何用 GUI 提高 python 程序的颜值? 但没有针对某个具体的库做介绍。最近有同学提到希望给讲解下 GUI 的开发,那么今天就来做个简单的“快速上手”。

而我们要介绍的库,就是

Tkinter

相比较其他的 GUI 库,Tkinter 有个优势在于,它是 Python 内置的 GUI 库,无需另行安装,省事了一点点。另外如果你要将开发出的程序打包成 exe,它也比第三方库稍稍更容易一点点。

而功能上,Tkinter 已足够处理大多数小型 GUI 程序的需求。其开发的程序在各主流操作系统上均可运行。Python 的内置编辑器 IDLE 就是使用 Tkinter 开发的。因此,我个人在之前的开发中,是将 Tkinter 作为首选。

(当然,PyQt 也是很强大的 GUI 库,可以做出复杂酷炫的界面效果。而原有 QT 开发经验的人更是很容易上手。)

Hello GUI World

我们从一个最简单的 Tkinter GUI 程序说起:

import tkinter as tk
root = tk.Tk()
root.mainloop()

1.创建一个 Tk 窗口对象;2.调用这个对象的消息主循环。一个窗口就出现了。在这个窗口之上,可以添加各种输入框、按钮、文本等,可以增加对各种动作的处理。

以往我们写的程序(比如猜数字、罚点球、查天气等)大多是有一个固定的执行流程。而 GUI 程序的不同之处在于,通常它们是由“事件驱动”的:程序运行后,相当于进入一个循环一直运行。如果你不做任何操作,这个窗口就一直在这里。看起来是静止的,但程序实际上是在等待你的操作:通过与窗口中的“控件”进行交互,比如点击按钮、输入文字、勾选选项等,产生不同的“事件”,程序再根据预设的“响应”做处理。就算要结束程序,也是通过“关闭窗口”和“退出”事件。

这就是 mainloop 的意义所在:监听各种事件。理解了这一点,也就理解了 GUI 程序的基本逻辑。

控件

所谓控件,就是 GUI 图形化界面上的对象,或者说功能元素。比如输入框、文本框、按钮、下拉菜单、滚动条等等,窗体本身也可以认为是一个控件。一个控件包含了数据和操作,决定了页面上的元素放在哪里、长什么样、有什么样的效果。

举几个 Tkinter 常用控件的例子:

label = tk.Label(root, text="Hello, world!")
label.pack()
btn = tk.Button(root, text="OK")
btn.pack()
entry = tk.Entry(root)
entry.pack()
root.mainloop()

在调用 mainloop 前,增加了 Label(文本标签)、Button(按钮)、Entry(输入框)三个控件,通过 pack() 方法把它们添加到了窗口之上。

Tkinter 有 15 个核心控件,每个控件有多种设置,这里不展开介绍,网上可以很容易搜到详细的文档说明。

另外除了这些基本控件之外,Tkinter 还提供了一个 ttk 模块,增加了几个控件并对部分已有控件进行了优化。例如:

from tkinter import ttk
entry = ttk.Entry(window)
entry.pack()
combo = ttk.Combobox(window)
combo['values'] = ('IDLE', 'PyCharm', 'VSCode', 'SublimeText')
combo.pack()

完整示例代码在文末附上。

对于控件属性的设置,有 3 种方法:

  1. 创建时通过参数设置。如 btn = Button(root, text="Click", fg="red", bg="blue", command=click)
  2. 通过字典的方式修改。如 btn["fg"] = "green"
  3. 通过 config 函数修改。如 btn.config(fg="green", bg="yellow")

布局

如果只是简单的用 pack() 方法将控件添加到窗口上,它们将按顺序从上往下的放置。这显然无法满足复杂的需求。

Tkinter 提供了三种布局方式:

1. Pack

pack 是最简单的布局管理方式,除了像我们前面直接调用外,可以加上 fill、padx、pady、ipadx、ipady、side 等参数,调整放置的边距、填充方式、对齐方式等。

btn.pack(fill=tk.X, padx=5, pady=20, side=tk.LEFT)

2. Place

用 place 替代 pack,可以精确地指定空间的放置坐标及长宽。

btn.place(x=50, y=100, width=120, height=25)

3. Grid

Grid 布局的逻辑在于,将窗口像表格一样划分成不同的格子,将控件放置进去。例如:

当控件数量众多时,这种布局方式更有条理。

btn.grid(row=1, column=0)

顺便提一句,如果你希望可以像 VB 那样所见即所得地设计窗体控件,可以了解下 Visual Tkinter 这个工具。

事件

前面说的都是外在的形式,一个 GUI 程序要能运行,离不开内部的事件响应。即:当用户做了一个操作,程序要做出怎样的反应。

事件要与特定的控件相绑定,比如按钮有点击事件,输入框有按键事件,窗体有关闭事件等。

常用的 2 种绑定方法:

1. command

通过控件的 command 参数指定响应函数:

def onClick():
    print('clicked!')

btn = Button(root, text='click', command=onClick)

注意这里传递参数时,onClick 后面不能加上括号。(思考下加与不加的区别在哪里?)

2. bind

通过 bind 方法绑定不同的事件:

def onButton(event):
    print("Clicked:", event.x, event.y)

def onKey(event):
    print("Pressed", event.char)

entry.bind('<Button-1>', onButton)
entry.bind('<Key>', onKey)

控件、布局、事件响应,就是 GUI 开发的几个重要部分。对此有了整体认识后,剩下的就是查阅相关文档和练习了。

如果有不理解的部分或想要深入了解的细节问题,可以在我们的论坛 bbs.crossincode.com 上发帖讨论,或在知识星球上提问。

运用上述内容,我们把课程最初的猜数字游戏改成一个 GUI 版本。

获取详细代码,请在公众号(Crossin的编程教室)里回复关键字 GUI

【课后作业】实现一个简单的 GUI 程序,猜数字或者一个简单的登录框、一个小计算器等等,可以用 Tkinter,也可以用其他 GUI 库。欢迎留言你的代码,或发在论坛上。

下课!

原文发布于微信公众号 - Crossin的编程教室(crossincode)

原文发表时间:2018-09-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Danny的专栏

&nbsp在IE和FireFox中显示不一致

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

983
来自专栏乐百川的学习频道

用WPF做一个简易浏览器

微软的WPF(Windows Presentation Foundation)是目前Windows平台上最好用的图形界面框架了。如果想在Windows平台上编写...

3425
来自专栏林德熙的博客

win10 uwp win2d 入门 看这一篇就够了

本文主要翻译,可能带有一定的主观性和局限性,说的东西可能不对或者不符合每个人的预期。如果觉得我有讲的不对的,就多多包含,或者直接关掉这篇文章,但是请勿生气或者发...

1592
来自专栏企鹅号快讯

常见的前端面试题,总有一点让你涨知识

首先在面试时,我会大声说:"本人擅长Ai、Fw、Fl、Br、Ae、Pr、Id、Ps等软件的安装与卸载,精通CSS、PHP、ASP、C、C++、C#、Java、R...

2277
来自专栏用户2442861的专栏

Chrome开发者工具不完全指南:(三、性能篇)

 卤煮在前面已经向大家介绍了Chrome开发者工具的一些功能面板,其中包括Elements、Network、Resources基础功能部分和Sources进阶功...

1412
来自专栏搞前端的李蚊子

基于Vue.js的大型报告页项目实现过程及问题总结(二)

距离上一篇文章过去了二十多天了,期间一直想把第二部分写完,结果在测试过程中遇到了各种坑爹的问题,到今天才算基本完成,也许还有后续,但趁着今天有时间就写出来吧,也...

44810
来自专栏河湾欢儿的专栏

React入门

React 是一个用于构建用户界面的 JAVASCRIPT 库。 起源: React 起源于 Facebook 的内部项目,因为该公司对市场上所有 Java...

1431
来自专栏转载gongluck的CSDN博客

MFC ActiveX (ocx)控件的开发

前言 ActiveX是Microsoft对于一系列策略性面向对象程序技术和工具的称呼,其中主要的技术是组件对象模型(COM)。 ActiveX控件是一种实现...

7617
来自专栏理论坞

那些你不知道的Photoshop冷知识⑤——CC2015评测专题

笔者在探索新版本时,首先注意的便是首选项的变化,可以发现这次更新之后首选项侧边栏多了不少东西,点进去之后才发现原来是进行了重新分类,那么有哪些好玩的功能呢?介绍...

864
来自专栏QQ会员技术团队的专栏

深入理解React(二) :数据流和事件原理

在React中,数据流是自上而下单向的从父节点传递到子节点,所以组件是简单且容易把握的,他们只需要从父节点提供的props中获取数据并渲染即可。如果顶层组件的某...

4.6K0

扫码关注云+社区

领取腾讯云代金券