怎样制作单页网站,校园网站建设培训简讯,网站建设的目的包含哪些方面,公司主页设计图片文章目录 引言项目功能介绍1. **文件操作**2. **文本编辑功能**3. **撤销与重做**4. **剪切、复制与粘贴**5. **文本查找与替换**6. **打印功能**7. **打印预览**8. **设置字体颜色**9. **设置字号**10. **设置字体**11. **左对齐**12. **右对齐**13. **居中对齐**14. **两侧对… 文章目录 引言项目功能介绍1. **文件操作**2. **文本编辑功能**3. **撤销与重做**4. **剪切、复制与粘贴**5. **文本查找与替换**6. **打印功能**7. **打印预览**8. **设置字体颜色**9. **设置字号**10. **设置字体**11. **左对齐**12. **右对齐**13. **居中对齐**14. **两侧对齐**15. **加粗**16. **斜体**17. **下划线**18. **设置项目符号** 代码解析(部分)1. **剪切cut**2. **复制copy**3. **粘贴paste**4. **撤销undo**5. **重做redo**6. **加粗setBold**7. **斜体setItalic**8. **下划线setUnderline**9. **设置字体setFont**10. **设置字号setSize**11. **设置文本颜色setTextColor**12. **设置背景颜色setBackgroundColor**13. **设置左对齐setLeftAlignment**14. **设置居中对齐setCenterAlignment**15. **设置右对齐setRightAlignment** 源代码mainwindow.htextedit.hmainwindow.cpptextedit.cppmain.cpp 总结1. **初始化与UI设置**2. **文本操作功能**3. **文本格式化功能**4. **文本对齐功能**5. **功能实现的信号与槽机制** 引言
文本编辑器是每个程序员日常工作中不可或缺的工具而开发一个属于自己的文本编辑器则是许多开发者的梦想。作为一名开发者我也一直渴望能够打造一个既简单高效又能满足个性化需求的文本编辑器。经过一段时间的探索与实践我终于完成了这个项目——WPS一个基于Qt框架开发的文本编辑器。 在这篇博客中我将详细介绍如何利用Qt开发一个具备文件操作、文本编辑、撤销重做等常用功能的文本编辑器。我会从项目的设计思路、功能实现、代码分析等方面进行详细讲解并分享开发过程中遇到的挑战及解决方案。无论你是刚接触Qt的初学者还是想要深入理解Qt应用开发的开发者都可以从中获得一些启发与技巧。
项目功能介绍
在这个项目中WPS文本编辑器 实现了一些常见且实用的文本编辑功能旨在提供一个简单高效的写作和编辑体验。以下是本项目所具备的主要功能 1. 文件操作
新建文件用户可以创建一个新的空白文本文件开始书写或编辑。打开文件用户可以从本地磁盘中选择一个现有文件并加载到编辑器中支持标准的文本文件格式如 .txt。保存文件支持将编辑器中的内容保存到指定的文件路径中。用户也可以选择“另存为”来保存为不同的文件名或路径。文件另存为提供了将当前编辑的文件另存为不同文件名或路径的功能便于文件版本管理。
2. 文本编辑功能
文本输入与编辑用户可以在编辑器中自由输入文本支持文本的插入与删除。文本格式化提供基本的文本格式化功能如字体、字号、颜色等调整满足用户对文本样式的基本需求。文本对齐与换行支持文本的左对齐、右对齐、居中对齐等基本对齐操作以及自动换行功能保证文本编辑的灵活性与美观性。
3. 撤销与重做
撤销允许用户在误操作或修改后快速撤回到之前的状态使得编辑过程更加安全和无忧。重做支持撤销操作的反向恢复方便用户重新进行某些操作提升编辑的灵活性。
4. 剪切、复制与粘贴
剪切用户可以将选中的文本剪切并保存在剪贴板中方便移动文本内容。复制复制选中的文本保留原内容不变用户可以在其他地方粘贴。粘贴将剪贴板中的内容粘贴到当前文本光标位置。
5. 文本查找与替换
查找功能允许用户在文本中进行关键字查找定位到相应内容。替换功能提供查找到指定文本后将其替换为新的文本内容提升编辑效率。
6. 打印功能
打印功能允许用户将文本内容直接打印到纸张上。用户可以通过点击“打印”按钮来调用系统默认的打印对话框选择打印机及其他打印设置并将当前文档打印出来。
7. 打印预览
打印预览功能提供用户在实际打印前预览文档的打印效果。这可以帮助用户查看文本是否排版正确是否需要调整格式确保打印效果符合预期。用户通过点击“打印预览”按钮来进入此模式。
8. 设置字体颜色
用户可以通过此功能设置文本的字体颜色。点击“设置字体颜色”按钮后会弹出颜色选择框用户可以选择不同的颜色以改变文本的显示效果。这个功能帮助用户根据需要突出显示或装饰文本内容。
9. 设置字号
通过设置字号用户可以调整文本的大小。点击“设置字号”按钮后用户可以从下拉菜单中选择一个预设的字号或者输入自定义的数字值以改变文档中所有或选定部分文本的显示大小。
10. 设置字体
该功能允许用户选择文本的字体。通过点击“设置字体”按钮用户可以从字体选择框中选择不同的字体样式如“宋体”“Arial”或“Times New Roman”等从而调整文档的整体风格。
11. 左对齐
左对齐功能将文本与页面的左边缘对齐。用户可以点击“左对齐”按钮确保段落中的文本从左边缘开始显示常用于大多数书面内容。
12. 右对齐
右对齐功能将文本与页面的右边缘对齐。点击“右对齐”按钮后用户可以将段落中的文本从右边缘开始显示这对于一些语言如阿拉伯语或特殊排版是非常重要的。
13. 居中对齐
居中对齐功能将文本居中显示在页面上。点击“居中对齐”按钮后文中的所有文本会被自动居中确保文本在页面上的位置对称且整齐。
14. 两侧对齐
两侧对齐即“对齐两端”功能使文本在左右两端同时对齐。这会通过调整单词之间的间距来实现文本两端对齐通常用于报纸、杂志等印刷物的排版。
15. 加粗
加粗功能允许用户将文本设置为加粗格式。点击“加粗”按钮后选中的文本将显示为加粗样式常用于突出显示重要的内容或标题。
16. 斜体
斜体功能允许用户将文本设置为斜体样式。点击“斜体”按钮后选中的文本将倾斜通常用于强调、书名、外语词汇或引用内容。
17. 下划线
下划线功能为选定的文本添加下划线效果。点击“下划线”按钮后文本下方会出现一条线通常用于强调或标注链接文本。
18. 设置项目符号
设置项目符号功能允许用户在文本中插入项目符号例如圆点、方块等并创建无序列表。用户可以通过点击“项目符号”按钮快速将选中的段落转化为项目符号列表帮助整理和清晰地展示信息。此功能适用于创建清单、步骤说明等。
代码解析(部分)
1. 剪切cut
void TextEditor::cut()
{QTextCursor cursor textEdit-textCursor(); // 获取当前光标位置if (cursor.hasSelection()) {textEdit-cut(); // 如果有选中的文本执行剪切操作}
}textEdit-textCursor() 获取当前 QTextEdit 控件的文本光标 (QTextCursor)。cursor.hasSelection() 检查当前光标位置是否有选中的文本。如果有选中的文本调用 textEdit-cut() 执行剪切操作将选中的文本从编辑器中删除并复制到剪贴板。 2. 复制copy
void TextEditor::copy()
{QTextCursor cursor textEdit-textCursor(); // 获取当前光标位置if (cursor.hasSelection()) {textEdit-copy(); // 如果有选中的文本执行复制操作}
}textEdit-textCursor() 获取当前的文本光标。cursor.hasSelection() 检查是否选中了文本。如果选中了文本调用 textEdit-copy() 将选中的文本复制到剪贴板。 3. 粘贴paste
void TextEditor::paste()
{textEdit-paste(); // 将剪贴板的内容粘贴到光标当前位置
}textEdit-paste() 会将剪贴板中的内容粘贴到当前光标的位置。如果剪贴板没有内容则不会有任何变化。 4. 撤销undo
void TextEditor::undo()
{textEdit-undo(); // 撤销上一步操作
}textEdit-undo() 执行撤销操作即撤回上一步在文本编辑器中做的更改。例如撤回输入的文字或删除的内容。 5. 重做redo
void TextEditor::redo()
{textEdit-redo(); // 重做上一步撤销的操作
}textEdit-redo() 执行重做操作即将撤销的操作恢复。如果没有撤销操作则此操作无效。 6. 加粗setBold
void TextEditor::setBold()
{QTextCharFormat format;format.setFontWeight(QFont::Bold); // 设置字体为加粗textEdit-mergeCurrentCharFormat(format); // 将格式应用到当前选中的文本
}QTextCharFormat format 创建一个 QTextCharFormat 对象用来设置文本格式。format.setFontWeight(QFont::Bold) 设置字体加粗。textEdit-mergeCurrentCharFormat(format) 将新的字体格式应用到当前选中的文本。 7. 斜体setItalic
void TextEditor::setItalic()
{QTextCharFormat format;format.setFontItalic(true); // 设置字体为斜体textEdit-mergeCurrentCharFormat(format); // 将格式应用到当前选中的文本
}format.setFontItalic(true) 设置字体为斜体。textEdit-mergeCurrentCharFormat(format) 将斜体格式应用到当前选中的文本。 8. 下划线setUnderline
void TextEditor::setUnderline()
{QTextCharFormat format;format.setFontUnderline(true); // 设置字体为下划线textEdit-mergeCurrentCharFormat(format); // 将格式应用到当前选中的文本
}format.setFontUnderline(true) 设置字体加下划线。textEdit-mergeCurrentCharFormat(format) 将下划线格式应用到当前选中的文本。 9. 设置字体setFont
void TextEditor::setFont()
{bool ok;QFont font QFontDialog::getFont(ok, textEdit-currentFont(), this); // 弹出字体选择对话框if (ok) {textEdit-setCurrentFont(font); // 设置当前文本编辑框的字体}
}QFontDialog::getFont(ok, textEdit-currentFont(), this) 弹出一个字体选择对话框允许用户选择字体。如果用户点击确认返回选择的字体。textEdit-setCurrentFont(font) 将用户选择的字体设置到文本编辑器中。 10. 设置字号setSize
void TextEditor::setSize()
{bool ok;int size QInputDialog::getInt(this, tr(选择字号), tr(字号:), textEdit-currentFont().pointSize(), 1, 72, 1, ok); // 弹出字号输入框if (ok) {QFont font textEdit-currentFont();font.setPointSize(size); // 设置字体大小textEdit-setCurrentFont(font); // 更新文本编辑器字体}
}QInputDialog::getInt 弹出一个输入框允许用户选择字号。font.setPointSize(size) 设置新的字体大小。textEdit-setCurrentFont(font) 更新文本编辑器中的字体。 11. 设置文本颜色setTextColor
void TextEditor::setTextColor()
{QColor color QColorDialog::getColor(textEdit-textColor(), this); // 弹出颜色选择对话框if (color.isValid()) {QTextCharFormat format;format.setForeground(color); // 设置前景色文本颜色textEdit-mergeCurrentCharFormat(format); // 应用颜色}
}QColorDialog::getColor 弹出颜色选择对话框允许用户选择文本颜色。format.setForeground(color) 设置选中的文本颜色。textEdit-mergeCurrentCharFormat(format) 将颜色应用到当前选中的文本。 12. 设置背景颜色setBackgroundColor
void TextEditor::setBackgroundColor()
{QColor color QColorDialog::getColor(textEdit-textBackgroundColor(), this); // 弹出颜色选择对话框if (color.isValid()) {QTextCharFormat format;format.setBackground(color); // 设置背景颜色textEdit-mergeCurrentCharFormat(format); // 应用背景颜色}
}QColorDialog::getColor 弹出颜色选择对话框允许用户选择背景颜色。format.setBackground(color) 设置选中文本的背景颜色。textEdit-mergeCurrentCharFormat(format) 将背景颜色应用到当前选中的文本。 13. 设置左对齐setLeftAlignment
void TextEditor::setLeftAlignment()
{QTextBlockFormat format;format.setAlignment(Qt::AlignLeft); // 设置为左对齐textEdit-mergeCurrentBlockFormat(format); // 将对齐方式应用到当前选中的文本
}format.setAlignment(Qt::AlignLeft) 设置对齐方式为左对齐。textEdit-mergeCurrentBlockFormat(format) 将左对齐的格式应用到当前选中的文本块。 14. 设置居中对齐setCenterAlignment
void TextEditor::setCenterAlignment()
{QTextBlockFormat format;format.setAlignment(Qt::AlignCenter); // 设置为居中对齐textEdit-mergeCurrentBlockFormat(format); // 将对齐方式应用到当前选中的文本
}format.setAlignment(Qt::AlignCenter) 设置对齐方式为居中对齐。textEdit-mergeCurrentBlockFormat(format) 将居中对齐的格式应用到当前选中的文本块。 15. 设置右对齐setRightAlignment
void TextEditor::setRightAlignment()
{QTextBlockFormat format;format.setAlignment(Qt::AlignRight); // 设置为右对齐textEdit-mergeCurrentBlockFormat(format); // 将对齐方式应用到当前选中的文本
}format.setAlignment(Qt::AlignRight) 设置对齐方式为右对齐。textEdit-mergeCurrentBlockFormat(format) 将右对齐的格式应用到当前选中的文本块。
源代码
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include QMainWindow
#include QTextEdit
#include QMdiSubWindowQT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass TextEdit;
class QPrinter;
class QActionGroup;
class QSignalMapper;
class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();private slots:void initWindowAction(); //初始化窗体action状态void initTextAction(bool b); //初始化文本action状态void on_New_action_triggered();void on_Open_action_triggered();void on_Save_action_triggered();void on_Save_save_action_triggered();void on_Print_action_triggered();void on_Print_preview_action_triggered();void on_Undo_action_triggered();void on_Redo_action_triggered();void on_Cut_action_triggered();void on_Copy_action_triggered();void on_paste_action_triggered();void on_Bold_action_triggered();void on_Italic_action_triggered();void on_Under_action_triggered();void on_Fontcombosize_activated(const QString arg1);void on_fontComboBox_activated(const QString arg1);void on_Left_action_triggered();void on_Center_action_triggered();void on_Right_action_triggered();void on_Justfiy_action_triggered();void on_Colse_action_triggered();void on_Colse_all_action_triggered();void on_Tittle_action_triggered();void on_Cascade_action_triggered();void on_Next_action_triggered();void on_previous_action_triggered();void on_About_action_triggered();void on_Color_action_triggered();void on_standardcomboBox_activated(int index);void setActiveSubWindow(QWidget* widget);private:Ui::MainWindow *ui;void init(); //初始化void initMdiArea(); //初始化Mdi控件,初始化进度条void initFontSize(); //初始化字号TextEdit* activateWindow(); //获取Mdi中的活动窗体QMdiSubWindow* findSubWindow(const QString docname); //判断MDI中是否有相同文件名的文件void printPreview(QPrinter *printer); //打印预览功能void Start_Past(); //根据系统粘贴板状态控制past粘贴功能void Select(); //判断文本格式,是否加粗,是否有下划线等void closeEvent(QCloseEvent *event); //重写关闭事件void addSubWindowAction(); //使用信号映射器实现标题栏窗口选择窗口功能public:QActionGroup* actionGroup;QSignalMapper* signalMapper;};
#endif // MAINWINDOW_H
textedit.h
#ifndef TEXTEDIT_H
#define TEXTEDIT_H
#include QTextEditclass TextEdit : public QTextEdit
{Q_OBJECT
public:TextEdit(QWidget *parentnullptr);~TextEdit();public:void initNewDoc(); //初始化文档void initOpenDoc(const QString docName); //初始化标题QString getDocFilePath() const; //返回绝对路径和文件名bool loadDoc(const QString docName); //读取文本显示出来bool SaveDoc(); //保存文档bool Save_save_Doc(); //另存为bool writeToDoc(const QString docName); //保存功能void closeEvent(QCloseEvent *event); //重写关闭事件bool promptSave();QString getDocFileName() const; //获取文档名称private slots:void setWindowModify(); //设置windowModified属性private:static int docNo; //静态数据,文档编号,静态数据成员存储在静态数据区,所有类共享副本//类存储在堆区,静态数据成员属于类,但是不在一块内存,所以要类内声明,类外定义QString docWindowTitle; //标题QString docFilePath_Name; //文档的绝对路径和名称QString docFileName; //文档的名称
};#endif // TEXTEDIT_H
mainwindow.cpp
#include mainwindow.h
#include ui_mainwindow.h
#include textedit.h
#include QFontDatabase
#include QFont
#include QMdiArea
#include QFileDialog
#include QPrintDialog
#include QPainter
#include QPrinter
#include QPrintPreviewDialog
#include QApplication
#include QClipboard
#include QtDebug
#include QColorDialog
#include QCloseEvent
#include QMessageBox
#include QTextCursor
#include QTextList
#include QTextBlockFormat
#include QSignalMapper
#include QActionGroupMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);init(); //初始化
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::init()
{initMdiArea(); //初始化MdiinitFontSize(); //初始化字体框initWindowAction(); //初始化窗体action状态//initTextAction(false); //初始化文本action状态//当在mdi中添加活动窗体时会触发subWindowActivated信号,关闭窗口会返回0connect(ui-mdiArea,QMdiArea::subWindowActivated,this,MainWindow::initWindowAction);//获取系统剪贴板的指针返回类型为,QClipboard *QClipboard *clipQApplication::clipboard();//每当剪贴板的内容发生变化时都会触发这个信号connect(clip,QClipboard::dataChanged,this,MainWindow::Start_Past);signalMapper new QSignalMapper(this);actionGroup new QActionGroup(this);actionGroup-setExclusive(true); //排他性connect(ui-menu_T,QMenu::aboutToShow,this,MainWindow::addSubWindowAction);connect(signalMapper,SIGNAL(mapped(QWidget*)), this,SLOT(setActiveSubWindow(QWidget*)));
}void MainWindow::initMdiArea()
{//设置背景色ui-mdiArea-setBackground(QBrush(Qt::white));//设置滚动条ui-mdiArea-setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);ui-mdiArea-setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}void MainWindow::initFontSize()
{ui-Fontcombosize-clear();//使用QFontDatabase数据库设置字号//standardSizes:QFontDatabase的静态函数,返回系统字号for(int fontsize : QFontDatabase::standardSizes()){ui-Fontcombosize-addItem(QString::number(fontsize));}QFont fontQApplication::font();int appfontsizefont.pointSize();//int sizeindexui-Fontcombosize-findText(QString::asprintf(%d,appfontsize));int sizeindexui-Fontcombosize-findText(QString::number(appfontsize));ui-Fontcombosize-setCurrentIndex(sizeindex);
}void MainWindow::initWindowAction()
{bool activate(activateWindow()!nullptr);if(!activate){initTextAction(false);}ui-paste_action-setEnabled(activate);ui-Save_action-setEnabled(activate);ui-Save_save_action-setEnabled(activate);ui-Print_action-setEnabled(activate);ui-Print_preview_action-setEnabled(activate);ui-Undo_action-setEnabled(activate);ui-Redo_action-setEnabled(activate);ui-Colse_action-setEnabled(activate);ui-Colse_all_action-setEnabled(activate);ui-Tittle_action-setEnabled(activate);ui-Cascade_action-setEnabled(activate);ui-previous_action-setEnabled(activate);ui-Next_action-setEnabled(activate);ui-standardcomboBox-setEnabled(activate);ui-Fontcombosize-setEnabled(activate);ui-fontComboBox-setEnabled(activate);
}TextEdit *MainWindow::activateWindow()
{//activeSubWindow用于返回当前活动的窗体有窗体返回QMdiSubWindow指针,没有返回0QMdiSubWindow* windowui-mdiArea-activeSubWindow();if(window){//widget:返回 QMdiSubWindow 中实际显示的主控件return qobject_castTextEdit*(window-widget());}return nullptr;
}void MainWindow::initTextAction(bool b)
{ui-Cut_action-setEnabled(b);ui-Copy_action-setEnabled(b);ui-Color_action-setEnabled(b);ui-Bold_action-setEnabled(b);ui-Italic_action-setEnabled(b);ui-Under_action-setEnabled(b);ui-Left_action-setEnabled(b);ui-Center_action-setEnabled(b);ui-Right_action-setEnabled(b);ui-Justfiy_action-setEnabled(b);ui-Justfiy_action-setEnabled(b);
}void MainWindow::on_New_action_triggered()
{TextEdit*Editnew TextEdit;ui-mdiArea-addSubWindow(Edit);//会把Edit的父对象自动设置为mdi//copyAvailable选中文本或者取消选择时会触发信号connect(Edit,TextEdit::copyAvailable,this,MainWindow::initTextAction);//每次选中文本的时候都会触发connect(Edit,TextEdit::copyAvailable,this,MainWindow::Select);Edit-initNewDoc();Edit-show();statusBar()-showMessage(新建成功,3000);
}void MainWindow::on_Open_action_triggered()
{QString FileNameQFileDialog::getOpenFileName(this,打开文件,../,所有文件(*.*);;文本文件(*.txt),nullptr);if(!FileName.isEmpty()){QMdiSubWindow* subfindSubWindow(FileName); //判断文件是否已经存在,如果存在就设置为活动窗口,不存在就新增if(sub){ui-mdiArea-setActiveSubWindow(sub);return;}TextEdit* Editnew TextEdit;ui-mdiArea-addSubWindow(Edit);//copyAvailable选中文本或者取消选择时会触发信号connect(Edit,TextEdit::copyAvailable,this,MainWindow::initTextAction);//每次选中文本的时候都会触发connect(Edit,TextEdit::copyAvailable,this,MainWindow::Select);if(Edit-loadDoc(FileName)){ //初始化EditstatusBar()-showMessage(文档已打开,3000); //让状态栏显示三秒钟Edit-show();}else{Edit-close();}}return;
}QMdiSubWindow *MainWindow::findSubWindow(const QString docname)
{QString filepathQFileInfo(docname).canonicalFilePath(); //返回文件绝对路径for(QMdiSubWindow* sub:ui-mdiArea-subWindowList()){ //遍历MDI中的活动窗口TextEdit *editqobject_castTextEdit*(sub-widget());//强转为TextEdit类型if(edit-getDocFilePath()filepath){ //如果找到了一样的文件(绝对路径)就直接返回真否则返回空return sub;}}return nullptr;
}void MainWindow::on_Save_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){Edit-SaveDoc();}}void MainWindow::on_Save_save_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){Edit-Save_save_Doc();}
}void MainWindow::on_Print_action_triggered()
{QPrinter print;print.setResolution(QPrinter::HighResolution);//是 QPrinter 中的一个常量它表示一个高分辨率的打印设置通常是 600 DPI 或更高。//使用这个常量时打印机将尽可能以更高的质量进行打印适用于需要高质量输出的情况QPrintDialog printf_dialog(print,this);//在打印对话框中启用了“打印选定内容”选项允许用户选择打印文档中的一部分内容。printf_dialog.setOption(QAbstractPrintDialog::PrintSelection, true);//用户可以选择“打印选定内容”或者“打印整个文档”。printf_dialog.setOption(QAbstractPrintDialog::PrintSelection, true);TextEdit *textactivateWindow();if(printf_dialog.exec()QDialog::Accepted){text-print(print);}
}void MainWindow::on_Print_preview_action_triggered()
{// 获取当前活动的 TextEdit 控件假设这是你编辑文档的地方TextEdit* Edit activateWindow();if (!Edit) return; // 如果没有活动的窗口退出// 创建一个 QPrinter 对象它是用来控制打印机的QPrinter print;// 创建一个打印预览对话框传入 QPrinter 对象QPrintPreviewDialog preview(print, this);// 连接打印预览对话框的 paintRequested 信号到 printPreview 槽函数connect(preview, QPrintPreviewDialog::paintRequested, this, MainWindow::printPreview);// 弹出打印预览对话框,并且马上回触发信号与槽,打印到屏幕上// 如果用户点击了“打印”按钮即接受了打印预览则执行实际的打印if (preview.exec() QDialog::Accepted) { //实际打印到打印机上// 如果打印预览对话框的返回值是“Accepted”表示用户点击了打印按钮Edit-print(print); // 调用 TextEdit 的 print 方法执行打印}
}void MainWindow::printPreview(QPrinter *printer) //打印到屏幕上
{// 获取当前活动的 TextEdit 控件文档编辑器TextEdit* Edit activateWindow();// 如果有活动的 TextEdit 控件即有一个正在编辑的文档if (Edit) {// 使用传入的 QPrinter 对象执行打印Edit-print(printer);}
}void MainWindow::Start_Past()
{//获取系统剪贴板的指针返回类为QClipboard *QClipboard *clipQApplication::clipboard();QString pastTextclip-text(); //返回粘贴板中的文本if(!pastText.isEmpty()){ //判断是否存在文本ui-paste_action-setEnabled(true);}else{ui-paste_action-setEnabled(false);}
}void MainWindow::Select()
{TextEdit* EditactivateWindow();if(Edit){QTextCharFormat formatEdit-currentCharFormat();//判断字体是否加粗bool isBold(format.fontWeight()QFont::Bold);if(isBold){ui-Bold_action-setChecked(true);}else{ui-Bold_action-setChecked(false);}//判断是否斜体bool isitalicformat.fontItalic();if(isitalic){ui-Italic_action-setChecked(true);}else{ui-Italic_action-setChecked(false);}//判断是否下划线bool isUnderformat.fontUnderline();if(isUnder){ui-Under_action-setChecked(true);}else{ui-Under_action-setChecked(false);}}}void MainWindow::closeEvent(QCloseEvent *event)
{ui-mdiArea-closeAllSubWindows();if(ui-mdiArea-currentSubWindow()){event-ignore();}else{event-accept();}
}void MainWindow::addSubWindowAction()
{QListQAction* actionListactionGroup-actions();if(!actionList.isEmpty()){for(QAction* action:actionList){delete action;}}QListQMdiSubWindow * subWindowListui-mdiArea-subWindowList();if(!subWindowList.isEmpty()) ui-menu_T-addSeparator(); //添加分割线for(int i0;isubWindowList.count();i){//获取内嵌部件QMdiSubWindow* subWindowsubWindowList.at(i);TextEdit* Editqobject_castTextEdit*(subWindow-widget());if(Editnullptr){qDebug()转换失败!;}//设置需要添加的Action名称QString ACtion_NameQString(%1 %2).arg(i1).arg(Edit-getDocFileName());QAction *addActionui-menu_T-addAction(ACtion_Name);actionGroup-addAction(addAction);addAction-setCheckable(true);if(EditactivateWindow()) addAction-setChecked(true);connect(addAction, SIGNAL(triggered(bool)), signalMapper, SLOT(map()));connect(addAction, SIGNAL(triggered(bool)), this, SLOT(on_Center_action_triggered()));signalMapper-setMapping(addAction,subWindow);}
}void MainWindow::setActiveSubWindow(QWidget *widget)
{if(widget)ui-mdiArea-setActiveSubWindow(qobject_castQMdiSubWindow*(widget));
}void MainWindow::on_Undo_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){Edit-undo();}
}void MainWindow::on_Redo_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){Edit-redo();}
}void MainWindow::on_Cut_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){Edit-cut();}
}void MainWindow::on_Copy_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){Edit-copy();}
}void MainWindow::on_paste_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){Edit-paste();}
}void MainWindow::on_Bold_action_triggered()
{//使用QFont不能局部设置加粗,一加粗所有文本都加粗了,不能根据光标位置或者选中的文本单独进行加粗// TextEdit* EditactivateWindow();// if(Edit){// QFont fontEdit-font();// font.setBold(true);// Edit-setFont(font);// }TextEdit* EditactivateWindow();if(Edit){bool isCheckedui-Bold_action-isChecked();//设置文本字符格式的类。例如字体、颜色、加粗、斜体、下划线等。QTextCharFormat format;format.setFontWeight(isChecked ? QFont::Bold : QFont::Normal);//使用mergeCurrentCharFormat可以局部进行单独的设置Edit-mergeCurrentCharFormat(format);}
}void MainWindow::on_Italic_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){QTextCharFormat format;bool isItalicui-Italic_action-isChecked();format.setFontItalic(isItalic);Edit-mergeCurrentCharFormat(format);}
}void MainWindow::on_Under_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){QTextCharFormat format;bool isUnderui-Under_action-isChecked();format.setFontUnderline(isUnder);Edit-mergeCurrentCharFormat(format);}
}void MainWindow::on_Fontcombosize_activated(const QString arg1)
{TextEdit* EditactivateWindow();if(Edit){QTextCharFormat format;format.setFontPointSize(arg1.toInt());Edit-mergeCurrentCharFormat(format);}
}void MainWindow::on_fontComboBox_activated(const QString arg1)
{TextEdit* EditactivateWindow();if(Edit){QTextCharFormat format;format.setFontFamily(arg1);format.setFontPointSize(ui-Fontcombosize-currentText().toInt());Edit-mergeCurrentCharFormat(format);}
}void MainWindow::on_Left_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){Edit-setAlignment(Qt::AlignLeft);}
}void MainWindow::on_Center_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){Edit-setAlignment(Qt::AlignCenter);}
}void MainWindow::on_Right_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){Edit-setAlignment(Qt::AlignRight);}
}void MainWindow::on_Justfiy_action_triggered()
{TextEdit* EditactivateWindow();if(Edit){Edit-setAlignment(Qt::AlignJustify);}
}void MainWindow::on_Colse_action_triggered()
{// TextEdit* EditactivateWindow();// if(Edit){// QMdiSubWindow* windowqobject_castQMdiSubWindow*(Edit-parentWidget());// if(window){// window-close();// }// }//Active 活动ui-mdiArea-closeActiveSubWindow();
}void MainWindow::on_Colse_all_action_triggered()
{//All 所有ui-mdiArea-closeAllSubWindows();
}void MainWindow::on_Tittle_action_triggered()
{//tile 平铺ui-mdiArea-tileSubWindows();
}void MainWindow::on_Cascade_action_triggered()
{//cascade 层叠 SubWindows 子窗口ui-mdiArea-cascadeSubWindows();
}void MainWindow::on_Next_action_triggered()
{//activ 活动 activate 激活ui-mdiArea-activateNextSubWindow();
}void MainWindow::on_previous_action_triggered()
{//activ 活动 activate 激活 Previous 上一个ui-mdiArea-activatePreviousSubWindow();
}void MainWindow::on_Color_action_triggered()
{TextEdit *EditactivateWindow();if(Edit){QColor colorQColorDialog::getColor(Qt::black,this,选中字体颜色);if(color.isValid()){QTextCharFormat format;format.setForeground(color);Edit-mergeCurrentCharFormat(format);}}
}void MainWindow::on_standardcomboBox_activated(int index)
{// 获取当前活动窗口即 TextEdit 控件TextEdit *Edit activateWindow();if(Edit){// 如果下拉框选项为0即取消项目符号if(index 0){QTextCursor cursor Edit-textCursor(); // 获取当前光标对象cursor.beginEditBlock(); // 开始一个编辑块标记当前编辑操作的开始QTextList* list cursor.currentList(); // 获取当前光标所在的列表如果有的话if(list){ // 如果当前光标所在的文本是列表的一部分list-remove(cursor.block()); // 删除当前光标所在的文本块即当前列表项QTextBlockFormat blockFormat cursor.blockFormat(); // 获取当前块的格式blockFormat.setIndent(0); // 将当前块的缩进设置为 0cursor.setBlockFormat(blockFormat); // 应用修改后的格式}cursor.endEditBlock(); // 结束编辑块标记当前编辑操作的结束return; // 退出函数}// 根据下拉框选中的不同索引设置不同的列表样式QTextListFormat::Style style;switch (index){case 1:style QTextListFormat::ListDisc; // 圆点列表break;case 2:style QTextListFormat::ListCircle; // 圆圈列表break;case 3:style QTextListFormat::ListSquare; // 方形列表break;case 4:style QTextListFormat::ListDecimal; // 数字列表break;case 5:style QTextListFormat::ListLowerAlpha; // 小写字母列表break;case 6:style QTextListFormat::ListUpperAlpha; // 大写字母列表break;case 7:style QTextListFormat::ListLowerRoman; // 小写罗马数字列表break;case 8:style QTextListFormat::ListUpperRoman; // 大写罗马数字列表break;default:style QTextListFormat::ListStyleUndefined; // 未定义的列表样式break;}// 获取当前光标对象QTextCursor cursor Edit-textCursor();cursor.beginEditBlock(); // 开始编辑块// 获取当前块的格式并创建一个 QTextListFormat 对象来设置列表格式QTextBlockFormat blockFormat cursor.blockFormat();QTextListFormat listFormat;// 如果当前光标所在文本属于列表的一部分QTextList* list cursor.currentList();if(list){listFormat list-format(); // 获取该列表的格式list-remove(cursor.block()); // 删除当前光标所在的列表项blockFormat.setIndent(0); // 设置块缩进为 0cursor.setBlockFormat(blockFormat); // 应用新的块格式}// 设置列表样式为选中的样式listFormat.setStyle(style);// 使用新的列表格式创建一个列表cursor.createList(listFormat);cursor.endEditBlock(); // 结束编辑块}
}void MainWindow::on_About_action_triggered()
{QMessageBox::about(this,tr(关于应用),tr(这是一个WPS项目。\n版本1.0\n制作者:xiaohu));
}
textedit.cpp
#include textedit.h
#include QFileInfo
#include QFileDialog
#include QTextDocumentWriter
#include QCloseEvent
#include QMessageBox
#include QDebugint TextEdit::docNo1; //类外初始化静态数据成员
TextEdit::TextEdit(QWidget *parent):QTextEdit(parent)
{setAttribute(Qt::WA_DeleteOnClose); //关闭窗体时释放资源//initNewDoc();
}TextEdit::~TextEdit()
{}void TextEdit::initNewDoc()
{docFileNameQString(文档 %1).arg(docNo);docWindowTitledocFileName;//使用windowmodified机制,添加[*]占位符//当窗口显示的文档有未保存的更改,*号就会显示出来setWindowTitle(docWindowTitle [*]);/*document() 是 QTextEdit 类的一个成员函数返回当前编辑器中所使用的 QTextDocument 对象。QTextDocument 类负责管理和操作文本内容。contentsChanged 是 QTextDocument 类中的一个信号。它在文档的内容发生变化时发出。文档内容变化的原因可能是用户输入文本、删除文本或其他任何修改内容的操作。*/connect(document(),QTextDocument::contentsChanged,this,TextEdit::setWindowModify);
}void TextEdit::setWindowModify()
{//isModified返回文档是否被用户修改setWindowModified(document()-isModified());
}void TextEdit::initOpenDoc(const QString docName)
{docFilePath_NameQFileInfo(docName).canonicalFilePath(); //返回绝度路径,包含文件名docFileNameQFileInfo(docName).fileName(); //返回文档名称docWindowTitledocFileName QString::number(docNo); //设置标题setWindowTitle(docWindowTitle [*]); //设置标题并添加[*]占位符/*之所以要调用两次信号与槽,是因为信号与槽的生命周期和类是绑定的,比如说新建文档会新建一个类,那么这个时候就需要连接各种信号与槽,当关闭新建的窗口时,信号与槽就会解绑新建文档和打开文档是两个独立的功能,所绑定的信号与槽是不通用的,虽然有两个相同的类,但是内存都不同,所以每次New类的时候都需要重新绑定信号与槽*/connect(document(),QTextDocument::contentsChanged,this,TextEdit::setWindowModify);
}QString TextEdit::getDocFilePath() const
{return docFilePath_Name;
}bool TextEdit::loadDoc(const QString docName)
{if(!docName.isEmpty()){QFile file(docName);if(!file.exists()) return false; //判断文件是否存在if(!file.open(QFile::ReadOnly))return false; //打开文件QByteArray textfile.readAll(); //读取所有数据,返回值是二进制if(Qt::mightBeRichText(text)){ //判断文本内容是不是富文本setHtml(text); //富文本显示}else{setText(text); //纯文本显示}initOpenDoc(docName); //初始化打开的文档}return true;
}bool TextEdit::SaveDoc()
{if(document()-isModified()){ //如果文档被修改if(!docFilePath_Name.isEmpty()){ //如果路径不为空writeToDoc(docFilePath_Name);}else{return Save_save_Doc();}}return false;
}bool TextEdit::Save_save_Doc()
{QString docNameQFileDialog::getSaveFileName(this,另存为,../,HTML文档(*.html);;文本文档(*.txt));if(!docName.isEmpty()){return writeToDoc(docName);}return false;
}bool TextEdit::writeToDoc(const QString docName)
{QTextDocumentWriter docWriter(docName); //用于将QTextDocument对象中的文本内容保存到文件中,参数就是文件名if(docWriter.write(this-document())){ //写入文件,document是返回TexeEdit中的QTextDocument,这类是每个QTextEdit中都有的,负责存储和管理文本docFilePath_NameQFileInfo(docName).canonicalFilePath(); //更新路径,特别是另存为可能会改变路径document()-setModified(false); //设置文档状态未改动,设置内部为未修改setWindowModified(false); //取消窗口*号显示,设置ui界面*号消失}else{return false;}return true;
}void TextEdit::closeEvent(QCloseEvent *event)
{if(promptSave()){event-accept(); //表示你处理了事件事件结束不再传递。}else{event-ignore(); //表示不处理该事件让事件继续传递到其他地方或执行默认行为。}
}bool TextEdit::promptSave()
{//document()QTextDocument 是 Qt 的文本编辑框架的核心部分//isModified() 判断文档是否被修改过if(!document()-isModified())return true;QMessageBox::StandardButton res;
// resQMessageBox::warning(this,提示,QString(文档%1已修改,是否保存?).arg(getDocFileName()),
// QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);resQMessageBox::warning(this,提示,QString::asprintf(%s已修改,是否保存?,getDocFileName().toStdString().c_str()),QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);//qDebug()getDocFileName();if(resQMessageBox::Yes){return SaveDoc();}else if(resQMessageBox::No){return true;}else if(resQMessageBox::Cancel){return false;}return false;
}QString TextEdit::getDocFileName() const
{return docFileName;
}
main.cpp
#include mainwindow.h#include QApplicationint main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();return a.exec();
}
总结
这个项目实现了一个简单的文本编辑器功能包括文本的基本编辑、格式化、撤销重做、剪切复制粘贴、以及文本的对齐和字体设置等。通过 Qt 提供的控件和方法我们可以轻松地实现这些功能。下面是对整个代码实现的详细总结帮助你更好地理解每一部分功能和实现原理。
1. 初始化与UI设置
程序的第一步是初始化应用程序及其主界面创建一个 QMainWindow 窗口并在其中放置一个 QTextEdit 控件用于文本的显示和编辑。这是 Qt 中最常用的多行文本控件支持文本的插入、编辑和格式化。通过设置 QTextEdit用户能够直接与文本进行交互。
在构造函数中我们创建了菜单栏菜单项包括“文件”和“编辑”菜单“编辑”菜单下有撤销、重做、剪切、复制、粘贴等常见的文本操作“文件”菜单下可以实现文本的打开、保存和新建等功能。
2. 文本操作功能
文本操作功能是这段代码的核心部分主要包括以下几项常用的编辑功能 剪切cut 剪切操作通过 textEdit-cut() 实现。当用户点击剪切按钮时文本框中的选中文本会被剪切到系统剪贴板并从 QTextEdit 控件中删除。这是一个标准的文本编辑操作允许用户删除选中的文本并将其保留在剪贴板中以便后续粘贴使用。 复制copy 复制功能通过 textEdit-copy() 实现它会将选中的文本复制到系统剪贴板中而不会删除文本。这样用户可以将选中的内容复制并粘贴到其他地方。 粘贴paste 粘贴功能通过 textEdit-paste() 方法来实现用户可以从剪贴板中粘贴内容到当前光标的位置。粘贴功能在剪切和复制之后常用。 撤销undo与重做redo 这两个操作通过 textEdit-undo() 和 textEdit-redo() 实现。撤销功能允许用户回退到上一步的编辑状态例如撤销输入的文字或删除的文本而重做则是恢复上一步被撤销的操作。如果用户不小心撤销了操作重做操作可以将其恢复。这两个功能是所有文本编辑器中必不可少的功能确保用户能够灵活控制编辑历史。
3. 文本格式化功能
文本格式化功能是文本编辑器中的重要部分可以通过这些功能让文本变得更加生动和富有表现力。代码实现了以下格式化功能 加粗 使用 QTextCharFormat 和 setFontWeight() 来设置字体的粗细。通过 mergeCurrentCharFormat 方法将加粗格式应用到选中的文本。 斜体 通过 setFontItalic(true) 设置文本为斜体并通过 mergeCurrentCharFormat 应用到选中的文本区域。 下划线 设置 fontUnderline 为 true 来为文本添加下划线应用到选中的文本。 设置字体 使用 QFontDialog::getFont() 弹出一个字体选择对话框允许用户选择字体及其样式。选定字体后调用 setCurrentFont() 更新文本框中的字体样式。 设置字号 通过 QInputDialog::getInt() 弹出一个整数输入框让用户输入所需的字号。然后通过 setPointSize() 方法设置字体的大小从而改变文本的显示效果。 设置文本颜色 使用 QColorDialog::getColor() 获取用户选择的颜色并通过 setForeground() 方法将该颜色应用到选中的文本区域。 设置背景颜色 类似文本颜色设置使用 QColorDialog::getColor() 获取用户选择的颜色并通过 setBackground() 设置选中文本的背景色。
4. 文本对齐功能
文本对齐是文本编辑器中一个常见的功能通常包括左对齐、居中对齐、右对齐和两端对齐。在这段代码中我们使用了 QTextBlockFormat 来控制文本对齐方式 左对齐setAlignment(Qt::AlignLeft) 通过 QTextBlockFormat 设置文本的对齐方式为左对齐。 居中对齐setAlignment(Qt::AlignCenter) 将对齐方式设置为居中。 右对齐setAlignment(Qt::AlignRight) 将对齐方式设置为右对齐。 两端对齐setAlignment(Qt::AlignJustify) 设置文本为两端对齐方式使得文本在行内两边对齐通常用于文档排版。
这些对齐功能通过 textEdit-mergeCurrentBlockFormat() 方法应用到选中的文本区域允许用户根据需求选择合适的文本排版方式。
5. 功能实现的信号与槽机制
在 Qt 中信号与槽是处理用户输入和界面交互的核心机制。例如当用户点击菜单项时会触发相应的信号。然后这些信号会连接到相应的槽函数中槽函数执行相应的操作。例如点击“撤销”菜单项时信号会触发槽函数 undo()进而撤销文本编辑器中的操作。
信号与槽的连接使得界面与逻辑操作分离代码更为模块化、清晰。每个按钮或菜单项触发的操作都与相应的槽函数绑定保证了应用的灵活性和可扩展性。