如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/X5cqennLrq7i1pzBAAqQ2w

本文大概 2562 个字,阅读需花 15 分钟
内容不多,但也花了一些精力
如要交流,欢迎关注我然后评论区留言
谢谢你的点赞收藏分享

​这篇文章属于系列文章《Python 内置界面开发框架 Tkinter入门篇》的第四篇,也是最后一篇,上接《Python 内置界面开发框架 Tkinter入门篇 丙》,欢迎关注我的微信公众号「ENG八戒」查看这个系列相关文章,也可以翻到文章底部查看整个系列的文章集合。

实现一个简单的记事本应用

前面说了这么多,用句流行语来概括就是 「散装知识点」。为了串联起来有个全面的体会,下面让我们一起来实现一个简单的记事本程序吧!

产品定义

作为一个产品的开发来看的话,我们需要清楚地知道自己到底想要的产品是长什么样子,然后才是实现的过程。

我们打算做一个基本的记事本,它可以点击按键打开 TXT 格式的文本文件,把文件内容读取出来显示在编辑区,然后在编辑区修改了文件内容后,又可以点击其它按键把编辑区的内容另存为其它文本文件。

按照上面的功能需求定义,就可以给记事本定个草图啦,长这样

可以看到,它需要先有个主窗口

import tkinter as tk

window = tk.Tk()
window.mainloop()

然后,应该有个标题栏,上面显示有软件名称 「记事本」

import tkinter as tk

window = tk.Tk()
window.title("记事本")
window.mainloop()

从草图来看,它还需要功能按钮区域和文本编辑区,可以使用 grid 布局管理器来划分区域。总体可以划分为 1 行 2 列,第 1 列是功能按钮区域,第 2 列是文本编辑区;第 1 行第 1 列也就是功能按钮区域,又可以划分为 2 行 1 列,第 1 行是按钮打开,第 2 行是按钮另存。

好了,这就是我们这个产品的初步定义。

UI实现

对界面布局做好划分之后,就开始添加控件代码了

import tkinter as tk

window = tk.Tk()
window.title("记事本") btn_frame = tk.Frame(
master=window,
bd=2
)
btn_open = tk.Button(
master=btn_frame,
text="打开"
)
btn_save_as = tk.Button(
master=btn_frame,
text="另存"
) btn_open.grid(row=0, column=0)
btn_save_as.grid(row=1, column=0)
btn_frame.grid(row=0, column=0) txt_edit = tk.Text(master=window)
txt_edit.grid(row=0, column=1) window.mainloop()

显示是这样

看起来已经和草图很接近了,不过按钮的布局还是需要调整,位置应该处于所属列的顶部,而且按钮太靠边了。还有,窗体在拉伸之后,控件也没有跟随变化。这几个问题怎么修复呢?

为了将按钮置顶,可以对控件 btn_frame 应用上下拉满,sticky 设为 "ns"。

而按钮太靠边,可以通过修改填充属性 padding,比如 padx=5, pady=5 让控件的边框收缩 5 个像素,保持距离感。

而编辑框控件没有跟随窗体一起拉伸,是因为控件 txt_edit 还需要设置所有边框靠着边界,比如 sticky 设为 "nsew" 即可。

看看修改后的代码

import tkinter as tk

window = tk.Tk()
window.title("记事本") window.rowconfigure(
0,
minsize=100,
weight=1
)
window.columnconfigure(
1,
minsize=100,
weight=1
) btn_frame = tk.Frame(
master=window,
bd=2
)
btn_open = tk.Button(
master=btn_frame,
text="打开"
)
btn_save_as = tk.Button(
master=btn_frame,
text="另存"
) btn_open.grid(
row=0,
column=0,
sticky="ew",
padx=5,
pady=5
)
btn_save_as.grid(
row=1,
column=0,
sticky="ew",
padx=5
)
btn_frame.grid(
row=0,
column=0,
sticky="ns"
) txt_edit = tk.Text(master=window)
txt_edit.grid(
row=0,
column=1,
sticky="nsew"
) window.mainloop()

跑起来试一下

OK ! UI 界面视觉效果达到预期了。

逻辑功能

下一步就是补充逻辑功能,让记事本能读写文本文件。

先看怎么实现打开逻辑。

理一下思路: 点击按钮「打开」,程序就会弹出选取文件的窗口,选中文件后点击确定就返回选中的文件路径,然后按照文件路径把文件内容读取出来并且显示到编辑框中。另外,为了让用户知道最终显示的内容来自哪个文件,所以可以把文件路径添加到窗口的标题栏最前面。看怎么修改代码

...

def open_file():
file_path = filedialog.askopenfilename(
filetypes=[
("Text files", "*.txt"),
("All files", "*.*")
]
)
if not file_path:
window.title("无标题 - 记事本")
return
window.title(f"{file_path} - 记事本")
txt_edit.delete("1.0",
tk.END)
with open(
file_path,
mode="r",
encoding="utf-8") as input_file:
txt_edit.insert(
tk.END,
input_file.read()
) ... btn_open = tk.Button(
master=btn_frame,
text="打开",
command=open_file
) ...

上面代码的修改点是添加了一个响应函数 open_file,这个函数用于打开文本文件并读取文件内容显示,然后在实例化按钮控件 btn_open 时,把响应函数 open_file 赋值给参数 command 即可。

为了测试记事本的显示文本内容功能,我们先手动在桌面创建一个文本文件 test.txt,然后输入内容并保存

这是测试文本文件
...

运行一下程序,然后点击「打开」按钮,选中刚刚创建的文件 test.txt 并打开

可见读取文本内容的目标功能基本达成,再看怎么实现另存逻辑。

理一下思路: 点击按钮「另存」,程序就会弹出选择保存文件的路径的窗口,选中路径后点击确定就返回选中的路径,然后按照路径把编辑框中的内容保存为文件。另存后,窗口标题栏也需要相应改变。看怎么修改代码

...

def save_as_file():
file_path = filedialog.asksaveasfilename(
defaultextension=".txt",
filetypes=[
("Text files", "*.txt"),
("All files", "*.*")
]
)
if not file_path:
return
with open(
file_path,
mode="w",
encoding="utf-8") as output_file:
output_file.write(txt_edit.get("1.0",
tk.END))
window.title(f"{file_path} - 记事本") ... btn_save_as = tk.Button(
master=btn_frame,
text="另存",
command=save_as_file
) ...

上面代码的修改点是添加了一个响应函数 save_as_file,这个函数用于选择另存文件位置并把编辑框内容写入指定位置文件,然后在实例化按钮控件 btn_save_as 时,把响应函数 save_as_file 赋值给参数 command 即可。

为了测试记事本的文件另存功能,我们先用我们最新修改的记事本程序打开上面手动创建的文本文件 test.txt,然后在编辑框把内容修改一下

点击「另存」按钮,弹出「另存为」文件窗口,找到保存位置并输入新文件名 test_save_as.txt,最后点击「保存」。

另存完毕后,窗口标题内容变成了新文件路径。

好了,一个简单的记事本程序就这样完成了。希望上面的内容能打开你的思路!

打包部署

关于 python 输出独立可执行应用的介绍,其实和用什么 GUI 框架无关,可直接参考一下我的另一篇文章《Python:界面开发,wx入门篇》里的相关介绍。


由于篇幅受限,系列文章《Python 内置界面开发框架 Tkinter入门篇》分成了下面几个部分,有兴趣的朋友可点击跳转查阅

《Python 内置界面开发框架 Tkinter入门篇 甲》

《Python 内置界面开发框架 Tkinter入门篇 乙》

《Python 内置界面开发框架 Tkinter入门篇 丙》

《Python 内置界面开发框架 Tkinter入门篇 丁》


如需要完整示例代码,可前往 github 仓库获取: git@github.com:ifi-leung/python_gui_tkinter.git


这里预告一下,本公众号 ENG八戒 的荐书活动马上来临,为了鼓励大家多读书,所以会有免费送图书的名额哦!

Python 内置界面开发框架 Tkinter入门篇 丁的更多相关文章

  1. Python 内置界面开发框架 Tkinter入门篇 丙(文末有福利彩蛋,今天可是元宵节)

    以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/B1hH5Qzd2RkAiiUId1tLWw 本文大概 2874 个字 ...

  2. Python 内置界面开发框架 Tkinter入门篇

    本文大概 4158 个字,阅读需花 10 分钟 内容不多,但也花了一些精力 如要交流,欢迎关注我然后评论区留言 谢谢你的点赞收藏分享 首先,今天先给大家拜个好年!新年快乐,恭喜发财!为了感谢大家对我的 ...

  3. Python 内置界面开发框架 Tkinter入门篇 乙

    本文大概 1685 个字,阅读需花 6 分钟内容不多, 但也花了一些精力如要交流, 欢迎关注我然后评论区留言 谢谢你的点赞收藏分享 这篇文章属于系列文章<Python 内置界面开发框架 Tkin ...

  4. Python内置函数详解——总结篇

    2个多月来,将3.5版本中的68个内置函数,按顺序逐个进行了自认为详细的解析,现在是时候进行个总结了.为了方便记忆,将这些内置函数进行了如下分类:     数学运算(7个)     类型转换(24个) ...

  5. Python内置GUI模块Tkinter的几点笔记

    组件属性,用法 组件位置 更多

  6. Python内置函数详解-总结篇

    参考链接:http://www.cnblogs.com/sesshoumaru/p/6140987.html

  7. Python入门之 Python内置函数

    Python入门之 Python内置函数 函数就是以功能为导向,一个函数封装一个功能,那么Python将一些常用的功能(比如len)给我们封装成了一个一个的函数,供我们使用,他们不仅效率高(底层都是用 ...

  8. 浅谈Python内置对象类型——数字篇(附py2和py3的区别之一)

    Python是一门面向对象的编程设计语言,程序中每一样东西都可以视为一个对象.Python内置对象可以分为简单类型和容器类型,简单类型主要是数值型数据,而容器类型是可以包含其他对象类型的集体,如序列. ...

  9. Python基础篇【第2篇】: Python内置函数(一)

    Python内置函数 lambda lambda表达式相当于函数体为单个return语句的普通函数的匿名函数.请注意,lambda语法并没有使用return关键字.开发者可以在任何可以使用函数引用的位 ...

  10. Python之路(第八篇)Python内置函数、zip()、max()、min()

    一.python内置函数 abs() 求绝对值 例子 print(abs(-2)) all() 把序列中每一个元素做布尔运算,如果全部都是true,就返回true, 但是如果是空字符串.空列表也返回t ...

随机推荐

  1. selenium被某些网页检测不允许正常访问、登录等,解决办法

    网站通过什么方式检测 function b() { return "$cdc_asdjflasutopfhvcZLmcfl_"in u || d.webdriver } 通过上方的 ...

  2. 关于python3格式化字符输出的问题

    前言 今天简答写了一个爬虫,利用 % 格式化输出总是有问题 第一种写法: url = 'https://yysygw.res.netease.com/pc/gw/20190826151318/data ...

  3. 第五章:matplotlib水印和桑基图

    1.Matplotlib水印 1 import matplotlib.pyplot as plt 2 import numpy as np 3 4 x = np.linspace(0.0,10,40) ...

  4. 【数据库】Oracle建表、创建序列、添加触发器生成自增主键

    CREATE TABLE "TEST"."T_ORDER" (    "AUUID_0" VARCHAR2 ( 255 ) NOT NULL ...

  5. 微服务组件-----Spring Cloud Alibaba 注册中心Nacos的CP架构Raft协议分析

    前言 本篇幅是继  注册中心Nacos源码分析 的下半部分. 意义 [1]虽说大部分我们采用注册中心的时候考虑的都是AP架构,为什么呢?因为性能相对于CP架构来说更高,需要等待的时间更少[相对于CP架 ...

  6. PHP 视频源文件加密方案

    先说下原理:因为视频是付费的,肯定需要作视频加密处理. 加密可实现的方式:修改视频字节流,只能替换字节流,例如头100-1024字节进行加密,源文件就无法打开了. 下面上代码吧,加解密是 openss ...

  7. 常用内置模块os sys json

    今日内容回顾 目录 今日内容回顾 os模块 sys模块 json模块 json模块实战 os模块 sys模块 json模块 os模块 os模块主要与代码运行的操作系统打交道 1.创建目录(文件夹) i ...

  8. 定制.NET 6.0的Middleware中间件

    大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 在本文中,我们将学习中间件,以及如何使用它进一步定制应用程序.我们将快速学习中间件 ...

  9. [0x12] 132.小组队列

    题意 link(more:UVA540) 简化题意:对 \(n\) 个小组排队,每个小组有至多 \(m\) 个成员(每个成员有唯一编号 \(x\)),当一个人来到队伍时,如果队中有同组成员,直接插入其 ...

  10. java定时任务Quartz整理

    目录 一.Quartz介绍 二.Quartz的组成 三.使用java实现一个简单的Quartz例子 四.使用Springboot整合Quartz定时任务框架 五.使用Springboot+mybati ...