当前位置: 首页 > news >正文

【Qt】解决设置QPlainTextEdit控件的Tab为4个空格

前言

PyQt5 是一个用于创建跨平台桌面应用程序的 Python 绑定集合,它提供了对 Qt 应用程序框架的访问。用于开发具有图形用户界面(GUI)的应用程序,以及非GUI程序。PyQt5 使得 Python 开发者可以使用 Qt 的丰富功能来构建应用程序。QPlainTextEdit 是 Qt 框架中的一个纯文本编辑器控件,它提供了一个高级的文本编辑和显示功能,专门用于处理纯文本数据。

使用QPlainTextEdit可作为文本显示控件,支持显示与编辑的功能,但是在编辑过程中遇到问题是,当键入Tab时,或者使用制表符(\t)显示文本内容时会发现,QPlainTextEdit控件中对于Tab或者制表符默认为8个空格键,而我们期望的是4个空格键。

接下来,我将展示三种不同的方法来应对前述问题:

(1)自定义Tab的宽度

QPlainTextEdit控件中包含两个对Tab属性进行设置的函数,分别是setTabStopWidthsetTabStopDistance方法,这两个方法都是设置Tab字符的宽度,单位是像素,两个函数共两个不同点:

1、setTabStopWidth方法参数是整型,setTabStopDistance方法参数为浮点型。

2、setTabStopWidth方法已经过时,建议使用setTabStopDistance函数替代。

官方文档中对此两个方法的说明如下:

      下面示例函数将设置QPlainTextEdit控件的Tab字符设置为40pix。

from PyQt5.QtWidgets import QApplication, QMainWindow
from untitled import Ui_MainWindow
import sysclass MainUi(QMainWindow, Ui_MainWindow):def __init__(self):super(MainUi, self).__init__()self.setupUi(self)# self.plainTextEdit.setTabStopWidth(40)self.plainTextEdit.setTabStopDistance(40)self.plainTextEdit.setPlainText("\t1\t2\t3\t4\t5\t6\t")if __name__ == '__main__':app = QApplication(sys.argv)ui = MainUi()ui.show()sys.exit(app.exec_())

下面是程序运行后,我们可以看到Tab键使得字符之间间隔约40pix。

缺点:此方案缺点是Tab字符宽度完全为用户自定义,QPlainTextEdit控件中文本字体大小不同,Tab字符宽度是不同的,因此此方案缺乏灵活性。

(2)自动设置Tab宽度

方法(1)中的缺陷就是忽略了Tab字符的宽度应该与QPlainTextEdit中文本字体大小相一致。因此本方法在方法(1)的基础上通过获取控件中文本字体的大小,并计算4个空格的宽度进行赋值。

from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtGui import QFont, QFontMetrics
from untitled import Ui_MainWindow
import sysclass MainUi(QMainWindow, Ui_MainWindow):def __init__(self):super(MainUi, self).__init__()self.setupUi(self)self.setFont(QFont("Arial", 10))  # 设置字体和大小# self.plainTextEdit.setTabStopWidth(40)# self.plainTextEdit.setTabStopDistance(40)self.plainTextEdit.setTabStopDistance(4 * self.spaceWidth())self.plainTextEdit.setPlainText("\t1\t2\t3\t4\t5\t6\t")print(self.spaceWidth())def spaceWidth(self):font_metrics = QFontMetrics(self.font())return font_metrics.width(' ')  # 获取单个空格的宽度if __name__ == '__main__':app = QApplication(sys.argv)ui = MainUi()ui.show()sys.exit(app.exec_())

缺点:此方法虽然可以使Tab根据控件中文本字体大小自动计算Tab字符宽度,缺点就是我们想要的Tab为4个空格,而实际确是1个字符。

(3)自定义QPlainTextEdit控件

此方法我认为是解决Tab为4个空格最彻底的方法,虽然较上面两种方法复杂,但是效果很好。

第一步:重写QPlainTextEdit控件的keyPressEvent方法。当检测到Tab事件时替换成4个空格:

第二步:重写QPlainTextEdit控件的setPlainText方法,利用python字符串的expandtabs方法,将python字符串中\t换成指定数量的空格。

class MyPlainTextEdit(QPlainTextEdit):def __init__(self, parent=None):super(MyPlainTextEdit, self).__init__(parent)def keyPressEvent(self, event):if event.key() == Qt.Key_Tab:# 插入4个空格cursor = self.textCursor()cursor.insertText('    ')self.setTextCursor(cursor)else:super(MyPlainTextEdit, self).keyPressEvent(event)def setPlainText(self, text: str) -> None:super(MyPlainTextEdit, self).setPlainText(text.expandtabs(4))class MainUi(QMainWindow, Ui_MainWindow):def __init__(self):super(MainUi, self).__init__()self.setupUi(self)self.setWindowTitle('')self.plainTextEdit = MyPlainTextEdit()layout = QVBoxLayout()layout.addWidget(self.plainTextEdit)self.frame.setLayout(layout)self.plainTextEdit.setPlainText("\t1\t2\t3\t4\t5\t6\t")if __name__ == '__main__':app = QApplication(sys.argv)ui = MainUi()ui.show()sys.exit(app.exec_())

 此方法完美解决Tab和制表符替换成4个空格符。

相关文章:

【Qt】解决设置QPlainTextEdit控件的Tab为4个空格

前言 PyQt5 是一个用于创建跨平台桌面应用程序的 Python 绑定集合,它提供了对 Qt 应用程序框架的访问。用于开发具有图形用户界面(GUI)的应用程序,以及非GUI程序。PyQt5 使得 Python 开发者可以使用 Qt 的丰富功能来构建应用程序。…...

elementUI根据列表id进行列合并@莫成尘

本文章提供了elementUI根据列表id进行列合并的demo&#xff0c;效果如图&#xff08;可直接复制代码粘贴&#xff09; <template><div id"app"><el-table border :data"tableList" style"width: 100%" :span-method"objectS…...

基于人工智能的智能安防监控系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据采集与预处理模型训练与预测实时监控与检测应用场景结论 1. 引言 随着科技的发展&#xff0c;智能安防监控系统逐渐成为家庭、企业和公共场所保障安全的核心工具。通过人工智能和计…...

分享从零开始学习网络设备配置--任务6.3 使用基本ACL限制网络访问

任务描述 某公司构建了互联互通的办公网&#xff0c;为保护公司内网用户数据的安全&#xff0c;该公司实施内网安全防范措施。公司分为经理部、财务部和销售部&#xff0c;分属3个不同的网段&#xff0c;3个部门之间用路由器进行信息传递。为了安全起见&#xff0c;公司领导要求…...

数据结构——线性表(静态链表、循环链表以及双向链表)

1、静态链表 用数组描述的链表叫做静态链表&#xff0c;这种描述方法叫做游标实现法。 静态链表需要对数组的第一个和最后一个元素作为特殊元素处理&#xff0c;不存数据。 最后一个指向第一个有数据的下标地址&#xff0c;第一个游标指向第一个没有数据的下标地址。 我们对…...

vue3_对接腾讯_实时音视频

项目需要对接腾讯的实时音视频产品&#xff0c;我这里选择的是多人会议&#xff0c;选择其他实时音视频产品对接流程也一样&#xff0c;如何对接腾讯实时音视频的多人会议产品&#xff0c;从开通服务到对接完成&#xff0c;一 一讲解。 一、开通腾讯实时音视频 1.腾讯实时音视…...

一台电脑对应一个IP地址吗?‌探讨两台电脑共用IP的可能性

在当今数字化时代&#xff0c;‌IP地址作为网络世界中的“门牌号”&#xff0c;‌扮演着至关重要的角色。‌它负责在网络上唯一标识每一台设备&#xff0c;‌使得数据能够在庞大的互联网中准确无误地传输。‌然而&#xff0c;‌对于IP地址与电脑之间的对应关系&#xff0c;‌许…...

XInput手柄输入封装

功能全面地封装了XInput的输入, 1. 普通按钮按下, 按住, 弹起状态检查, 2. 摇杆4个方向的按下, 按住, 弹起检查 3. 按键状态变化检测并且记录按下触发时间, 按住保持时间, 方便用来完全自定义的输入功能 4. 多手柄输入合并 CXinputHelper.h #pragma once #include <win…...

NodeMCU-ESP8266+flash_download_tool_3.9.7 烧录

USB-TTL 接 NodeMCU的RXD0, TXD0, GND 例程hello_world&#xff1a; Eclipse编译信息&#xff1a; python /d/ESP/ESP8266_RTOS_SDK/ESP8266_RTOS_SDK/components/esptool_py/esptool/esptool.py --chip esp8266 --port COM6 --baud 115200 --before default_reset --after …...

首例开源的自动驾驶混合运动规划框架,手握“规划可解释”和“决策准确”两张王牌!

导读&#xff1a; 本文开发了一种新的混合运动规划方法&#xff0c;将环境和预测信息集成在Frenet坐标系中&#xff0c;提升了运动规划能力。本文将传统运动规划算法的可预测性和稳定性与RL的动态适应性相结合&#xff0c;从而形成了一个能够有效管理复杂情况并适应不断变化的环…...

数据结构之红黑树的 “奥秘“

目录&#xff1a; 一.红黑树概念 二. 红黑树的性质 三.红黑树的实现 四.红黑树验证 五.AVL树和红黑树的比较 一.红黑树概念 1.红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过对任何 一条从根…...

【鸿蒙 HarmonyOS NEXT】使用EventHub进行数据通信

✨本人自己开发的开源项目&#xff1a;土拨鼠充电系统 ✨踩坑不易&#xff0c;还希望各位大佬支持一下&#xff0c;在GitHub给我点个 Start ⭐⭐&#x1f44d;&#x1f44d; ✍GitHub开源项目地址&#x1f449;&#xff1a;https://github.com/cheinlu/groundhog-charging-syst…...

大模型RAG实战|构建知识库:文档和网页的加载、转换、索引与存储

我们要开发一个生产级的系统&#xff0c;还需要对LlamaIndex的各个组件和技术进行深度的理解、运用和调优。本系列将会聚焦在如何让系统实用上&#xff0c;包括&#xff1a;知识库的管理&#xff0c;检索和查询效果的提升&#xff0c;使用本地化部署的模型等主题。我将会讲解相…...

江协科技stm32————11-5 硬件SPI读写W25Q64

一、开启时钟&#xff0c;开启SPI和GPIO的时钟 二、初始化GPIO口&#xff0c;其中SCK和MOSI是由硬件外设控制的输出信号&#xff0c;配置为复用推挽输出 MISO是硬件外设的输入信号&#xff0c;配置为上拉输入&#xff0c;SS是软件控制的输出信号&#xff0c;配置为通用推挽输出…...

网络编程day04(UDP、Linux IO 模型)

目录 【1】UDP 1》通信流程 2》函数接口 1> recvfrom 2> sendto 3》代码展示 1> 服务器代码 2> 客户端代码 【2】Linux IO 模型 场景假设一 1》阻塞式IO&#xff1a;最常见、效率低、不耗费CPU 2》 非阻塞 IO&#xff1a;轮询、耗费CPU&#xff0c;可以处…...

【android10】【binder】【2.servicemanager启动——全源码分析】

系列文章目录 可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501 目录 …...

Java实现简易计算器功能(idea)

目的&#xff1a;写一个计算器&#xff0c;要求实现加减乘除功能&#xff0c;并且能够循环接收新的数据&#xff0c;通过用户交互实现。 思路&#xff1a; &#xff08;1&#xff09;写4个方法&#xff1a;加减乘除 &#xff08;2&#xff09;利用循环switch进行用户交互 &…...

Parsec问题解决方案

Parsec目前就是被墙了&#xff0c;有解决方案但治标不治本&#xff0c;如果想稳定串流建议是更换稳定的串流软件&#xff0c;以下是一些解决方案 方案一&#xff1a;在%appdata%/Parsec/config.txt中&#xff0c;添加代理 app_proxy_address 127.0.0.1 app_proxy_scheme http…...

Swift 创建扩展(Extension)

类别(Category) 和 扩展(Extension) 的 用法很多. 常用的 扩展(Extension) 有分离代码和封装模块的功能,例如登陆页面有注册功能,有登陆功能,有找回密码功能,都写在一个页面就太冗余了,可以考虑使用 扩展(Extension) 登陆页面的方法来分离代码 本文介绍Swift 如何创建扩展(Ex…...

九月五日(k8s配置)

一、安装环境 环境准备&#xff1a;&#xff08;有阿里云&#xff09; k8s-master 192.168.1.11 k8s-node1 192.168.1.22 k8s-node2 192.168.1.33 二、前期准备 在k8s-master主机 [rootk8s-master ~]# vim /etc/hosts …...

Amphenol ICC DRPC215001340线束组件在工业设备中的应用与替代分析

在工业自动化和高速设备不断发展的背景下&#xff0c;线束组件的重要性越来越高。很多设备故障&#xff0c;表面看是系统问题&#xff0c;实际上往往与内部连接稳定性有关。而高品质线束组件&#xff0c;正是保障设备长期稳定运行的重要基础。 近期&#xff0c;Amphenol ICC&am…...

emWin GUIBuilder按钮样式修改问题解决方案

1. 问题现象与背景解析在Keil MDK开发环境中使用emWin的GUIBuilder工具时&#xff0c;许多开发者会遇到一个典型问题&#xff1a;创建按钮&#xff08;Button&#xff09;等控件后无法修改其外观设计。具体表现为&#xff1a;在GUI设计界面选中按钮控件&#xff0c;尝试调整颜色…...

STM32F103C8T6+TJA1042+UTA0403:一个CAN通讯新手踩过的所有坑(附完整接线图与代码)

STM32F103C8T6与TJA1042的CAN通讯实战&#xff1a;从零到通的完整避坑指南 当蓝色PCB上那颗STM32F103C8T6第一次通过CAN总线发出数据帧时&#xff0c;我的示波器上终于出现了规整的差分信号波形——这距离我首次焊接CAN收发器已经过去了整整三周。作为嵌入式开发的新手&#xf…...

从霍金难题到MESI协议:原子操作性能瓶颈的硬件根源与优化实践

1. 项目概述&#xff1a;从霍金的难题到现代CPU的协同困境 如果你写过并发程序&#xff0c;或者研究过Linux内核的同步机制&#xff0c;你一定对“原子操作”和“缓存一致性”这两个词不陌生。我们常常被告知&#xff0c;原子操作是昂贵的&#xff0c;因为它需要“锁总线”或者…...

RISC-V MCU移植RTOS实战:以鸿蒙OS LiteOS-M与CH32V307为例

1. 项目概述与核心思路 最近在折腾一块沁恒微电子的CH32V307开发板&#xff0c;这是一颗基于RISC-V架构的MCU&#xff0c;性能不错&#xff0c;外设也丰富。手头正好有个任务&#xff0c;需要把华为的鸿蒙OS LiteOS-M内核给移植上去。这活儿听起来挺唬人&#xff0c;但实际拆解…...

初创团队如何通过Taotoken模型广场选型并控制AI成本

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 初创团队如何通过Taotoken模型广场选型并控制AI成本 对于资源有限的初创团队而言&#xff0c;将大模型能力集成到产品中是加速创新…...

终极ncmdump工具完整指南:3分钟快速解密NCM格式音乐文件

终极ncmdump工具完整指南&#xff1a;3分钟快速解密NCM格式音乐文件 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的歌曲只能在特定播放器里播放而烦恼吗&#xff1f;ncmdump工具为你提供完美的解决方案&…...

Joy-Con Toolkit:3大核心功能让你的Switch手柄重获新生

Joy-Con Toolkit&#xff1a;3大核心功能让你的Switch手柄重获新生 【免费下载链接】jc_toolkit Joy-Con Toolkit 项目地址: https://gitcode.com/gh_mirrors/jc/jc_toolkit 你是否曾为Switch手柄的摇杆漂移而烦恼&#xff1f;是否想过让千篇一律的手柄颜色变得与众不同…...

【 Godot 4 学习笔记】命名规范

命名规范类型命名规范示例文件与文件夹snake_case (蛇形)player_controller.gd, assets/类名 / 脚本名PascalCase (大驼峰)PlayerController, YAMLParser场景节点名PascalCase (大驼峰)HitBox, Camera3D, Player函数 / 方法snake_case (蛇形)func load_level():变量 / 信号snak…...

别再手动拖拽了!用CodeWave自由布局5分钟搞定一个高还原度后台管理页

5分钟高保真还原设计稿&#xff1a;CodeWave自由布局实战指南 每次拿到设计师发来的Figma稿子&#xff0c;你是不是也经历过这样的痛苦&#xff1f;在传统开发工具里手动调整像素级间距&#xff0c;反复比对色值&#xff0c;调试响应式效果到深夜…上周我接手一个电商后台改版项…...