当前位置: 首页 > 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 …...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

前端高频面试题2:浏览器/计算机网络

本专栏相关链接 前端高频面试题1&#xff1a;HTML/CSS 前端高频面试题2&#xff1a;浏览器/计算机网络 前端高频面试题3&#xff1a;JavaScript 1.什么是强缓存、协商缓存&#xff1f; 强缓存&#xff1a; 当浏览器请求资源时&#xff0c;首先检查本地缓存是否命中。如果命…...

机器学习的数学基础:线性模型

线性模型 线性模型的基本形式为&#xff1a; f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法&#xff0c;得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...