项目:文本编辑器

文章目录

    • @[toc]
  • 文本编辑器
    • 1.项目概述
      • 1.1功能介绍
      • 1.2界面实现预览
      • 1.3界面设计简要介绍
    • 2.设计流程
      • 2.1窗口图片,和标题更改
      • 2.1.1gui方式改变
      • 2.1.2代码方式更改
      • 2.2 QPushButton按钮设置样式表
    • 2.2 功能实现
      • 2.2.1 打开读取文件
      • 2.2.2 打开保存文件
      • 2.2.3 文件关闭
      • 2.2.4 更改编码方式
      • 2.2.5 textEdit光标位置,和当前行高亮
      • 2.2.6 快捷键
      • 2.2.7 ctrl + 滚轮实现放大缩小功能
      • 2.2.8 事件过滤来实现Ctrl+滚轮放缩文字

文本编辑器


1.项目概述

1.1功能介绍

  • 可以实现打开、保存、关闭功能
  • UI界面美化
  • 添加打开快捷键,添加保存快捷键
  • 底部显示行列号,和编码方式
  • Ctrl + "+"实现字体放大,Ctrl + "-"实现字体缩小
    Ctrl + "滚轮"实现字体的放大缩小
  • 实现光标行高亮

1.2界面实现预览

在这里插入图片描述


1.3界面设计简要介绍

本项目使用的是Qt5.12.0,QtCreator GUI编程。选择Widget,wingw64位。

  • Widget的窗口图标和标题自行设计
  • 打开,保存,关闭的样式借助ui编程的样式表
  • 中间计录文本的部件是一个textEdit
  • 下面记录行列号的是一个Label,编码方式选择的是一个combo Box
  • 灰色背景也是借助样式表

2.设计流程


2.1窗口图片,和标题更改

2.1.1gui方式改变

  1. 前提是要添加Qt Resource 文件,将图片文件保存Ctrl+“s”。
  2. 点击.ui文件
    在这里插入图片描述

在上面画线处修改。

2.1.2代码方式更改

示例

    setWindowTitle("nihao");//改标题 QPixmap pix("E:/QT_Example/QtLiangxu/37-notebookUI/icon/note.png");QIcon icon(pix);setWindowIcon(icon);//改图标

2.2 QPushButton按钮设置样式表

查看帮助文档:

help document
Qt Style Sheets
The Style Sheet Syntax

在The Style Sheet Syntax 里会看到一些示例。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这三行分别表示鼠标不在按钮上时的图标状态,鼠标移动到按钮上图标状态,鼠标点击按钮时的图标状态。


2.2 功能实现

  • 文件读取功能
  • 文件保存功能,创建快捷键
  • 文件关闭功能,创建快捷键
  • 关闭按钮弹出消息框功能
  • 文本放大缩小功能
  • 文本光标所在行高亮
  • 状态栏:行号,列号
  • 更改编码方式

2.2.1 打开读取文件

打开文件
读取文件内容
关闭文件
QFileDialog,QFile
QtextStream
file.close()
//打开文件功能
void Widget::on_btnOpen_clicked()
{//打开QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"),"E:/QT_Example/QtLiangxu/37-notebook002",tr("Text(*.txt)"));ui->textEdit->clear();  //在打开文本之前先清空ui界面的textEditfile.setFileName(fileName);     //打开的文件是fileName获取的路径文件if(!file.open(QIODevice::ReadWrite | QIODevice::Text)){qDebug()<<"File open error.";}this->setWindowTitle(fileName + " -MyNoteBook");//这里是实现窗口标题的改变,知道打开的是那个文件//读取QTextStream in(&file);//in.setCodec("UTF-8"); 不在手动输入//将ui->comboBox->currentText()转换为charQString str = ui->comboBox->currentText();const char *cstr = str.toStdString().c_str();//先转换成c++的string再转成char*//std::cout<<cstr;in.setCodec(cstr);//需要传进去char*的变量while(!in.atEnd()){QString context = in.readLine();    //一行一行读取ui->textEdit->append(context);}//关闭,,,以增加了关闭功能//file.close();
}

2.2.2 打开保存文件

打开文件
读取文件内容,修改文件并保存
关闭文件
QFileDialog,QFile
QtextStream
file.close()
//保存文件功能
void Widget::on_btnSave_clicked()
{if(!file.isOpen()){//打开文件QString fileName = QFileDialog::getSaveFileName(this,tr("Save File"),"E:/QT_Example/QtLiangxu/37-notebook002",tr("Text(*.txt)"));file.setFileName(fileName);if(!file.open(QIODevice::ReadWrite | QIODevice::Text)){qDebug()<<"File open error.";}this->setWindowTitle(fileName + " -MyNoteBook");//这里是实现窗口标题的改变,知道打开的是那个文件}//写入文件QTextStream out(&file);QString str = ui->comboBox->currentText();const char *cstr = str.toStdString().c_str();//先转换成c++的string再转成char*out.setCodec(cstr);//out.setCodec("ANSI");QString content = ui->textEdit->toPlainText();//将ui的textEdit的文本返回给QString变量out<<content;//关闭文件,,,已增加了关闭功能//file.close();
}

QString QTextEdit::toPlainText() 常量以纯文本形式返回文本编辑的文本。注意:属性 plainText 的 Getter 函数。参见 QTextEdit::setPlainText()。


2.2.3 文件关闭

这个弹框功能在QMessageBox的帮助文档里有示例。

//关闭文件功能
void Widget::on_btnClose_clicked()
{QMessageBox msgBox;int ret = QMessageBox::warning(this, tr("MyNoteBook Close"),tr("The document has been modified.\n""Do you want to save your changes?"),QMessageBox::Save | QMessageBox::Discard| QMessageBox::Cancel,QMessageBox::Save);// 这里是点击关闭按钮后弹出详细框提供关闭选择 switch (ret) {case QMessageBox::Save:// Save was clickedon_btnSave_clicked();break;case QMessageBox::Discard:// Don't Save was clickedui->textEdit->clear();//清空textEditif(file.isOpen()){file.close();this->setWindowTitle(" -MyNoteBook");}break;case QMessageBox::Cancel:// Cancel was clickedbreak;default:// should never be reachedbreak;}
}

2.2.4 更改编码方式

void Widget::on_comboBox_currentIndexChanged(int index)
{//切换编码后,重新读取//qDebug()<<index;ui->textEdit->clear();  //不管打开还是没打开文件,当comboBox改变时,先清空文本if(file.isOpen()){      //打开文件以comboBox现在的编码方式读取文本QTextStream in(&file);  in.setCodec(ui->comboBox->currentText().toStdString().c_str());//因为在打开文件时光标已经在尾部了,要让光标回到头部才能正常运行下面的代码//文件的光标回到头,QFile的seekfile.seek(0);while(!in.atEnd()){QString context = in.readLine();ui->textEdit->append(context);}}
}
  • void QTextEdit::append(const QString &text):将带有文本的新段落追加到 TextEdit 的末尾。
  • [virtual] bool QIODevice::seek(qint64 pos):
    对于随机访问设备,此函数将当前位置设置为 pos,成功时返回 true,如果发生错误则返回 false。对于顺序设备,默认行为是生成警告并返回 false。

2.2.5 textEdit光标位置,和当前行高亮

  • 需要用到textEdit的信号cursorPositionChanged()。

  • QTextCursor QTextEdit::textCursor() const:
    返回表示当前可见游标的 QTextCursor 的副本。请注意,对返回的游标的更改不会影响 QTextEdit 的游标;使用 setTextCursor() 更新可见光标。

  • 设置当前行高亮需要用到结构体ExtraSelection:

struct ExtraSelection
{QTextCursor cursor;QTextCharFormat format;
};
  • QListQTextEdit::ExtraSelection extraSelections;:来存放QTextEdit::ExtraSelection的变量。
  • QBrush:来获取颜色样式
//实现光标位置更新的功能
void Widget::onCursorPositionChanged()
{QTextCursor cursor=ui->textEdit->textCursor();//qDebug()<<cursor.columnNumber() + 1<<" ;"<<cursor.blockNumber() + 1;//lie hangQString blockNum = QString::number(cursor.blockNumber());   //number()将整形转换为QString型QString columnNum = QString::number(cursor.columnNumber());const QString labelMes = "L:"+blockNum+"   C:"+columnNum;ui->labelPosition->setText(labelMes);//设置当前行高亮
//    struct ExtraSelection
//    {
//        QTextCursor cursor;
//        QTextCharFormat format;
//    };QList<QTextEdit::ExtraSelection> extraSelections;QTextEdit::ExtraSelection ext;//1.知道当前行ext.cursor = ui->textEdit->textCursor();QBrush qBrush(Qt::yellow);//2.颜色ext.format.setBackground(qBrush);//配置属性,整行显示,没有这句话不行ext.format.setProperty(QTextFormat::FullWidthSelection, true);//3.设置//把ext加到容器里extraSelections.append(ext);ui->textEdit->setExtraSelections(extraSelections);
}

2.2.6 快捷键

    QShortcut *shortOpen = new QShortcut(QKeySequence(tr("Ctrl+O", "File|Open")),this);QShortcut *shortSave = new QShortcut(QKeySequence(tr("Ctrl+S", "File|Save")),this);QShortcut *shortZoomIn = new QShortcut(QKeySequence(tr("Ctrl+=", "File|Save")),this);QShortcut *shortZoomOut = new QShortcut(QKeySequence(tr("Ctrl+-", "File|Save")),this);connect(shortOpen,&QShortcut::activated,[=](){on_btnOpen_clicked();});connect(shortSave,&QShortcut::activated,[=](){on_btnSave_clicked();});connect(shortZoomIn,&QShortcut::activated,[=](){zoomIn();});connect(shortZoomOut,&QShortcut::activated,[=](){zoomOut();});void Widget::zoomIn()
{//获取textEdit字体信息QFont font = ui->textEdit->font();//获取当前字体的大小int fontSize = font.pointSize();if(fontSize == -1) return ;//改变字体大小,并设置字体大小int newFontSize = fontSize + 1;font.setPointSize(newFontSize);ui->textEdit->setFont(font);
}void Widget::zoomOut()
{//获取textEdit字体信息QFont font = ui->textEdit->font();//获取当前字体的大小int fontSize = font.pointSize();if(fontSize == -1) return ;//改变字体大小,并设置字体大小int newFontSize = fontSize - 1;font.setPointSize(newFontSize);ui->textEdit->setFont(font);
}

2.2.7 ctrl + 滚轮实现放大缩小功能

  • 新建一个类,需要重写事件:
protected:void wheelEvent(QWheelEvent *e) override;   //滚轮事件void keyPressEvent(QKeyEvent *e) override;  //键盘按下事件void keyReleaseEvent(QKeyEvent *e) override;//键盘施放事件
private:bool ctrlkeyPressed = 0;    //ctrl键按下为true,释放为false
  • 包含头文件:QWheelEvent

  • QPoint QWheelEvent::angleDelta() const:
    返回轮子旋转的距离,以八分之一度为单位。正值表示轮子向前旋转,远离用户;负值表示滚轮向用户向后旋转。

  • void QEvent::accept():
    设置事件对象的 accept 标志,相当于调用 setAccepted(true)。
    设置 accept 参数表示事件接收器需要该事件。不需要的事件可能会传播到父小组件。
    事件一层一层传下去,事件处理了就调用accept就结束了;ignore是将事件往外放,如果放到在最外面(最大的控件)还往外放就不处理这个事件。

void MyTextEdit::wheelEvent(QWheelEvent *e)
{//这一步还要将ui界面的textEdit提升为MyTextEdit//qDebug()<<e->angleDelta().y();if(ctrlkeyPressed == 1){if(e->angleDelta().y() > 0){zoomIn();}else if(e->angleDelta().y() < 0){zoomOut();}e->accept();//事件处理完毕}else{//如果ctrl没按下就不执行放大缩小,,按照滚轮的之前的功能运行QTextEdit::wheelEvent(e);}}void MyTextEdit::keyPressEvent(QKeyEvent *e)
{//用ctrl控制避免 字体随着滚轮滑动变化if(e->key() == Qt::Key_Control){ctrlkeyPressed = 1; //ctrl按下}QTextEdit::keyPressEvent(e);
}void MyTextEdit::keyReleaseEvent(QKeyEvent *e)
{if(e->key() == Qt::Key_Control){ctrlkeyPressed = 0; //ctrl松开}QTextEdit::keyReleaseEvent(e);
}

2.2.8 事件过滤来实现Ctrl+滚轮放缩文字

在Qt的事件处理过程中,引入事件过滤器(Event Filter)可以让你在事件达到目标对象之前进行拦截和
处理。这是一种强大的机制,允许你在不同对象间共享事件处理逻辑或在父对象中集中处理特定事件。

  1. 定义事件过滤器: 事件过滤器通常是一个重写了 QObject::eventFilter() 方法的对象。这个方法
    会在事件传递给目标对象之前被调用。
  2. 安装事件过滤器: 使用 QObject::installEventFilter() 方法安装事件过滤器。这个方法告诉Qt
    在将事件发送给特定对象之前先通过过滤器对象。例如,如果你想在父窗口中过滤子窗口的事件,
    你需要在父窗口的对象上调用 installEventFilter() ,并将子窗口作为参数传递。
  3. 事件过滤器逻辑: 在 eventFilter() 方法内部,你可以编写自定义逻辑来决定如何处理或忽略事
    件。如果此方法返回 true ,则表示事件已被处理,不应该继续传递;如果返回 false ,则事件将
    正常传递给目标对象。
  4. 事件分发: 当事件发生时,Qt首先将事件发送到安装了事件过滤器的对象。在这一步,
    eventFilter() 方法被调用。
  5. 决定是否传递事件: 根据 eventFilter() 方法的返回值,Qt决定是否继续向目标对象传递事件。如
    果过滤器返回 true ,事件处理到此结束;如果返回 false ,事件继续传递到原始目标对象。
  6. 目标对象处理事件: 如果事件过滤器允许事件继续传递,目标对象将像没有事件过滤器存在时那样处
    理事件
bool Widget::eventFilter(QObject *watched, QEvent *event)
{/* QKeyEvent *keyEvent = (QKeyEvent*)event;if(keyEvent->key() == Qt::Key_Control){qDebug() << "Ctrl";}*/if(event->type() == QEvent::Wheel){if(QGuiApplication::keyboardModifiers() == Qt::ControlModifier){QWheelEvent *wheelEvent = dynamic_cast<QWheelEvent*>(event);if(wheelEvent->angleDelta().y() > 0){zoomIn();}else if(wheelEvent->angleDelta().y()<0){zoomOut();}return true;}return false;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Web 前端 UI 框架Bootstrap简介与基本使用

Bootstrap 是一个流行的前端 UI 框架&#xff0c;用于快速开发响应式和移动设备优先的网页。它由 Twitter 的设计师和工程师开发&#xff0c;现在由一群志愿者维护。Bootstrap 提供了一套丰富的 HTML、CSS 和 JavaScript 组件&#xff0c;可以帮助开发者轻松地构建和定制网页和…

【selenium】三大切换 iframe 弹窗alert 句柄window 和 鼠标操作

目录 一、iframe 1、切换方式&#xff1a; 1、第一种情况&#xff1a; 2、第二种情况&#xff1a; 方式1: 先找到iframe&#xff0c;定位iframe元素&#xff08;可以通过元素定位的各种方式&#xff1a;xpath&#xff0c;css等等&#xff09;&#xff0c;用对象接收&…

Sora模型开启了AI视频模型的新篇章,将引领未来更多领域的创新和应用。

目录 一、Sora模型的工作原理 二、AI视频模型的无限可能性 1.视频编辑和创作 2.游戏和虚拟现实 3.教育和远程协作 4.娱乐和社交媒体 OpenAI最近推出了其首个AI视频模型Sora&#xff0c;这个模型能够生成逼真的视频&#xff0c;具有许多潜在的应用领域。本文将探讨Sora模型…

旅游景点旅行研学门票特产小程序开发

旅游景点旅行研学门票特产小程序开发 旅游线路智能推荐与精心规划&#xff0c;我们为用户提供丰富多样的旅游线路选择&#xff0c;助力您的行程安排更加顺畅无忧。 景点门票在线预订与购买功能&#xff0c;覆盖景区、博物馆、演出等各类门票。告别排队等待&#xff0c;一键操…

揭秘抖音自动评论软件的使用方法和步骤

**一、引言** 随着移动互联网的普及&#xff0c;抖音已经成为了人们日常生活中不可或缺的一部分。为了更好地利用抖音&#xff0c;我们今天就来探讨一下抖音自动评论软件的使用方法和步骤。本文将通过通俗易懂的语言&#xff0c;结合实际操作&#xff0c;帮助大家轻松掌握这一…

(十四)【Jmeter】线程(Threads(Users))之开放模型线程组(Open Model Thread Group)

简述 操作路径如下: 开放模型线程组(Open Model Thread Group) 是 JMeter 5.5 版本中引入的一个新特性,它允许用户创建具有可变负载的负载配置文件。相较于传统的线程组,开放模型线程组提供了更多的灵活性和动态调整的能力。 优点: 灵活性:允许测试人员根据测试需求动…

LED景观照明灯驱动电路串联、并联和恒流3款方案

LED景观照明灯是现代城市照明中常见的一种灯具。为了保证LED景观照明灯的正常工作&#xff0c;需要设计合适的驱动电路。LED景观照明灯的驱动电路可以采用串联、并联或恒流的方式来设计。 首先&#xff0c;串联驱动电路是指将多个LED灯串联在一起&#xff0c;然后接入电源进行…

OR-806A固态继电器SSR光耦,可替代AQW212

OR-806A 固态继电器 VL60V输出端击穿电压光耦 高隔离电压 60 至 600V 输出耐受电压 工业温度范围&#xff1a;-40 to 85℃ 高灵敏度和高速响应 特征 输入和输出之间的高隔离电压 &#xff08;Viso&#xff1a;5000 V rms&#xff09;。 控制低电平模拟信号 高灵敏度和…

Vi/Vim 使用小窍门,如何消除搜索后的关键字高亮

Vim/Vi 基本上是 *nix 世界最受欢迎的编辑器了&#xff0c;不知道为什么&#xff0c;一直以来觉得和 Emacs 比起来&#xff0c;Vim 更加有亲和力。用起来很舒服。 今天就记录一个困扰了我很久的问题。 大家应该都知道&#xff0c;在 Vi 里面如果要搜索某个关键字&#xff0c;…

短剧小程序系统,重塑视频观看体验的科技革命

随着科技的飞速发展&#xff0c;人们对于数字化内容的消费需求也在不断增长。在这个大背景下&#xff0c;短剧小程序作为一种新型的视频观看方式&#xff0c;正逐渐受到大众的青睐。本文将探讨短剧小程序的发展背景、特点以及市场前景&#xff0c;分析其在重塑视频观看体验方面…

flutter开发实战-StreamBuilder使用介绍及实例

flutter开发实战-StreamBuilder使用介绍及实例 StreamBuilder是一个Widget&#xff0c;它依赖Stream来做异步数据获取刷新widget。 一、Stream Stream是一种用于异步处理数据流的机制&#xff0c;它允许我们从一段发射一个事件&#xff0c;从另外一段去监听事件的变化.Strea…

Vulnhub-OSCP

信息收集 # nmap -sn 192.168.1.0/24 -oN live.nmap Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-07 17:49 CST Nmap scan report for 192.168.1.1 Host is up (0.00052s latency). MAC Address: 00:50:56:C0:00:08 (VMware) Nmap scan report for 192.168.1.…

#LLM入门|Prompt#1.8_聊天机器人_Chatbot

聊天机器人设计 以会话形式进行交互&#xff0c;接受一系列消息作为输入&#xff0c;并返回模型生成的消息作为输出。原本设计用于简便多轮对话&#xff0c;但同样适用于单轮任务。 设计思路 个性化特性&#xff1a;通过定制模型的训练数据和参数&#xff0c;使机器人拥有特…

安卓手机修改 设置永不锁屏 屏幕永不超时 设置自动锁屏时间 从不 无源码修改系统设置 无需反编译

项目需要 。个别手机系统是的 自动锁屏时间 是没有 永不这个选项的&#xff0c;最多是30分钟。 根据需要。借鉴别人代码&#xff0c;修改&#xff0c;实现了可以在无源码 不反编译系统的情况下。实现屏幕用不锁屏&#xff0c;永不超时的需求&#xff0c; 有需要的小伙伴可以私…

Jenkins的使用GIT(4)

Jenkins的使用GIT 20211002 我们使用 Jenkins 集成外部 Git 仓库&#xff0c;实现对真实代码的拉取和构建。在这里&#xff0c;我们选用 Coding/Github/Gitee 等都可以作为我们的代码源 1 生成公钥私钥 首先&#xff0c;我们先来配置公钥和私钥。这是 Jenkins 访问 Git 私有库…

SparkSQL学习03-数据读取与存储

文章目录 1 数据的加载1.1 方式一&#xff1a;spark.read.format1.1.1读取json数据1.1.2 读取jdbc数据 1.2 方式二&#xff1a;spark.read.xxx1.2.1 读取json数据1.2.2 读取csv数据1.2.3 读取txt数据1.2.4 读取parquet数据1.2.5 读取orc数据1.2.6 读取jdbc数据 2 数据的保存2.1…

vue使用luckysheet时报错window.luckysheet.destroy is not a function

这里写自定义目录标题 vue使用luckysheet时报错window.luckysheet.destroy is not a function解决办法 vue使用luckysheet时报错window.luckysheet.destroy is not a function 按照教程 luckysheet教程: link 将需要的资源进行本地引入。 本地预览excel正常&#xff0c;但是放…

Tomcat 学习之 Filter 过滤器

目录 1 Filter 介绍 2 Filter 的生命周期 3 Filter 和 FilterChain 4 Filter 拦截过程 5 FilterConfig 6 Filter 使用 1 Filter 介绍 在 Tomcat 中&#xff0c;Filter 是一种用于拦截请求和过滤响应的组件&#xff0c;可以在请求到达 Servlet 之前或响应离开 Servlet 之后…

视频的语音转成文字字幕?这3个方法让你实现

随着网络的普及&#xff0c;越来越多的学生选择在网上观看辅导视频&#xff0c;以便随时随地学习。然而&#xff0c;整理这些视频中的教学笔记却成为了一个让人头疼的问题。传统的边看边记录的方式不仅费时费力&#xff0c;还容易遗漏重要信息。那么&#xff0c;有没有一种方法…

Spring Boot application.properties和application.yml文件的配置

在Spring Boot中&#xff0c;application.properties 和 application.yml 文件用于配置应用程序的各个方面&#xff0c;如服务器端口、数据库连接、日志级别等。这两个文件是Spring Boot的配置文件&#xff0c;位于 src/main/resources 目录下。 application.properties 示例 …