Qt实现文本编辑器(二)

上一章节讲述了如何制作文本编辑页面,以及应该有哪些功能需要实现,只是做了展示效果,实际的点击事件并没有处理。今天来具体讲解下是如何实现菜单栏以及工具栏上对应的需求吧~

功能实现

功能:

1、动作消息触发

2、具体功能:打开文件、新建文件、复制、剪切、粘贴

3、文本编辑功能:字体设置

今天只讲述以上三大功能,至于:旋转、缩放等功能都是针对于图片来说的,等下一章节,具体的讲解方式就不在是文本编辑器的功能了,静待后续更文吧!

功能1:动作消息

上一章节的动作已经创建完成了,那么该如何触发这些动作呢?

在Qt中动作触发方式与控件触发方式是一致的,例如:想要让一个按钮控件响应操作,需要响应QPushButton::clicked消息,这里也是同样的道理。

想要响应动作事件用到的是QAction::triggered

各个动作对应的槽函数如下

打开文件

connect(m_pActionOpenFile, &QAction::triggered, this, &QtTextEditor::OnTriggeredOpenFile);

新建文件

connect(m_pActionOpenFile, &QAction::triggered, this, &QtTextEditor::OnTriggeredNewFile);

复制、剪切、粘贴

connect(m_pActionOpenFile, &QAction::triggered, m_editContent, &QTextEdit::copy);connect(m_pActionOpenFile, &QAction::triggered, m_editContent, &QTextEdit::cut);connect(m_pActionOpenFile, &QAction::triggered, m_editContent, &QTextEdit::paste);

看到槽函数,大家可以发现,对于复制、剪切、粘贴功能都是采用QTextEdit控件实现的,在这里不需要做新的处理,直接使用父类消息就可以了。

为了对编辑文本类的功能处理,最好的方式继承自QTextEdit进行功能封装,假设叫做:QMyTextEdit,后续都用该类作为编辑文本类

功能2:动作事件实现

针对上述两个需要自己实现的槽函数响应,接下来就进行详细的讲述吧~

2.1:打开文件

打开文件,代表的是打开一个已经存在的文件,这里需要用到QFileDialog类,使用QFileDialog::getOpenFileName()静态函数,返回选择文件的带路径的完整路径名。

void QtTextEditor::OnTriggeredOpenFile()
{QString qsFileName = QFileDialog::getOpenFileName(this);if (qsFileName.isEmpty()){return;}if (m_editContent->document()->isEmpty()){this->LoadFileContent(m_editContent, qsFileName);}else{QMyTextEdit *editContent = new QMyTextEdit;editContent->show();this->LoadFileContent(editContent, qsFileName);m_vetEditCtrls.push_back(editContent);}
}

代码思路:

获取打开的文件路径,如果返回的字符串是空,说明未打开有效文件,不进行处理;

在展示内容之前,判断当前edit控件是否有数据?如果没有直接在当前文本编辑控件中展示;

如果当前文本编辑控件存在数据,则重新创建一个QMyTextEdit自定义类,用来展示新内容。

其中,LoadFileContent函数的具体内容:

void QtTextEditor::LoadFileContent(QMyTextEdit* editCtrls, QString qsFileName)
{QFile file(qsFileName);if (file.open(QIODevice::ReadOnly | QIODevice::Text)){QTextStream textStream(&file);while (!textStream.atEnd()){editCtrls->append(textStream.readLine());}}
}

代码说明:

采用了QTextStream方式读取文件流数据,可以方便的读写单词、行和数字,甚至还提供了填充、对齐和数字格式化的选项操作。

为什么第一个参数会传入类指针呢?

因为在这里有个功能,叫做新建,在读取文件的时候,假设当前展示的文本编辑器类QMyEdit中存在了内容时,是需要重新创建的,为了统一起见,将第一个参数设置为类指针,方便函数调用。

无论是新创建的页面还是已经存在的页面都可以进行写入文本。

2.2:新建文件

在这里所谓的新建就是建立一个空白的编辑文本,功能简单,这里就不再过多说明了。

void QtTextEditor::OnTriggeredNewFile()
{QMyTextEdit *editCtrls = new QMyTextEdit;editCtrls->show();m_vetEditCtrls.push_back(editCtrls);
}

唯一需要提一句的就是:创建了新的文本类之后,一定要记得存储类指针,为了防止在后续使用的过程中查询不到以及在销毁的过程中,防止内存泄漏。

2.3:复制、剪贴、粘贴

这三个功能都沿用的QTextEdit自带功能,这里不用再过多说明,直接响应父类消息就可以了。

功能3:文本编辑

大家都用过文本编辑器,主要的功能还是对文字的操作,那么在这里主要讲述了文字工具栏以及文字的展示风格

3.1 文字工具栏

正如上一章节讲述那般,工具条的使用大家都不陌生了吧,这里需要创建一个字体工具栏,并包含了如下几个功能:

实际做出来的效果,如下:

对于字体的设置,与其它工具条上展示的内容不一致,不再采用动作,而是使用了控件的方式

具体每个功能对应的类名上面的表格已经说明了,重点要说的是:获取字体风格以及字体的大小

字体风格

QFontCombobox是QComboBox的一个子类,是不能被编辑的,只能用来选择字体。

m_ComboFontStyle = new QFontComboBox;
m_ComboFontStyle->setFontFilters(QFontComboBox::ScalableFonts);
字体字号

采用的是:QFontDatabase,提供了有关底层窗口系统中可用的字体信息,当前主要用来查询字体大小的。

m_ComboFontSize = new QComboBox;
QFontDatabase dbFont;
foreach(int size, dbFont.standardSizes())
{m_ComboFontSize->addItem(QString::number(size));
}

代码解析:

这里使用了foreach的方式,代替了for循环,要是有不懂得小伙伴可以详细查询,这里只是做了解释说明~

standarSizes函数,返回了可用的标准字号的列表,并将列表内容插入到QCombobox中。

另外说明:QToolButton与QPushButton的用法一致,只是换了类名,创建方法以及消息绑定都不再过多说明了。

最后,将创建的这些控件绑定到字体工具条上

m_pToolFont = addToolBar("Font");
m_pToolFont->setAllowedAreas(Qt::BottomToolBarArea );
m_pToolFont->addWidget(m_labFontStyle);
m_pToolFont->addWidget(m_ComboFontStyle);
m_pToolFont->addWidget(m_labFontSize);
m_pToolFont->addWidget(m_ComboFontSize);
m_pToolFont->addSeparator();
m_pToolFont->addWidget(m_btnFontBold);
m_pToolFont->addWidget(m_btnFontItalic);
m_pToolFont->addSeparator();
m_pToolFont->addWidget(m_btnFontColor);

看到这里,大家可以尝试下自己写的代码,看看是不是可以运行起来。

在这里需要注意的是:为什么运行起来是下面这个样子?

有没有人有这种情况?为什么和第一张效果图不一样呢?不是另起一行,而是什么都看不到了呢?

在ToolBar中,如果一行展示不全的情况下,需要告诉QToolBar另起一行,则,需要在addToolBar之前添加如下代码:

this->addToolBarBreak(Qt::TopToolBarArea);

再次运行,就变成了两行的工具栏了,踩坑记录,希望大家也不要犯这个错误啦~

3.2:字体风格

在这里,说到的字体风格无外乎就是工具栏上所展示的内容啦!

文字风格这部分都采用了QTextCharFormat对象进行实现的

字体风格
void QtTextEditor::OnComboFontStyle(QString& qsText)
{QTextCharFormat fmt;fmt.setFontFamily(qsText);QTextCursor cursor = m_editContent->textCursor();if (!cursor.hasSelection()){cursor.select(QTextCursor::WordUnderCursor);}cursor.mergeCharFormat(fmt);m_editContent->mergeCurrentCharFormat(fmt);
}

代码解析:

获取控件的焦点,假设当前控件上的文本并没有被选中,就指定光标区域所在的词为高亮选定词,从而设置字体风格样式

字号
fmt.setFontPointSize(qsText.toInt());
加粗
fmt.setFontWeight(bCheck);
斜体
fmt.setFontItalic(bchecked);

以上几个功能,用法都很类似,正如我前面提到的,都是采用QTextCharFormat类,只是设置的函数不同,具体的功能不在做过多说明,下面,与上述几个功能相比较,需要说明的是:颜色设置。

字体颜色

在这时颜色的时候,用到了系统文件类:QColorDialog,与打开文件的方式类似,只是类名不一致

void QtTextEditor::OnToolFontColor(bool bchecked)
{QColor color = QColorDialog::getColor(Qt::red, this);if (color.isValid()){QTextCharFormat fmt;fmt.setForeground(color);m_editContent->mergeCurrentCharFormat(fmt);}
}

根据以上功能,具体的显示效果如下:

总结

到这里,具体的文本风格就讲解完成了,在整个设置过程中,最最重要的类就是:QTextCharFormat。

在代码使用过程中,大家会发现,我一直是对m_editContent进行操作的,是滴!

其实是存在新建功能的,这里的新建空白文本的文字处理功能就交给大家啦,这是只是做一个示范例子而已,提前说明下,不是很难,只要掌握了当前处于活跃的QMyEdit类指针就可以了。

今天的内容就到这里了,我是糯诺诺米团,一名C++开发程序媛~

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

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

相关文章

常见安全概念澄清,Java小白入门(八)

认证 认证 (Identification) 是验证当前用户的身份。 常见的认证技术: 身份证用户名和密码用户手机:手机短信、手机二维码扫描、手势密码用户的电子邮箱用户的生物学特征:指纹、语音、眼睛虹膜 授权 授权 (Authorization) 指赋予用户系统…

Pointnet++改进:更换不同的激活函数,打造更优性能

简介: 1.该教程提供大量的首发改进的方式,降低上手难度,多种结构改进,助力寻找创新点! 2.本篇文章对Pointnet进行激活函数的改进,助力解决RELU激活函数缺陷。 3.专栏持续更新,紧随最新的研究内容…

前端Web系统架构设计

文章目录 1.目录结构定义2. 路由封装2.1 API路由定义2.2 组件路由定义 3. Axios请求开发4. 环境变量封装5. storage模块封装(sessionStorage, localStorage)6. 公共函数封装(日期,金额,权限..)7. 通用交互定义(删除二次确认,类别,面包屑...)8. 接口全貌概览 1.目录结构定义 2. …

LeetCode刷题--- 三步问题

个人主页:元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 ​​​​​​http://t.csdnimg.cn/6AbpV 数据结构与算法 ​​​http://t.csdnimg.cn/hKh2l 前言:这个专栏主要讲述动…

【Matlab】PSO-BP 基于粒子群算法优化BP神经网络的数据时序预测(附代码)

资源下载: https://download.csdn.net/download/vvoennvv/88689096 一,概述 PSO-BP算法是一种结合了粒子群算法(PSO)和BP神经网络的方法,用于数据时序预测。下面是PSO-BP算法的原理和过程: 1. 数据准备&…

继承和多态

全局变量,int monster 10000:定义英雄类hero,受保护的属性string name,int hp,int attck;公有的无参构造,有参构造,虚成员函数 void Ak(blood-0),法师类继承自英雄类,私有属性 int p_atk50;重写…

Github 2024-01-03 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-01-03统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目3TypeScript项目3Jupyter Notebook项目1Dart项目1C项目1Rust项目1 系统设计指南 创建周期&#x…

计算机毕业设计 SpringBoot的停车场管理系统 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…

堆排序 Heapsort

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概…

简易机器学习笔记(四)初识卷积神经网络

前言 第一次写卷积神经网络,也是照着paddlepaddle的官方文档抄,这里简单讲解一下心得。 首先我们要知道之前写的那些东西都是什么,之前写的我们称之为简单神经网络,也就是简单一层连接输出和输出,通过前向计算和逆向…

Simple Facebook Sign-In

简单的Facebook登录为Android、iOS、Windows、Mac、通用Windows平台(UWP)和Unity制作的WebGL应用程序提供了基于OAuth 2.0的Facebook登录。 优点: ● 跨平台游戏和应用程序的跨平台用户身份验证 ● 无插件,无第三方库,无依赖● 对建筑规模没有影响 ● 客户端-服务器应…

solidity显示以太坊美元价格

看过以太坊白皮书的都知道,以太坊比较比特币而言所提升的地方中,我认为最重要的一点就是能够访问外部的数据,这一点在赌博、金融领域应用会很广泛,但是区块链是一个确定的系统,包括里面的所有数值包括交易ID等都是确定…

OS 7--DNS配置+Apache发布网站

环境准备 centOS 7 1.配置DNS 1.1 域名为lianxi.com 1.2 为WWW服务器、FTP服务器、NEWS服务器做域名解析 1)安装DNS yum -y install bind bind-utils (如果安装不上,就把磁盘在重洗挂载一下) 2)修改DNS配置文件 vim /etc/resolv.conf…

车载 Android之 核心服务 - CarPropertyService 解析

重要类的源码文件名及位置: CarPropertyManager.java packages/services/Car/car-lib/src/android/car/hardware/property/ CarPropertyService.java packages/services/Car/service/src/com/android/car/ 类的介绍: CarPropertyManager&#xff1a…

航芯ACM32G103开发板评测 02-GPIO输入输出

航芯ACM32G103开发板评测 02-GPIO输入输出 航芯ACM32G103开发板评测 GPIO输入输出应用 软硬件平台 ACM32G103 Board开发板 MDK-ARM Keil GPIO输出典型应用——点灯 GPIO输入典型应用——按键 GPIO 功能概述 GPIO 是通用输入/输出(General Purpose I/O&#x…

[Flutter]WindowsOS中相关配置

Flutter项目在Windows平台上如何配置 目录 Flutter项目在Windows平台上如何配置 写在开头 正文 1、OS准备 2、编译环境准备 ① 下载AndroidStudio ② 下载dart ③ 下载flutter ④ 下载并安装VS ⑤ 在AS中配置dart和flutter 3、配置中遇到的问题 写在结尾 写在开头…

C++ stack使用、模拟实现、OJ题

目录 一、介绍 二、常用函数 三、模拟实现 四、OJ练习题 1、最小栈 2、栈的压入、弹出序列 3、逆波兰表达式(后缀转中缀) 4、中缀转后缀思路 5、用栈实现队列 一、介绍 stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除…

自动驾驶论文

文章目录 一、Convolutional Social Pooling for Vehicle Trajectory Prediction二、QCNet:Query-Centric Trajectory Prediction三、VectorNet: Encoding HD Maps and Agent Dynamics from Vectorized Representation 一、Convolutional Social Pooling for Vehicl…

iOS 小组件开发

iOS14之后Apple引入了新的WidgetKit,舍弃了原有额TodayExtension。 开发准备: 新的WidgetExtension只能通过SwiftUI进行开发; Widget有三种尺寸:systemSmall、 systemMedium、systemLarge,三种尺寸对应固定的UI类型布…

BIND-DNS配置介绍

一、主要配置文件 /etc/named.conf options { //Option 段全部配置 listen-on port 53 { 127.0.0.1; };//表示BIND将在53端口监听,若需要对所有IP进行监听,则修改为// listen-on port 53 { any; }; directory "/var/named"…