QT的Qmainwindow实现简易记事本,不带有UI界面。
1、功能展示
1、编辑文件时,文件名左上角有个"*",代表文件未保存
2、菜单栏有文件、编辑的选项
3、工具栏有保存、新建、打开、调节字体、调节颜色。
4、文件菜单中有,新建,保存、打开、另存为
5、编辑栏中有复制、剪切、粘贴、撤销、恢复
2、mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QTextEdit>
#include <QFileDialog>
#include <QFile>
#include <QDebug>
#include <QMessageBox>
#include <QAction>
#include <QToolButton>
#include <QFileInfo>
#include <QFontDialog>
#include <QColorDialog>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void openFile();//文件的打开,给槽函数调用的
void readFile(QString filePath);
//自已添加的公有槽函数
public slots:
void openActionSlots();
void newActionSlots();
void saveActionSlots();
void saveasActionSlots();
void copyActionSlots();
void pasteActionSlots();
void cutActionSlots();
void undoActionSlots();
void redoActionSlots();
//自已添加的私有成员变量(数据成员)
private:
QString fileName;//保存文件的文件名
QString filePath;//保存文件的绝对路径,一般用
QTextEdit *text;//主体区域的多行文本
};
#endif // MAINWINDOW_H
3、mainwindow.cpp
#include "mainwindow.h"
#include <QAction>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
//1.给窗口设置图标、标题
this->setWindowIcon(QIcon(":/icons/icons/1.png"));
this->fileName = "新建文本文档.txt";
this->setWindowTitle(this->fileName);
//2.给窗口添加菜单栏,工具栏、状态栏、主体区域
QMenuBar *menu_bar = new QMenuBar(this);
this->setMenuBar(menu_bar);
QToolBar *tool_bar = new QToolBar(this);
this->addToolBar(tool_bar);
QStatusBar *status_bar = new QStatusBar(this);
this->setStatusBar(status_bar);
this->text = new QTextEdit(this);//因为这是一个记事本,所以主体区域是多行文本框
this->setCentralWidget(this->text);
//3.给菜单栏添加菜单,有两个菜单:文件、编辑
QMenu *file_menu = new QMenu("文件(F)",this);
menu_bar->addMenu(file_menu);
QMenu *edit_menu = new QMenu("编辑(E)",this);
menu_bar->addMenu(edit_menu);
//4.1 给文件菜单添加动作 file_menu的功能(动作) 新建、打开、保存、另存为
QAction *new_action = new QAction(this);
new_action->setText("新建(N)");
new_action->setIcon(QIcon(":/icons/icons/new.png"));
new_action->setShortcut(QKeySequence::New);
file_menu->addAction(new_action);
QAction *open_action = new QAction(QIcon(":/icons/icons/open.png"),"打开(O)",this);
open_action->setShortcut(QKeySequence::Open);
file_menu->addAction(open_action);
QAction *save_action = new QAction(QIcon(":/icons/icons/save.png"),"保存(S)",this);
save_action->setShortcut(QKeySequence::Save);
file_menu->addAction(save_action);
QAction *saveas_action = new QAction("另存为(A)",this);
saveas_action->setShortcut(QKeySequence::SaveAs);
file_menu->addAction(saveas_action);
//4.2 给编辑菜单添加动作 edit_menu的功能(动作) 复制、粘贴、剪切、撤销、恢复
QAction *copy_action = new QAction(QIcon(":/icons/icons/copy.png"),"复制(C)",this);
copy_action->setShortcut(QKeySequence::Copy);
edit_menu->addAction(copy_action);
QAction *paste_action = new QAction(QIcon(":/icons/icons/paste.png"),"粘贴(V)",this);
paste_action->setShortcut(QKeySequence::Paste);
edit_menu->addAction(paste_action);
QAction *cut_action = new QAction(QIcon(":/icons/icons/cut.png"),"剪切(X)",this);
cut_action->setShortcut(QKeySequence::Cut);
edit_menu->addAction(cut_action);
QAction *undo_action = new QAction("撤销(Z)",this);
undo_action->setShortcut(QKeySequence::Undo);
edit_menu->addAction(undo_action);
QAction *redo_action = new QAction("恢复(Y)",this);
redo_action->setShortcut(QKeySequence::Redo);
edit_menu->addAction(redo_action);
//4.3.1 给工具栏添加动作,便于快速实现某些功能 :新建、打开、保存
tool_bar->addAction(new_action);
tool_bar->addAction(open_action);
tool_bar->addAction(save_action);
//4.3.2 给工具栏添加工具按钮,有字体和颜色的按钮
QToolButton *font_btn = new QToolButton(this);//创建字体按钮对象
font_btn->setIcon(QIcon(":/icons/icons/font.png"));//给字体按钮对象设置图标
tool_bar->addWidget(font_btn);//向工具栏中添加这个按钮,使用addWidget
QToolButton *color_btn = new QToolButton(this);
color_btn->setIcon(QIcon(":/icons/icons/color.png"));
tool_bar->addWidget(color_btn);
//5.信号与槽函数的关联,三种方式:1、QT5。 2、QT4。 3、匿名槽函数(C++11)。
//信号是菜单栏的行为动作,点击
connect(new_action,&QAction::triggered,this,&MainWindow::newActionSlots);
connect(open_action,&QAction::triggered,this,&MainWindow::openActionSlots);
connect(save_action,&QAction::triggered,this,&MainWindow::saveActionSlots);
connect(saveas_action,&QAction::triggered,this,&MainWindow::saveasActionSlots);
//对文档输入内容时,文档名称会有个'*'
connect(this->text,&QTextEdit::textChanged,this,[=]()
{
this->setWindowTitle("*"+this->fileName);
});
//字体和颜色选择的信号和槽函数的关联,信号是工具按钮的点击,槽函数是匿名函数
connect(font_btn,&QToolButton::clicked,this,[=]()
{
bool ok;
QFont font = QFontDialog::getFont(&ok,this);//获取字体
this->text->setFont(font);//给文本设置字体
});
connect(color_btn,&QToolButton::clicked,this,[=]()
{
QColor color = QColorDialog::getColor(Qt::white,this);//获取颜色
this->text->setTextColor(color);//给文本框的字体设置颜色
});
//对编辑菜单的信号和槽函数的关联 复制、粘贴、剪切、撤销、恢复
connect(copy_action, &QAction::triggered, this, &MainWindow::copyActionSlots);
connect(paste_action, &QAction::triggered, this, &MainWindow::pasteActionSlots);
connect(cut_action, &QAction::triggered, this, &MainWindow::cutActionSlots);
connect(undo_action, &QAction::triggered, this, &MainWindow::undoActionSlots);
connect(redo_action, &QAction::triggered, this, &MainWindow::redoActionSlots);
//connect(copy_action, &QAction::triggered, this->text, &QTextEdit::copy);
}
MainWindow::~MainWindow()
{
}
void MainWindow::openFile()
{
//这是一个文件的绝对路径,不是单独的文件名
this->filePath = QFileDialog::getOpenFileName(this,"打开","./","TXT(*.txt)");
qDebug()<<this->filePath;
//对文件进行操作,打开文件,读文件的全部内容,关闭文件
QFile file(this->filePath);
bool res = file.open(QFile::ReadOnly);
if(res == true)
{
QByteArray data = file.readAll();//读文件中全部都内容,将其给多行文本区
this->text->setText(data);
file.close();//关闭文件
//设置文件名为当前打开的文件名,将绝对路径的最后为文件名 back()或者last()获取分割后整个列表的最后一个值
this->fileName = this->filePath.split("/").last();
//设置给窗口标题
this->setWindowTitle(this->fileName);
}
}
void MainWindow::readFile(QString filePath)
{
this->filePath = filePath;
//对文件进行操作,打开文件,读文件的全部内容,关闭文件
QFile file(this->filePath);
bool res = file.open(QFile::ReadOnly);
if(res == true)
{
QByteArray data = file.readAll();//读文件中全部都内容,将其给多行文本区
this->text->setText(data);
file.close();//关闭文件
//获取到了文件名
this->fileName = QFileInfo(this->filePath).fileName();
//设置给窗口标题
this->setWindowTitle(this->fileName);
}
}
void MainWindow::newActionSlots()
{
//QTextDocument * 是否怎么样,优先去找is开头并且函数类型是bool
bool res = this->text->document()->isModified();
//首先判断是否修改过文件
if(res == true)//若修改了,则分情况讨论。是否要保存修改的文件,再新建文件
{
int ret = QMessageBox::question(this,"记事本","是否对修改进行保存",
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
if(ret == QMessageBox::Yes)
{
qDebug()<<"保存";
this->saveActionSlots();
this->text->clear();
this->fileName = "无标题-记事本";
this->setWindowTitle(this->fileName);
}
else if(ret == QMessageBox::No)
{
qDebug()<<"不保存";
this->text->clear();
this->fileName = "无标题-记事本";
this->setWindowTitle(this->fileName);
}
}
else//若没有修改,则直接清空文本,设置窗口标题
{
this->text->clear();
this->fileName = "无标题-记事本";
this->setWindowTitle(this->fileName);
}
}
void MainWindow::openActionSlots()
{
bool res = this->text->document()->isModified();
//打开新文件,要先判断当前文档是否修改过
if(res == true)//文档是修改过,看是否要保存
{
int ret = QMessageBox::question(this,"记事本","是否对修改进行保存",
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel);
if(ret == QMessageBox::Yes)//保存
{
qDebug()<<"保存";
this->saveActionSlots();
this->openFile();
}
else if(ret == QMessageBox::No)//不保存
{
qDebug()<<"不保存";
this->openFile();
}
}
else//文档没有修改过
{
this->openFile();
}
}
void MainWindow::saveActionSlots()
{
if(this->fileName == "无标题-记事本")
{
//新建一个无标题的文件,保存的话为另存为的操作,因为要给这个新文件一个位置
this->saveasActionSlots();
}
else
{
QFile file(this->filePath);
bool res = file.open(QFile::WriteOnly);//打开
if(res)
{
//获取文本框的内容
QString data = this->text->toPlainText();
//写入文件中
file.write(data.toUtf8());//把QString 转化为 QByteArray类型
file.close();//文件关闭
//获取文件名、设置给窗口标题
this->fileName = QFileInfo(this->filePath).fileName();//根据文件的绝对路径,拿到文件名
this->setWindowTitle(this->fileName);
//把文本框的文档的修改状态改为未修改,只要保存了,就不能提示是否要保存
this->text->document()->setModified(false);
}
}
}
void MainWindow::saveasActionSlots()
{
this->filePath = QFileDialog::getSaveFileName(this,"另存为","./","TXT(*.txt)");
//另存为,与保存类似
QFile file(this->filePath);
bool res = file.open(QFile::WriteOnly);//打开
if(res)
{
//获取文本框的内容
QString data = this->text->toPlainText();
//写入文件中
file.write(data.toUtf8());//把QString 转化为 QByteArray类型
file.close();//文件关闭
//获取文件名、设置给窗口标题
this->fileName = QFileInfo(this->filePath).fileName();//根据文件的绝对路径,拿到文件名
this->setWindowTitle(this->fileName);
//把文本框的文档的修改状态改为未修改,只要保存了,就不能提示是否要保存
this->text->document()->setModified(false);
}
}
void MainWindow::copyActionSlots()
{
this->text->copy();
}
void MainWindow::pasteActionSlots()
{
this->text->paste();
}
void MainWindow::cutActionSlots()
{
this->text->cut();
}
void MainWindow::undoActionSlots()
{
this->text->undo();
}
void MainWindow::redoActionSlots()
{
this->text->redo();
}