前言
学习了有关Qt的基础知识,下面来做一个简单的案例---多文档文本编辑器,具有新建、打开、保存一个文件、设置字体、设置字号、文字的剪切、复制、粘贴、加粗、倾斜、下划线、设置字体颜色、左对齐、居中、右对齐、撤销、重做等功能。
一、设计目标
设计一个文本编辑器首先需要在ui界面设计一个界面,里面包含许多MainWindow类的对象,可以选择给对象添加一些图标来增加美观,设计界面后在MainWindow类的头文件声明所需要的类,在源文件MainWindow.cpp中通过信号与槽来实现相应的功能。
二、效果展示
三、设计过程
1.设计思路
1.1文件的打开和新建
新建文件的本质是打开一个新窗口然后保存,新建子窗口使用MainWindow类,打开文件需要先获取文件的路径,通过readAll函数可以将文件内容都给读出来,然后再在窗口中编辑。保存文件的原理也类似,读取文件后使用QByteAarry类型的值储存接收,需要注意的是QFile类不支持utf8编码,需要自己转换。
1.2设置字体和字号
需要用到QFontComboBox和QComboBox类,这里也是本次案例的一个难点,用了设置字体的筛选器setFontFilters(可缩放字体),还用了foreach循环,语法为:foreach(变量,容器)+语句。在connect函数中需要用到QTextCharFormat类获取字符的格式,再通过mergeFormat函数转换。
1.3设置字型和颜色
也是需要用到QTextCharFormat类获取字符的格式,不过比上面简单得多,只需要获取->变化即可,这里有个注意的点,点完对象字体变粗后再点一次取消,需要用到最后一句代码。颜色方面不同的是需要新建一个系统自带的颜色窗口。
1.4设置文字对齐撤销等
其他这些就简单了,只需要调用相应的函数即可,不理解的可以去帮助文档里查看。
2.核心代码
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(950,650);
Boldcheck = true;
Italiccheck=true;
UnderLinecheck=true;
//新建一个新窗口
connect(ui->actionnew,&QAction::triggered,[=](){
MainWindow*newWindow=new MainWindow;
newWindow->show();
});
//打开一个文件
connect(ui->actionopen,&QAction::triggered,[=](){
//获取打开文件的路径
QString path = QFileDialog::getOpenFileName(this,"open","../");
QFile file(path);
file.open(QIODevice::ReadOnly);
QString array = file.readAll();
ui->textEdit->setText(array);
});
//修改并且保存文件
connect(ui->actionsave,&QAction::triggered,[=](){
QString filename=QFileDialog::getSaveFileName(this,"save","E:/file.txt","*.txt");
QFile file(filename);
file.open(QIODevice::WriteOnly);
QString text=ui->textEdit->toPlainText();
//QFile默认支持的是utf8格式(Unicode编码的一种)
file.write(text.toUtf8());
file.close();
});
//设置字体字号
fontlabel1 = new QLabel(" 字体: ");
fontlabel2 = new QLabel(" 字号: ");
fontComboBox = new QFontComboBox;
fontComboBox->setFontFilters(QFontComboBox::ScalableFonts);
sizeComboBox = new QComboBox;
//该宏用于实现Qt的foreach循环(类似for)
foreach(int size,dbase.standardSizes())
sizeComboBox->addItem(QString::number(size));
ui->toolBar->addWidget(fontlabel1);
ui->toolBar->addWidget(fontComboBox);
ui->toolBar->addWidget(fontlabel2);
ui->toolBar->addWidget(sizeComboBox);
ui->toolBar->addSeparator();
//字体
connect(fontComboBox,QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
[=](const QString &text){
QTextCharFormat fmt;
fmt.setFontFamily(text);
mergeFormat(fmt);
});
//字号
connect(sizeComboBox,QOverload<const QString &>::of(&QComboBox::currentIndexChanged),
[=](const QString &text){
QTextCharFormat fmt;
fmt.setFontPointSize(text.toFloat());
ui->textEdit->mergeCurrentCharFormat(fmt);
});
//粗体
connect(ui->actionbold,&QAction::triggered,[=](){
QTextCharFormat fmt;
fmt=ui->textEdit->currentCharFormat();
if(Boldcheck)
fmt.setFontWeight(QFont::Bold);
else
fmt.setFontWeight(QFont::Normal);
ui->textEdit->mergeCurrentCharFormat(fmt);
Boldcheck=!Boldcheck;
});
//斜体
connect(ui->actionitalec,&QAction::triggered,[=](){
QTextCharFormat fmt;
fmt=ui->textEdit->currentCharFormat();
fmt.setFontItalic(Italiccheck);
ui->textEdit->mergeCurrentCharFormat(fmt);
Italiccheck=!Italiccheck;
});
//下划线
connect(ui->actionunderline,&QAction::triggered,[=](){
QTextCharFormat fmt;
fmt=ui->textEdit->currentCharFormat();
fmt.setFontUnderline(UnderLinecheck);
ui->textEdit->mergeCurrentCharFormat(fmt);
UnderLinecheck=!UnderLinecheck;
});
//颜色
connect(ui->actioncolor,&QAction::triggered,[=](){
QColor color = QColorDialog::getColor(Qt::red, this);
QTextCharFormat format;
format.setForeground(color);
ui->textEdit->mergeCurrentCharFormat(format);
});
//向左对齐
connect(ui->actionleft,&QAction::triggered,[=](){
ui->textEdit->setAlignment(Qt::AlignLeft);
});
//向右对齐
connect(ui->actionright,&QAction::triggered,[=](){
ui->textEdit->setAlignment(Qt::AlignRight);
});
//居中对齐
connect(ui->actioncenter,&QAction::triggered,[=](){
ui->textEdit->setAlignment(Qt::AlignCenter);
});
//剪切
connect(ui->actioncut,&QAction::triggered,[=](){
if(ui->textEdit){
ui->textEdit->cut();
}
});
//复制
connect(ui->actioncopy,&QAction::triggered,[=](){
if(ui->textEdit){
ui->textEdit->copy();
}
});
//粘贴
connect(ui->actionpaste,&QAction::triggered,[=](){
if(ui->textEdit){
ui->textEdit->paste();
}
});
//撤销
connect(ui->actionundo,&QAction::triggered,[=](){
if(ui->textEdit){
ui->textEdit->undo();
}
});
//重做
connect(ui->actionredo,&QAction::triggered,[=](){
if(ui->textEdit){
ui->textEdit->redo();
}
});
//快捷键
ui->actioncopy->setShortcut(tr("Ctrl+C"));
ui->actionpaste->setShortcut(tr("Ctrl+V"));
ui->actioncut->setShortcut(tr("Ctrl+X"));
ui->actionundo->setShortcut(tr("Ctrl+Z"));
//状态栏
QLabel *textInfo= new QLabel();
textInfo->setText("Ready");
statusBar()->addPermanentWidget(textInfo);
}
void MainWindow::mergeFormat(QTextCharFormat format){
QTextCursor curcor = ui->textEdit->textCursor();
if(!curcor.hasSelection())
curcor.select(QTextCursor::WordUnderCursor);
curcor.mergeCharFormat(format);
ui->textEdit->mergeCurrentCharFormat(format);
}
上述代码只供参考,因为配置环境和ui界面不一样的原因,运行一起效果可能会不一样,总之最重要的还是需要自己思考和理解。