【Python】使用tkinter设计开发Windows桌面程序记事本(2)

news2024/12/25 10:04:31

上一篇:【Python】使用tkinter设计开发Windows桌面程序记事本(1)-CSDN博客

下一篇:

作者发炎

此代码模块是继承上一篇文章的代码模块的基础上开始设计开发的。

如果不知道怎么新建"记事本项目"文件夹,请参考上一篇文章,在此我不在复述。

在本篇文章主要完成了改变编辑区字体大小、右侧上下滑块滑动、底侧左右滑块滑动、显示光标在编辑区的位置、以及底部状态栏显示数据更新。

设计步骤

在"记事本项目"文件夹的"code"目录下新建本文章要设计开发的代码模块文件"记事本功能设计_1.py",如下图:

运行结果

代码示例:记事本功能设计_1.py

"""
    记事本功能设计

不足:
    1.底部状态栏的字体缩放百分比不是±10%,因为默认10号字体太小了,所以我选择了12号字体大小
    2.底部状态栏不能识别编辑内容编码格式,所以一直是UTF-8

"""

# 通配符 "*"
__all__ = ['Notepad_1', 'FONT_SIZE']

# 导入内置模块
import tkinter as tk
from tkinter import font

# 导入"记事本底座"模块
from 记事本项目.code.记事本底座 import Notepad_base


# 全局变量
# 初始化
FONT_SIZE = 12      # 默认字体大小


class Notepad_1(Notepad_base):
    """ 继承Notepad_base, 设计记事本功能 """
    def __init__(self):
        """ 重写父类的构造方法 """
        # 调用父类的构造方法
        super().__init__()

        """ 开始对记事本功能进行设计 """

        # 设置文本域与右侧和底部滚动条关联
        self.text.config(wrap="word", xscrollcommand=self.bottomScrollbar.set, yscrollcommand=self.rightScrollbar.set)
        # 底侧滚动条与文本域关联
        self.bottomScrollbar.config(command=self.text.xview)
        # 右侧滚动条与文本域关联
        self.rightScrollbar.config(command=self.text.yview)
        # 隐藏底侧滚动条(让其默认勾选上自动换行)
        self.bottomScrollbar.pack_forget()

        # 设置文本域编辑字体样式,以及字体大小
        self.fontSize = tk.IntVar(value=FONT_SIZE)
        self.setFont = font.Font(family='Tahoma', size=self.fontSize.get())
        self.text.config(font=self.setFont)


        # 捆绑事件,获取Text文本的光标位置
        self.text.bind('<KeyPress>', self.cursorPosition)  # 键盘按下触发
        self.text.bind('<KeyRelease>', self.cursorPosition)  # 键盘释放触发
        self.text.bind('<ButtonPress>', self.cursorPosition)  # 鼠标按下触发
        self.text.bind('<ButtonRelease>', self.cursorPosition)  # 鼠标释放触发
        # 自定义注册事件
        # self.text.event_add('<<CursorEvent>>', *('<KeyPress>', '<KeyRelease>', '<ButtonPress>', '<ButtonRelease>'))
        # self.text.bind('<<CursorEvent>>', self.cursorPosition)

        # 文本域字体大小捆绑事件
        self.threeViewMenu.entryconfigure(0, command=lambda: self.FontSizeEvent('放大'))
        self.threeViewMenu.entryconfigure(1, command=lambda: self.FontSizeEvent('缩小'))
        self.threeViewMenu.entryconfigure(2, command=lambda: self.FontSizeEvent('默认缩放'))
        # 自定义注册缩放事件('<<ZoomEvent>>')
        self.event_add('<<ZoomEvent>>',*('<Control-MouseWheel>','<Control-Key-=>','<Control-Key-+>','<Control-minus>','<Control-Key-0>'))
        # 捆绑自定义注册缩放事件改变字体大小
        self.bind('<<ZoomEvent>>', self.FontSizeEvent)  # 鼠标上滚缩小,下滚放大


        # 文本域输入自动换行显隐捆绑事件
        self.formatMenu.entryconfigure(0, command=self.setWord_wrap)
        # 文本域底部状态栏显隐捆绑事件
        self.viewMenu.entryconfigure(1, command=self.setState)


    # 状态栏:更新字体大小百分比
    def FontSizeEvent(self, event):
        # 菜单调整字体大小
        if event == '放大':
            self.event_generate('<Control-Key-+>')  # 引起键盘触发事件
            return
        elif event == '缩小':
            self.event_generate('<Control-minus>')  # 引起键盘触发事件
            return
        elif event == '默认缩放':
            self.event_generate('<Control-Key-0>')  # 引起键盘触发事件
            return

        # 快捷键调整字体大小
        # 向下滚动
        if event.delta < 0 or event.keysym == 'minus':
            # 字体大小范围
            if self.fontSize.get() <= 1:
                return
            # 缩小字体
            self.fontSize.set(self.fontSize.get() - 1)
            print('向上滚动,字体大小:', self.fontSize.get())
        # 向上滚动
        else:
            # 字体大小范围
            if self.fontSize.get() >= FONT_SIZE * 5:
                return
            # 放大字体
            self.fontSize.set(self.fontSize.get() + 1)
            # 恢复默认缩放
            if event.keysym == '0':
                self.fontSize.set(FONT_SIZE)
            print('向下滚动,字体大小:', self.fontSize.get())

        # 改变字体大小
        self.setFont.config(size=self.fontSize.get())
        # 改变底部显示字体大小百分比
        self.fontSizeLabel.config(text='{:.0%}'.format(self.fontSize.get() / FONT_SIZE))


    # 状态栏:获取Text光标位置
    def cursorPosition(self, event):
        row, column = event.widget.index("insert").split(".")
        print("光标位置:行", row, "列", int(column) + 1)
        self.locationLabel.config(text=f'  第 {row} 行,第 {int(column) + 1} 列')


    # 勾选自动换行显示与否
    def setWord_wrap(self, event=None):
        # 设置自动换行
        if self.word_wrap.get():
            # 自动换行设置
            self.text.config(wrap='word')
            # 移除底部水平滑动条
            self.bottomScrollbar.pack_forget()
            # 底部框架没有组件显示时移除
            if not self.state.get():
                self.bottomFrame.pack_forget()
        # 设置取消自动换行
        else:
            # 先移除右侧滚动条,再显示
            self.rightScrollbar.pack_forget()
            # 先移除中间文本域,再显示
            self.text.pack_forget()
            # 显示底部框架
            self.bottomFrame.pack(side=tk.BOTTOM, fill='both')
            # 取消自动换行设置
            self.text.config(wrap='none')
            # 显示底部水平滑动条
            self.bottomScrollbar.pack(fill='both')
        # 再显示右侧滚动条
        self.rightScrollbar.pack(side=tk.RIGHT, fill='both')
        # 再中间文本域
        self.text.pack(expand=True, fill='both')


    # 勾选底部状态栏显示与否
    def setState(self, event=None):
        # 底部显示状态栏
        if self.state.get():
            # 先移除右侧滚动条,再显示
            self.rightScrollbar.pack_forget()
            # 先移除中间文本域,再显示
            self.text.pack_forget()
            # 显示底部框架
            self.bottomFrame.pack(side=tk.BOTTOM, fill='both')
            # 显示状态栏
            self.stateFrame.pack(side=tk.BOTTOM, fill='both')
        # 底部移除状态栏
        else:
            # 移除状态栏
            self.stateFrame.pack_forget()
            # 底部框架没有组件显示时移除
            if self.word_wrap.get():
                self.bottomFrame.pack_forget()
        # 再显示右侧滚动条
        self.rightScrollbar.pack(side=tk.RIGHT, fill='both')
        # 再中间文本域
        self.text.pack(expand=True, fill='both')


# 代码测试
if __name__ == '__main__':
    ui = Notepad_1()    # 实例化记事本UI
    ui.mainloop()       # 循环窗口运行
else:
    print(f'导入【{__name__}】')

作者:周华

创作日期:2024/1/10

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1372577.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

程序员试用期转正工作总结

一、试用期工作总结 在公司的三个月试用期中&#xff0c;我完成了以下工作&#xff1a; 完成了XX个功能模块的开发&#xff0c;包括XX模块、XX模块和XX模块。参与了XX个项目的开发和上线&#xff0c;其中XX项目、XX项目和XX项目是我主导的。优化了现有系统的性能&#xff0c;特…

跟着我学Python进阶篇:02.面向对象(上)

往期文章 跟着我学Python基础篇&#xff1a;01.初露端倪 跟着我学Python基础篇&#xff1a;02.数字与字符串编程 跟着我学Python基础篇&#xff1a;03.选择结构 跟着我学Python基础篇&#xff1a;04.循环 跟着我学Python基础篇&#xff1a;05.函数 跟着我学Python基础篇&#…

计算机体系结构----寄存器重命名/Tomasulo算法

前情提要 计分板算法可看我写的博文计算机体系结构----计分板&#xff08;scoreboard&#xff09;算法 Tomasulo算法的核心是寄存器重命名&#xff08;register renaming&#xff09;&#xff1b;通过寄存器重命名&#xff0c;可彻底消除WAR/WAW冲突&#xff0c;计分板算法中…

2024--Django平台开发-Django知识点(五)

day05 django知识点 今日概要&#xff1a; 中间件 【使用】【源码】cookie 【使用】【源码 - Django底层请求本质】session【使用】【源码 - 数据库请求周期中间件】 1.中间件 1.1 使用 编写类&#xff0c;在类型定义&#xff1a;process_request、process_view、process_…

C++重新认知:inline关键字

一、为什么要使用inline关键字 在C中.&#xff0c;为了解决频繁调用小函数造成大量消耗栈空间的问题&#xff0c;引进了inline关键字&#xff0c;inline修饰的函数为内敛函数&#xff08;频繁大量的使用栈空间会造成栈溢出&#xff09;。 在这段代码中&#xff0c;每次执行for…

RT-Thread:SPI万能驱动 SFUD 驱动Flash W25Q64,通过 STM32CubeMX 配置 STM32 SPI 驱动

关键词&#xff1a;SFUD,FLASH,W25Q64&#xff0c;W25Q128&#xff0c;STM32F407 说明&#xff1a;RT-Thread 系统 使用 SPI万能驱动 SFUD 驱动 Flash W25Q64&#xff0c;通过 STM32CubeMX 配置 STM32 SPI 驱动。 提示&#xff1a;SFUD添加后的存储位置 1.打开RT-Thread Sett…

【obj To 3DTiles 格式转换】 可以自定义经纬高、属性表等参数 (一)

目录 0 引言1 3DTiles数据2 objTo3DTiles2.1 工具的安装2.1.1 拓展&#xff1a;Node.js 和 npm 2.2 工具的使用2.2.1 输出成瓦片数据2.2.2 输出带有坐标参数的瓦片数据 3 查看3DTiles数据 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;Cesiumfor…

强化学习9——免模型预测算法介绍(蒙特卡洛方法和时步差分方法)

对于大部分情况来说&#xff0c;环境是未知的&#xff0c;也就是说状态转移概率未知&#xff0c;对于这种情况的算法称为免模型预测算法。免模型算法与环境不断交互学习&#xff0c;但是需要大量的运算。 蒙特卡洛方法 蒙特卡罗方法通过重复随机抽选&#xff0c;之后运用统计…

条款21:必须返回对象时,别妄想返回其引用

考虑一个表示有理数的类&#xff0c;其中包含一个计算两个有理数相乘的函数: class Rational { public:Rational(int numerator 0, int denominator 1) :n{ numerator }, d{ denominator }{} private:int n, d; // 分子和分母friend const Rational& operator*(const R…

vue知识-03

购物车案例 要实现的功能&#xff1a; 1、计算商品总价格 2、全选框和取消全选框 3、商品数量的增加和减少 <body> <div id"app"><div class"row"><div class"col-md-6 col-md-offset-3"><h1 class"text-center…

C++模板——(4)C++泛型编程与标准模板库简介

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 勤奋&#xff0c;机会&#xff0c;乐观…

苍穹外卖Day01——解决总结1中存在的问题

前序章节&#xff1a; 苍穹外卖Day01——总结1 解决总结1中存在的问题 1. 什么是JWT2. POJO、Entity、VO、DTO3. Nginx&#xff08;反向代理&#xff09;4. Data注解 1. 什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一种用于在网络应用间传递信息的开放标准&#…

智慧校园电子班牌管理系统源码 Java Android原生

智慧校园电子班牌系统源码是一种智能化的教育管理解决方案&#xff0c;它可以在学校内实现信息共享、教学管理、学生管理、家校互通等各个方面的协调与配合&#xff0c;帮助教师、学生和家长更加高效地开展教学活动、管理学生、协同合作&#xff0c;从而推动学校教育水平的提高…

【高等数学之泰勒公式】

一、从零开始 1.1、泰勒中值定理1 什么是泰勒公式?我们先看看权威解读: 那么我们从古至今到底是如何创造出泰勒公式的呢? 由上图可知&#xff0c;任一无穷小数均可以表示成用一系列数字的求和而得出的结果&#xff0c;我们称之为“无穷算法”。 那么同理我们想对任一曲线来…

Ubuntu启动Xming报错:cannot open display: :1.0

Ubuntu启动Xming报错&#xff1a;cannot open display: :1.0 1、问题描述&#xff1a;2、问题解决&#xff1a;3、实践结果&#xff1a; 叮嘟&#xff01;这里是小啊呜的学习课程资料整理。好记性不如烂笔头&#xff0c;今天也是努力进步的一天。一起加油进阶吧&#xff01; 1、…

Android 事件分发介绍

文章目录 一、目的二、环境三、相关概念3.1 事件分发 四、详细设计4.1应用布局4.1.1 应用布局结构4.1.2 LayoutInspector 4.2 关键View&方法4.2.1 相关View4.2.2 相关方法4.2.3 View与方法关系 4.3 事件分发概念图4.3.1 事件分发类图4.3.2 事件分发模型图 4.4 Activity组件…

C#编程-描述异常

描述异常 异常是在程序执行期间出现的错误。异常情况发生在运算不能正常完成的时候。当程序中出现异常是,系统会抛出错误。错误通过异常处理过程被处理。 例如,System.IO.IOException异常在试图访问非法流对象时抛出。同样,如果分母是0,整数除法运算抛出System.DivideByZ…

02.构建和使用的大型语言模型(LLMs)阶段

我们为什么要建立自己的LLMs?LLM从头开始编码是了解其机制和局限性的绝佳练习。此外,它还为我们提供了必要的知识,可以保留或微调现有的开源LLM架构,以适应我们自己的特定领域的数据集或任务。 研究表明,在建模性能方面,定制(LLMs为特定任务或领域量身定制的)可以胜过…

前端项目构建打包生成Git信息文件

系列文章目录 TypeScript 从入门到进阶专栏 文章目录 系列文章目录前言一、前端项目构建打包生成Git信息文件作用二、步骤1.引入相关的npm包1.1. **fs** 包1.2. **child_process** 包1.3. **os** 包 (非必须 如果你想生成的文件信息中包含当前电脑信息则可用)1.4. **path** 包…

Qt QCheckBox复选按钮控件

文章目录 1 属性和方法1.1 文本1.2 三态1.3 自动排他1.4 信号和槽 2 实例2.1 布局2.2 代码实现 Qt中的复选按钮类是QCheckBox它和单选按钮很相似&#xff0c;单选按钮常用在“多选一”的场景&#xff0c;而复选按钮常用在"多选多"的场景比如喜欢的水果选项中&#xf…