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++开发程序媛~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue +elementui 项目登录通过不同账号切换侧边栏菜单的颜色

前景提要:要求不同权限账号登录侧边栏颜色不一样。分为 theme:1代表默认样式,theme:2代表深色主题样式。 1.首先定义一个主题文件 theme.js,定义两个主题样式 // 主要是切换菜单栏和菜单头部主题的设计,整体主题样式切…

electron进程通信之预加载脚本和渲染进程对主进程通信

主进程和预加载脚本通信 主进程 mian,js 和预加载脚本preload.js,在主进程中创建预加载脚本, const createWindow () > {// Create the browser window.const mainWindow new BrowserWindow({width: 300,height: 300,// 指定预加载脚本webPreferences: {preload: path.j…

基于rockpi4b启动流程(2)

uboot启动kernel 基于上篇文章,将开发板烧录loder和system镜像,即可开机进console。 我们将系统停到uboot命令行,printenv看下环境变量 => printenv arch=arm baudrate=1500000 board=evb_rk3399 board_name=evb_rk3399 boot_a_script=load ${devtype} ${devnum}:${di…

闭包,垃圾回收机制

1.垃圾回收机制 当函数执行完毕后,函数内部的变量就会被销毁。 代码: function fn() {var a 10;a;return a;}console.log(fn()); 输出的结果: 11 持续调用的结果: 2.变量的私有化 代码: function fn() {var a 10;return function fn1() {return a;}…

汽车架构解析:python cantools库快速解析arxml

文章目录 前言一、安装cantools二、官方说明文档三、cantools方法1、解析message的属性2、解析pdu中的signals3、根据message查找signals4、报文组成bytes 总结 前言 曾经有拿cantools来解析过dbc,用得比较浅,不知道可以用来解析arxml。最近有个需求需要…

鸿蒙开发第一天

一、开发准备工作 1、开发工具的安装 1)下载地址:https://developer.huawei.com/consumer/cn/deveco-studio/ 2)查询API文档链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/syscap-00000014080893…

Spring-Retry 重试框架使用

一、Spring-Retry Spring-Retry框架是Spring自带的功能&#xff0c;具备间隔重试、包含异常、排除异常、控制重试频率等特点&#xff0c;是项目开发中很实用的一种框架。 支持手动调用方式和注解方式。 使用需引入下面依赖&#xff1a; <dependency><groupId>o…

css文本溢出处理——单行、多行

日常开发中&#xff0c;经常会遇到需要展示的文本过长&#xff0c;这种情况下&#xff0c;为了提高用户的使用体验&#xff0c;最常见的处理方式就是把溢出的文本显示成省略号。 处理文本的溢出的方式&#xff1a;1&#xff09;单行文本溢出&#xff1b; 2&#xff09;多行文本…

一年中ChatGPT使用情况

介绍 本人是独立开源软件开发者&#xff0c;参与很多项目建设&#xff0c;谈下日常使用情况。 我用了一年多&#xff0c;现在已经离不开&#xff0c;我如指挥家&#xff0c;它是我最忠诚的乐手。 编码 GitHub Copilot&#xff1a;GitHub Copilot是GitHub和OpenAI合作开发的一…

Delphi6函数大全3-SysUtils.pas

Delphi6函数大全3-SysUtils.pas首部 function FindNext(var F: TSearchRec): Integer; $[SysUtils.pas功能 返回继续文件搜索说明 搜索成功则返回0参考 function Windows.FindNextFile例子 <参见FindFirst>━━━━━━━━━━━━━━━━━━━━━首部…

WebStorm 创建一个Vue项目(1)

一、下载并安装WebStorm 步骤一 步骤二 选择激活方式 激活码&#xff1a; I2A0QUY8VU-eyJsaWNlbnNlSWQiOiJJMkEwUVVZOFZVIiwibGljZW5zZWVOYW1lIjoiVU5JVkVSU0lEQURFIEVTVEFEVUFMIERFIENBTVBJTkFTIiwiYXNzaWduZWVOYW1lIjoiVGFvYmFv77yaSkVU5YWo5a625qG25rAIOa0uW3peS9nOWup…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-7Lead Compensator超前补偿器(调节根轨迹)

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-7Lead Compensator超前补偿器&#xff08;调节根轨迹&#xff09; 1. Plot Rootlocus 绘制根轨迹2. System Performance 系统表现3. 改善/加快收敛速度4. 超前补偿器 Lead Compe…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)主线程给子线程添加任务以及如何处理该任务

在看此篇文章&#xff0c;建议先看我的往期文章&#xff1a; 基于多反应堆的高并发服务器【C/C/Reactor】&#xff08;中&#xff09;在EventLoop的任务队列中添加新任务-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/135346492?spm1001.2014.3001.5501一…

计算机毕业论文内容参考|基于智能搜索引擎的图书管理系统的设计与实现

文章目录 摘要前言绪论课题背景国内外现状与趋势课题内容相关技术与方法介绍系统分析系统设计系统实现系统测试总结与展望摘要 本文介绍了基于智能搜索引擎的图书管理系统的设计与实现。该系统旨在提供一个高效、智能化的图书管理平台,帮助用户更快、更准确地找到所需的图书资…

python统计分析——直方图(plt.hist)

使用matplotlib.pyplot.hist()函数绘制直方图 from matplotlib.pyplot as pltdata_setnp.array([2,3,3,4,4,4,4,5,5,6]) plt.hist(fish_data) 下面介绍plt.hist()函数中常用的几个重要参数&#xff08;参数等号后为默认设置&#xff09;&#xff1a; &#xff08;1&#xff0…

linux下超级程序!在linux界面实现类图像化界面的操作体验!

linux下超级程序&#xff01;在linux界面实现类图像化界面的操作体验&#xff01; 本期带来一个超级程序&#xff01;在linux界面实现类图像化界面的操作体验。具体功能代码如下: 1500行完整代码想要完成部署&#xff0c;只需在本地创建一个LinuxGJ.sh的文件&#xff0c;然后…

物联网与金融安全的交叉点

先进的物联网 (IoT) 技术改变了金融服务中的网络安全系统。他们不断发展和改进。以信用卡为例&#xff0c;商业银行通过用芯片和密码卡取代磁条卡&#xff0c;显著降低了窃取的风险。 但尽管取得了这些进步&#xff0c;欺诈者仍然逍遥法外。他们仍然找到通过社会工程策略操纵受…

How to understand the Trusted Intelligent Computing Service in Huawei Cloud

How to understand the Trusted Intelligent Computing Service in Huawei Cloud 概述什么是TICS产品架构TICS规格说明产品优势产品功能应用场景政企信用联合风控政府数据融合共治金融联合营销使能数据交易 快速入门TICS快速入门TICS使用流程简介入门实践 概述 什么是TICS 可信…

前端开发个人简历范本(2024最新版-附模板)

前端开发工程师个人简历范本> 年龄 25岁 性别 男 毕业院校 XX大学 张三 学历 邮箱 leeywai-tools.cn 本科 专业 计算机科学与技术 个人梗概 拥有扎实的前端开发技能和丰富的实践经验 善于与团队合作&#xff0c;适应能力强&#xff0c;能够快速融入团队并贡献自…

防火墙未开端口导致zookeeper集群异常,kafka起不来

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 问题描述&#xff1a; 主机信息&#xff1a; IPhostname10.0.0.10host1010.0.0.12host1210.0.0.13host13 在这三台主机上部署…