当前位置: 首页 > news >正文

Qt(制作一个方便的文本编辑器)

目录

功能的简单介绍:

制作过程步骤:

菜单栏、工具栏和文本编辑器的创建和设置:

主窗口:

文本编辑框:

菜单栏、工具栏的创建和设置:

主菜单栏:

创建文件菜单:

为文件菜单添加打开文件、保存文件、关闭的动作:

创建工具栏:

连接信号和槽函数:

打开文件:

保存文件:

关闭:

字体设置:

颜色设置:

完整代码:

MainWindow代码:

主函数:


用QDialog类的文件窗口、颜色窗口、字体窗口、QMessageBox类中的弹窗消息、菜单栏、工具栏、信号和槽函数实现一个简单的文本编辑器。

常用对话框:

https://blog.csdn.net/HMBBLOVEPDX/article/details/151968097?spm=1001.2014.3001.5501

信号和槽函数:

https://blog.csdn.net/HMBBLOVEPDX/article/details/151928089?spm=1001.2014.3001.5501

菜单栏、工具栏、状态栏:

https://blog.csdn.net/HMBBLOVEPDX/article/details/152092439?spm=1001.2014.3001.5501

功能的简单介绍:

制作一个建议的文本编辑器,实现:

打开文件:将选择的文件点击打开之后,内容显示在文本编辑框。

保存文件:将文本编辑框中的内容保存到选择的路径下。

关闭:点击关闭之后,关闭程序。

设置字体:将选中的内容的字体改变为选择的字号和字体。

设置字体:将选中的内容的字体颜色改变为选择的字体颜色。

制作过程步骤:

菜单栏、工具栏和文本编辑器的创建和设置:

先将要使用到的变量定义为成员变量,方便后面对其进行封装,要不然全写构造函数,看起来太多。在成员函数中定义一个createMenuBar()函数,对菜单栏、工具栏、文本编辑框进行设置。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include 
#include 
#include 
#include 
#include 
#include 
#include 
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{Q_OBJECT
public:MainWindow(QWidget *parent = nullptr);~MainWindow();void createMenuBar();
private:Ui::MainWindow *ui;QMenuBar* newmenuBar;//定义一个主菜单栏QMenu* FileMenu;//定义一个文件菜单QAction* openFileMenu;//定义打开文件动作QAction* saveFileMenu;//定义保存文件动作QAction* closeMenu;//定义关闭动作QToolBar* toolBar;//定义一个工具栏QToolButton* FontButton;//定义设置字体的工具按钮QToolButton* ColorButton;//定义一个设置字体颜色的工具按钮QTextEdit* textEdit;//定义一个文本编辑框
};
#endif // MAINWINDOW_H

主窗口:

在构造函数中,先将主窗口的标题和图标进行一个设置:

this->setWindowTitle("文件编辑器");
this->setWindowIcon(QIcon(":/resimage/downloaded-image.png"));
//QIcon("资源路径")

图标需要添加到该项目当中的资源文件中,然后复制图片的路径。这样可以达到:

文本编辑框:

然后对文本编辑框进行设置:

textEdit=new QTextEdit(this);
this->setCentralWidget(textEdit);

创建一个QTextEdit控件实例(多行文本编辑区域),参数this表示将当前窗口设为父对象,实现内存自动管理。将创建的文本编辑器设置为窗口的中央部件,在QMainWindow布局体系中,centralWidget会占据除菜单栏/状态栏外的所有空间。

菜单栏、工具栏的创建和设置:

然后对createMenuBar()函数进行封装:

主菜单栏:

先创建一个主菜单栏,将其添加到主窗口当中:

newMenuBar=this->menuBar();//将获取到的菜单栏指针赋值给newMenuBar变量。
//这种方式相比直接new QMenuBar()更安全,避免了重复创建导致的内存泄漏问题
this->setMenuBar(newMenuBar);

因为菜单栏在一个窗口只有一个,所以这里采用menuBar(),当newMenuBar为空时,就创建,如果不为空,则不会创建,保证只有一个主菜单栏。将菜单栏设置到主窗口。虽然此处newMenuBar就是当前窗口的菜单栏,该操作看似冗余,但实际确保了菜单栏的正确初始化状态。

创建文件菜单:
FileMenu=new QMenu("文件");
newmenuBar->addMenu(FileMenu);

将文件菜单添加到主菜单栏中。

为文件菜单添加打开文件、保存文件、关闭的动作:
openFileMenu=new QAction(QIcon(":/resimage/open.png"),"打开文件");
openFileMenu->setShortcut(QKeySequence("Ctrl+O"));
FileMenu->addAction(openFileMenu);
saveFileMenu=new QAction(QIcon(":/resimage/save.png"),"保存文件");
saveFileMenu->setShortcut(QKeySequence("Ctrl+S"));
FileMenu->addAction(saveFileMenu);
closeMenu=new QAction(QIcon(":/resimage/close.png"),"退出");
closeMenu->setShortcut(QKeySequence("Ctrl+X"));
FileMenu->addAction(closeMenu);

可以跳到QAction的头文件进行查看其构造函数:

可以知道,创建动作时,可以通过构造函数为其添加图标、标题和父窗口指针。

所以这里采用第三种构造函数,在创建时,就为其添加好图标。

setShortcut(QKeySequence("设置的键"))是Qt框架中为动作或控件设置键盘快捷键的核心方法。

该方法将组合键绑定到目标对象(如QAction或QPushButton),当用户按下该组合键时,会触发对象关联的信号(如QAction的triggered信号或按钮的clicked信号)。快捷键支持跨平台统一处理,在Windows/Linux/macOS中均能生效。

快捷键事件由Qt事件系统全局监听,通过QShortcut类实现底层拦截。当检测到匹配按键时,会直接调用目标对象的槽函数,效果等同于用户手动点击。作用范围默认为当前窗口(Qt::WindowShortcut),可通过setContext()调整。

创建号动作之后还是和之前一样,将动作添加到文件菜单项中。

效果如下:

创建工具栏:

toolBar=new QToolBar("工具栏",this);
//设置工具栏的停靠位置为左边、右边和上边
toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea|Qt::TopToolBarArea);
//设置工具栏的浮空状态,将其关闭
toolBar->setFloatable(false);
//将打开文件、保存文件和关闭动作添加到工具栏中
toolBar->addAction(openFileMenu);
toolBar->addAction(saveFileMenu);
toolBar->addAction(closeMenu);
//将工具栏添加到主窗口中,并设置默认停靠位置为上边
this->addToolBar(Qt::TopToolBarArea,toolBar);
//添加了分割线
toolBar->addSeparator();
//设置字体和颜色按钮的图标并添加到工具栏中
FontButton=new QToolButton(toolBar);
FontButton->setText("字体");
FontButton->setIcon(QIcon(":/resimage/Font.png"));
//添加按钮
toolBar->addWidget(FontButton);
ColorButton=new QToolButton(toolBar);
ColorButton->setText("颜色");
ColorButton->setIcon(QIcon(":/resimage/Color.png"));
toolBar->addWidget(ColorButton);
//添加分割线
toolBar->addSeparator();

addSeparator() 是 Qt 框架中用于在菜单、工具栏或布局中插入分隔符的常用方法。

addWidget() 允许将任意 QWidget 子类‌(如 QToolButtonQLabelQComboBox 等)直接添加到工具栏中。

效果如下:

连接信号和槽函数:

打开文件:

点击打开文件之后设置一个文件弹窗,然后选择文件进行打开,将文件内容写入到文本编辑框中进行显示。

connect(openFileMenu,&QAction::triggered,this,[=](){QString FileDir=QFileDialog::getOpenFileName(this,"文件管理","./","所有文件(*.*);;文本文件(*.txt);;源码(*.cpp *.h *.c)");if(FileDir.isNull()){return;}QFile file(FileDir);file.open(QIODevice::ReadOnly);if(!file.isOpen()){QMessageBox::information(this,"提示","文件打开失败",QMessageBox::Ok);return;}textEdit->clear();while(!file.atEnd()){textEdit->append(QString(file.readAll()));}file.close();
});

可以看到getOpenFileName()函数的返回值是QString,所以创建一个QString类型的变量来接收返回的文件路径。对其进行判断是否为空,判断是否选择了文件,如果没有选择直接结束,如果选择了文件,那么创建一个QFile类来对该文件进行操作,设置为只读操作,判断是否成功打开,如果没有成功打开,那么弹出提示框并结束。如果打开,那么将文件中的内容写入到文本编辑框中。

保存文件:

connect(saveFileMenu,&QAction::triggered,this,[=](){QString FileDir=QFileDialog::getSaveFileName(this,"资源管理","./","所有文件(*.*);;文本文件(*.txt);;编译文件(*.cpp *.h *.c)");if(FileDir.isNull()){return;}QFile file(FileDir);file.open(QIODevice::WriteOnly|QIODevice::Truncate);if(!file.isOpen()){QMessageBox::information(this,"提示","保存文件失败",QMessageBox::Ok);return;}file.write(textEdit->document()->toPlainText().toStdString().c_str());file.close();
});

保存文件和打开文件整体上流程是相同的,不同的是,必须将创建的QFile类的权限设置为可写,这样才能将文本编辑框中的文本写入到创建的文件当中。

textEdit->document()->toPlainText()
获取文本编辑控件中的纯文本内容(去除富文本格式),返回QString类型对象。

toStdString()
QString转换为C++标准库的std::string类型,便于跨平台处理字符串编码。

c_str()
std::string转换为C风格字符串(const char*),这是QFile::write()方法所需的参数类型。

file.write()
调用QFile的写入方法,将转换后的字符串内容写入已打开的文件中。需确保文件已通过open()以可写模式(如QIODevice::WriteOnly)打开。

关闭:

connect(closeMenu,&QAction::triggered,this,[=](){this->close();
});

直接关闭当前窗口。

字体设置:

connect(FontButton,&QToolButton::clicked,this,[=](){bool ok=false;QFont font=QFontDialog::getFont(&ok,this);if(!ok){return;}textEdit->setFont(font);textEdit->setCurrentFont(font);
});

bool ok=false;
声明布尔变量ok用于接收字体选择是否成功的状态,初始值为false。

QFont font=QFontDialog::getFont(&ok,this);
调用静态函数QFontDialog::getFont()打开字体选择对话框。

参数&ok传递ok变量的地址,对话框关闭后会更新其值(true表示用户确认选择),参数this指定父窗口,返回值是用户选择的QFont对象。

if(!ok) return;
如果用户取消选择(ok为false),则直接返回不执行后续操作。

textEdit->setFont(font);
将选择的字体应用到QTextEdit控件的全局字体样式。

textEdit->setCurrentFont(font);
设置当前光标位置或选中文本的字体样式,会覆盖全局字体设置。
与setFont()的区别在于:setCurrentFont()仅影响当前选区/插入点的格式,而setFont()影响整个控件。

颜色设置:

connect(ColorButton,&QToolButton::clicked,this,[=](){QColor color=QColorDialog::getColor(QColor(Qt::white),this,"颜色框");if(!color.isValid()){return;}QTextCharFormat tcfmp;tcfmp.setForeground(QBrush(color));textEdit->mergeCurrentCharFormat(tcfmp);
});

通过QColorDialog::getColor()静态方法弹出颜色选择窗口,参数QColor(Qt::white)设置默认初始颜色为白色,this指定父窗口,"颜色框"为对话框标题。若用户取消选择或关闭窗口,返回的color.isValid()为false,直接退出函数。

QTextCharFormat类是Qt框架中用于处理富文本字符格式化的核心类,继承自QTextFormat,主要用于设置和修改文本的视觉属性和功能特性。创建QTextCharFormat对象tcfmp,调用setForeground()方法将用户选择的颜色(通过QBrush包装)设置为文本前景色。该操作会修改格式对象中的字体颜色属性。

mergeCurrentCharFormat(tcfmp)是Qt富文本处理中的关键方法,用于将指定的字符格式(QTextCharFormat对象)合并到当前光标选区或插入点位置,通过textEdit->mergeCurrentCharFormat(tcfmp)将设置好的文本格式合并到当前光标选区或输入位置。若存在选中文本则修改选中部分颜色,否则对后续输入文本生效。

完整代码:

MainWindow代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include 
#include 
#include 
#include 
#include 
#include 
#include 
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{Q_OBJECT
public:MainWindow(QWidget *parent = nullptr);~MainWindow();void createMenuBar();
private:Ui::MainWindow *ui;QMenuBar* newmenuBar;QMenu* FileMenu;QAction* openFileMenu;QAction* saveFileMenu;QAction* closeMenu;QToolBar* toolBar;QToolButton* FontButton;QToolButton* ColorButton;QTextEdit* textEdit;
};
#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);this->setWindowTitle("文件编辑器");this->setWindowIcon(QIcon(":/resimage/downloaded-image.png"));textEdit=new QTextEdit(this);this->setCentralWidget(textEdit);createMenuBar();connect(openFileMenu,&QAction::triggered,this,[=](){QString FileDir=QFileDialog::getOpenFileName(this,"文件管理","./","所有文件(*.*);;文本文件(*.txt);;源码(*.cpp *.h *.c)");if(FileDir.isNull()){// QMessageBox::information(this,"提示","文件打开失败",QMessageBox::Ok);return;}QFile file(FileDir);file.open(QIODevice::ReadOnly);if(!file.isOpen()){QMessageBox::information(this,"提示","文件打开失败",QMessageBox::Ok);return;}textEdit->clear();while(!file.atEnd()){textEdit->append(QString(file.readAll()));}file.close();});connect(saveFileMenu,&QAction::triggered,this,[=](){QString FileDir=QFileDialog::getSaveFileName(this,"资源管理","./","所有文件(*.*);;文本文件(*.txt);;编译文件(*.cpp *.h *.c)");if(FileDir.isNull()){return;}QFile file(FileDir);file.open(QIODevice::WriteOnly|QIODevice::Truncate);if(!file.isOpen()){QMessageBox::information(this,"提示","保存文件失败",QMessageBox::Ok);return;}file.write(textEdit->document()->toPlainText().toStdString().c_str());file.close();});connect(FontButton,&QToolButton::clicked,this,[=](){bool ok=false;QFont font=QFontDialog::getFont(&ok,this);if(!ok){return;}textEdit->setFont(font);textEdit->setCurrentFont(font);});connect(ColorButton,&QToolButton::clicked,this,[=](){QColor color=QColorDialog::getColor(QColor(Qt::white),this,"颜色框");if(!color.isValid()){return;}QTextCharFormat tcfmp;tcfmp.setForeground(QBrush(color));textEdit->mergeCurrentCharFormat(tcfmp);});connect(closeMenu,&QAction::triggered,this,[=](){this->close();});
}
MainWindow::~MainWindow()
{delete ui;
}
void MainWindow::createMenuBar()
{newmenuBar=this->menuBar();this->setMenuBar(newmenuBar);//创建文件菜单项FileMenu=new QMenu("文件");newmenuBar->addMenu(FileMenu);//添加文件子菜单项openFileMenu=new QAction(QIcon(":/resimage/open.png"),"打开文件");openFileMenu->setShortcut(QKeySequence("Ctrl+O"));FileMenu->addAction(openFileMenu);saveFileMenu=new QAction(QIcon(":/resimage/save.png"),"保存文件");saveFileMenu->setShortcut(QKeySequence("Ctrl+S"));FileMenu->addAction(saveFileMenu);closeMenu=new QAction(QIcon(":/resimage/close.png"),"退出");closeMenu->setShortcut(QKeySequence("Ctrl+X"));FileMenu->addAction(closeMenu);//创建工具栏toolBar=new QToolBar("工具栏",this);toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea|Qt::TopToolBarArea);toolBar->setFloatable(false);toolBar->addAction(openFileMenu);toolBar->addAction(saveFileMenu);toolBar->addAction(closeMenu);this->addToolBar(Qt::TopToolBarArea,toolBar);toolBar->addSeparator();FontButton=new QToolButton(toolBar);FontButton->setText("字体");FontButton->setIcon(QIcon(":/resimage/Font.png"));toolBar->addWidget(FontButton);ColorButton=new QToolButton(toolBar);ColorButton->setText("颜色");ColorButton->setIcon(QIcon(":/resimage/Color.png"));toolBar->addWidget(ColorButton);toolBar->addSeparator();
}

主函数:

#include "mainwindow.h"
#include 
int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}
http://www.hskmm.com/?act=detail&tid=21044

相关文章:

  • Java EE初阶启程记05---线程安全 - 指南
  • DataGridView表格控件使用说明
  • 题解:P7126 [Ynoi2008] rdCcot
  • 个人微信机器人开发api接口
  • MyBatis技术详解:从入门到高效开发 - 详解
  • 解码数据结构队列
  • 解决升级 Windows 11 24H2 后 NAS 共享无法显示的问题
  • 【还未找到原题】宝石(GEM) - Harvey
  • 第八篇
  • C# AStar 算法 - 实际应用
  • nocobase 源码安装
  • 航司网站url后缀参数FECU分析
  • 子网掩码完全指南:从入门到精通
  • 微信群机器人API
  • 9月29号
  • 【CF19E】Fairy - Harvey
  • Python从入门到实战 (14):工具落地:用 PyInstaller 打包 Python 脚本为可执行文件 - 实践
  • Harmony实现流转开发之音乐播放器跨设备流转 - 实践
  • 软件工程中线性回归应用
  • 解决秒杀高并发的一些方案
  • 构建移动网关:Air780EPM用4G为WiFi和LAN设备供网
  • 9.29模拟赛总结
  • 多corner综合
  • 优化 if/else 的四种设计模式
  • Day11-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\oop\demo06
  • 牛客周赛 Round 111
  • OpenLayers地图交互 -- 章节十一:拖拽材料交互详解
  • 2025年人工智能与智能装备国际学术会议(AIIE 2025)
  • 通过IDOR实现权限提升导致未授权用户注入
  • APUE学习笔记之基础知识(一) - Invinc