QTextEdit将多个字符作为一个整体,不可单独修改

2024-05-27 09:44

本文主要是介绍QTextEdit将多个字符作为一个整体,不可单独修改,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

考虑一个问题,QTextEdit如何实现类似微信和QQ聊天输入框中的“@xxx”效果,其内容作为一个整体,以突出颜色显示,并且不可以单独编辑修改,只能整体删除修改。

突出颜色显示有很多方式可以实现,例如

  • 通过setTextColor接口,此接口可以设置当前字体颜色为指定颜色
//保存当前颜色
QColor _color = this->textColor();
//设置为红色
this->setTextColor(Qt::red);
//添加文字
this->append("hello world");
//恢复颜色
this->setTextColor(_color);
  • 通过html格式实现
this->append("<font color=\"#FF0000\">红色字体</font> ");
  • 通过QTextCharFormat实现
auto cursor = this->textCursor();
//备份格式auto backFormat = cursor.charFormat();//设置字体auto _font_size = this->font().pointSize();//构建格式QTextCharFormat _format;//设置文本颜色_format.setForeground(Qt::red);cursor.insertText(QString(QChar::ObjectReplacementCharacter),_format);//恢复默认格式this->setCurrentCharFormat(backFormat);

颜色搞定了,如何将指定的字符串设为整体呢?
通过面向百度编程和查阅文档(主要是面向百度编程,哈哈)找到一种方法。
众所周知,QTextEdit中的内容是有QTextDocument类实现渲染的,而QTextDocument的布局方式是由QAbstractTextDocumentLayout实现的,可以通过QAbstractTextDocumentLayout *QTextDocument::documentLayout()接口获取。而在QAbstractTextDocumentLayout类中提供了
void registerHandler(int objectType, QObject *component)接口可以注册自定义的Handler实现自定义绘制。因此可以通过此方式实现将多个文本作为整体。

先看效果
在这里插入图片描述
继承QTextObjectInterface实现intrinsicSizedrawObject

enum TextFormatRole
{//字体大小Format_FontSize = QTextFormat::UserProperty + 1,//文本Format_Text
};
class TextEditHander : public QObject,QTextObjectInterface
{Q_OBJECTQ_INTERFACES(QTextObjectInterface)
public:TextEditHander(QObject* parent = nullptr);~TextEditHander();//计算绘制区域QSizeF intrinsicSize(QTextDocument *doc, int posInDocument,const QTextFormat &format) override;void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc,int posInDocument, const QTextFormat &format) override;};
TextEditHander::TextEditHander(QObject *parent):QObject(parent)
{}TextEditHander::~TextEditHander()
{}//计算绘制区域
QSizeF TextEditHander::intrinsicSize(QTextDocument *doc, int posInDocument,const QTextFormat &format)
{//获取字体大小int font_size = format.property(Format_FontSize).toInt();QString text = format.property(TextFormatRole::Format_Text).toString();auto _font = doc->defaultFont();_font.setPointSize(font_size);QFontMetrics _metrics(_font);int textWidth = _metrics.horizontalAdvance(text);return QSizeF(textWidth,_metrics.height());
}//绘制
void TextEditHander::drawObject(QPainter *painter, const QRectF &rect,QTextDocument *doc, int posInDocument, const QTextFormat &format)
{Q_UNUSED(doc);Q_UNUSED(posInDocument);QString text = format.property(Format_Text).toString();int font_size = format.property(Format_FontSize).toInt();//调整rect
//    QRectF _drawRect = rect.adjusted(0,1,0,-1);QRectF _drawRect = rect;//绘制painter->save();//绘制背景painter->fillRect(_drawRect,format.background());//绘制文字auto _font = doc->defaultFont();_font.setPointSize(font_size);painter->setFont(_font);painter->setPen(format.foreground().color());painter->drawText(_drawRect,Qt::AlignBaseline,text);painter->restore();
}

继承QTextEdit

class TextEdit : public QTextEdit
{Q_OBJECT
public:explicit TextEdit(QWidget *parent = nullptr);virtual ~TextEdit() = default;
protected slots://插入标签void slot_addText();
};
TextEdit::TextEdit(QWidget *parent): QTextEdit{parent}
{//注册handlerauto handler = new TextEditHander(this);this->document()->documentLayout()->registerHandler(QTextFormat::UserObject+1,handler);QFont _font = this->font();_font.setPointSize(12);this->setFont(_font);//创建右键菜单QAction *act = new QAction("插入标签",this);connect(act,&QAction::triggered,this,&TextEdit::slot_addText);this->addAction(act);this->setContextMenuPolicy(Qt::ActionsContextMenu);
}void TextEdit::slot_addText()
{auto cursor = this->textCursor();//备份格式auto backFormat = cursor.charFormat();//设置字体auto _font_size = this->font().pointSize();//构建格式QTextCharFormat _format;//设置格式使用自定义的Hander渲染,这步很重要_format.setObjectType(QTextFormat::UserObject + 1);//设置需要绘制的文本_format.setProperty(TextFormatRole::Format_Text,"${123}");//设置字体大小_format.setProperty(TextFormatRole::Format_FontSize,_font_size);//设置前景色_format.setForeground(Qt::black);//设置背景色_format.setBackground(Qt::lightGray);cursor.insertText(QString(QChar::ObjectReplacementCharacter),_format);//恢复默认格式this->setCurrentCharFormat(backFormat);//添加一个空格this->textCursor().insertText(" ");}

这篇关于QTextEdit将多个字符作为一个整体,不可单独修改的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1007127

相关文章

Docker镜像修改hosts及dockerfile修改hosts文件的实现方式

《Docker镜像修改hosts及dockerfile修改hosts文件的实现方式》:本文主要介绍Docker镜像修改hosts及dockerfile修改hosts文件的实现方式,具有很好的参考价... 目录docker镜像修改hosts及dockerfile修改hosts文件准备 dockerfile 文

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Linux修改pip和conda缓存路径的几种方法

《Linux修改pip和conda缓存路径的几种方法》在Python生态中,pip和conda是两种常见的软件包管理工具,它们在安装、更新和卸载软件包时都会使用缓存来提高效率,适当地修改它们的缓存路径... 目录一、pip 和 conda 的缓存机制1. pip 的缓存机制默认缓存路径2. conda 的缓

Linux修改pip临时目录方法的详解

《Linux修改pip临时目录方法的详解》在Linux系统中,pip在安装Python包时会使用临时目录(TMPDIR),但默认的临时目录可能会受到存储空间不足或权限问题的影响,所以本文将详细介绍如何... 目录引言一、为什么要修改 pip 的临时目录?1. 解决存储空间不足的问题2. 解决权限问题3. 提

Python实现合并与拆分多个PDF文档中的指定页

《Python实现合并与拆分多个PDF文档中的指定页》这篇文章主要为大家详细介绍了如何使用Python实现将多个PDF文档中的指定页合并生成新的PDF以及拆分PDF,感兴趣的小伙伴可以参考一下... 安装所需要的库pip install PyPDF2 -i https://pypi.tuna.tsingh

Linux文件名修改方法大全

《Linux文件名修改方法大全》在Linux系统中,文件名修改是一个常见且重要的操作,文件名修改可以更好地管理文件和文件夹,使其更具可读性和有序性,本文将介绍三种在Linux系统下常用的文件名修改方法... 目录一、引言二、使用mv命令修改文件名三、使用rename命令修改文件名四、mv命令和rename命

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

mybatis-plus 实现查询表名动态修改的示例代码

《mybatis-plus实现查询表名动态修改的示例代码》通过MyBatis-Plus实现表名的动态替换,根据配置或入参选择不同的表,本文主要介绍了mybatis-plus实现查询表名动态修改的示... 目录实现数据库初始化依赖包配置读取类设置 myBATis-plus 插件测试通过 mybatis-plu