QT 多文件文字編輯器

為什麼要起名字呢發表於2021-01-01

在這裡插入圖片描述
在這裡插入圖片描述

一、設計目標

設計開發一個簡單的多文件文字編輯器,具有新建、開啟、儲存一個檔案、另存為一個檔案、設定字型、設定字號、跨子視窗的剪下、複製、貼上、查詢、加粗、傾斜、下劃線、設定字型顏色、左對齊、居中、右對齊、撤銷、重做、視窗層疊、視窗平鋪等功能。

二、設計思路

使用MainWindows類,建立一個主視窗,並且具有選單欄和工具欄。使用MdiArea作為主視窗檔案編輯的主要顯示介面。自定義類childedit繼承QTextEdit類,並且新增了儲存為txt檔案、開啟txt檔案並且讀取到當前視窗中的功能。使用childedit類的物件作為子視窗新增到MdiArea中,並在其中對字型等進行各種各樣的操作。
新建直接new建立一個childedit物件新增到MdiArea中。開啟是使用QFile的物件通過getOpenFileName函式呼叫系統檔案對話方塊,並且返回絕對路徑給QFile物件。使用檔案流將內容讀取出來。儲存和另存為也類似。
設定字型、顏色、字號、加粗、下劃線、傾斜等功能均使用QTextCharFormat 物件獲取字型格式,並且使用mergeCurrentCharFormat函式設定當前選中的文字的字型格式。

三、原始碼

mainwindows.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QFontComboBox>
#include<QToolButton>
#include<QTextEdit>
#include<QMdiSubWindow>
#include"childedit.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
    bool is_saved;
    bool is_MDI;
    bool Boldcheck;
    bool Italiccheck;
    bool UnderLinecheck;
    int childNumber;
    QDialog *newDialog;
    QLineEdit *line;
    QToolButton *undo;
    QToolButton *redo;

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    childEdit *activeEdit();

private:
    Ui::MainWindow *ui;
public slots:
    void Newfile();
    void Openfile();
    void Save();
    void Savefile(QString);
    void SaveAs();
    void Setfont(QString);
    void SetfontSize(int);
    void Font_Bold();
    void Font_Underline();
    void Font_Italic();
    void Setcolor();
    void Set_center();
    void Set_left();
    void Set_right();
    void Setfontfamily();
    void Search();
    void Find_text();
    void actionCascade();
    void actionTile();
    void actionMDI();
    void actionPrevious();
    void actionNext();
    void cut();
    void copy();
    void paste();
    void Undo();
    void Redo();
    void Close();
    void CloseAll();

};
#endif // MAINWINDOW_H

mainwindows.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"childwindows.h"
#include<QFile>
#include<QFileDialog>
#include<QTextStream>
#include<QMessageBox>
#include<QFontDialog>
#include<QFont>
#include<QFontComboBox>
#include<QSpinBox>
#include<QLabel>
#include<QTextCharFormat>
#include<QToolButton>
#include<QPushButton>
#include<QColorDialog>
#include<QLineEdit>
#include<QTextEdit>
#include<QHBoxLayout>
#include<QSignalMapper>
#include<QMdiArea>
#include<QMdiSubWindow>
#include<QDebug>
#include"childedit.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    is_saved = false;
    is_MDI = true;
    Boldcheck = true;
    Italiccheck = true;
    UnderLinecheck = true;
    childNumber = 0;

    line = new QLineEdit(this);
    QPushButton *btn = new QPushButton(this);
    QHBoxLayout *layout = new QHBoxLayout(this);
    newDialog =new QDialog(this);
    btn->setText("搜尋下一個");
    layout->addWidget(line);
    layout->addWidget(btn);
    newDialog->setLayout(layout);
    newDialog->setWindowTitle("查詢");

    QFontComboBox *fontbox = new QFontComboBox(this);
    QSpinBox *fontsize = new QSpinBox(this);
    QToolButton *btn_Bold = new QToolButton(this);
    QToolButton *btn_Underline = new QToolButton(this);
    QToolButton *btn_Italic = new QToolButton(this);
    QToolButton *color = new QToolButton(this);
    QToolButton *center = new QToolButton(this);
    QToolButton *left = new QToolButton(this);
    QToolButton *right = new QToolButton(this);
    undo = new QToolButton(this);
    redo = new QToolButton(this);
    fontbox->setMinimumWidth(120);
    fontsize->setValue(13);

    btn_Bold->setText("加粗");
    btn_Underline->setText("下劃線");
    btn_Italic->setText("傾斜");
    color->setText("顏色");
    center->setText("居中");
    left->setText("左對齊");
    right->setText("右對齊");
    undo->setText("撤銷");
    redo->setText("重做");
    ui->actioncut->setShortcut(tr("Ctrl+X"));
    ui->actioncopy->setShortcut(tr("Ctrl+C"));
    ui->actionpaste->setShortcut(tr("Ctrl+V"));
    ui->actionsearch->setShortcut(tr("Ctrl+F"));
    ui->actionsave->setShortcut(tr("Ctrl+S"));

    ui->toolBar->addWidget(fontbox);
    ui->toolBar->addWidget(fontsize);
    ui->toolBar->addWidget(btn_Bold);
    ui->toolBar->addWidget(btn_Italic);
    ui->toolBar->addWidget(btn_Underline);
    ui->toolBar->addWidget(color);
    ui->toolBar->addWidget(left);
    ui->toolBar->addWidget(center);
    ui->toolBar->addWidget(right);
    ui->toolBar->addWidget(undo);
    ui->toolBar->addWidget(redo);

    ui->actionnew->setIcon(QIcon(":/res/xinjian.png"));
    ui->actionopen->setIcon(QIcon(":/res/dakai.png"));
    ui->actionsave->setIcon(QIcon(":/res/baocun.png"));
    btn_Bold->setIcon(QIcon(":/res/jiacu.png"));
    btn_Italic->setIcon(QIcon(":/res/xieti.png"));
    btn_Underline->setIcon(QIcon(":/res/xiahuaxian.png"));
    color->setIcon(QIcon(":/res/color.png"));
    ui->actioncut->setIcon(QIcon(":/res/jianqie.png"));
    ui->actioncopy->setIcon(QIcon(":/res/fuzhi.png"));
    ui->actionpaste->setIcon(QIcon(":/res/zhangtie.png"));
    ui->actionsearch->setIcon(QIcon(":/res/chazhao.jpg"));
    undo->setIcon(QIcon(":/res/chexiao.png"));
    redo->setIcon(QIcon(":/res/chongzuo.png"));
    left->setIcon(QIcon(":/res/left.png"));
    center->setIcon(QIcon(":/res/center.png"));
    right->setIcon(QIcon(":/res/right.png"));

    ui->mdiArea->setViewMode(QMdiArea::TabbedView);

    connect(ui->actionnew,SIGNAL(triggered()),this,SLOT(Newfile()));
    connect(ui->actionopen,SIGNAL(triggered()),this,SLOT(Openfile()));
    connect(ui->actionsave,SIGNAL(triggered()),this,SLOT(Save()));
    connect(ui->actionSaveas,SIGNAL(triggered()),this,SLOT(SaveAs()));
    connect(fontbox,SIGNAL(currentIndexChanged(QString)),this,SLOT(Setfont(QString)));
    connect(fontsize,SIGNAL(valueChanged(int)),this,SLOT(SetfontSize(int)));
    connect(btn_Bold,SIGNAL(clicked()),this,SLOT(Font_Bold()));
    connect(btn_Underline,SIGNAL(clicked()),this,SLOT(Font_Underline()));
    connect(btn_Italic,SIGNAL(clicked()),this,SLOT(Font_Italic()));
    connect(color,SIGNAL(clicked()),this,SLOT(Setcolor()));
    connect(center,SIGNAL(clicked()),this,SLOT(Set_center()));
    connect(left,SIGNAL(clicked()),this,SLOT(Set_left()));
    connect(right,SIGNAL(clicked()),this,SLOT(Set_right()));
    connect(undo,SIGNAL(clicked()),this,SLOT(Undo()));
    connect(redo,SIGNAL(clicked()),this,SLOT(Redo()));

    connect(ui->actioncut,SIGNAL(triggered()),this,SLOT(cut()));
    connect(ui->actioncopy,SIGNAL(triggered()),this,SLOT(copy()));
    connect(ui->actionpaste,SIGNAL(triggered()),this,SLOT(paste()));
    connect(ui->actioncolor,SIGNAL(triggered()),this,SLOT(Setcolor()));
    connect(ui->actionfont,SIGNAL(triggered()),this,SLOT(Setfontfamily()));
    connect(ui->actionsearch,SIGNAL(triggered()),this,SLOT(Search()));
    connect(btn,SIGNAL(clicked()),this,SLOT(Find_text()));

    connect(ui->actionclose,SIGNAL(triggered()),this,SLOT(Close()));
    connect(ui->actioncloseAll,SIGNAL(triggered()),this,SLOT(CloseAll()));
    connect(ui->actioncascade,SIGNAL(triggered()),this,SLOT(actionCascade()));
    connect(ui->actiontile,SIGNAL(triggered()),this,SLOT(actionTile()));
    connect(ui->actionmdi,SIGNAL(triggered()),this,SLOT(actionMDI()));
    connect(ui->actionprevious,SIGNAL(triggered()),this,SLOT(actionPrevious()));
    connect(ui->actionnext,SIGNAL(triggered()),this,SLOT(actionNext()));

}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::Newfile()  //開啟新視窗
{
    childEdit *edit = new childEdit(this);
    ui->mdiArea->addSubWindow(edit);
    edit->setFontPointSize(13);
    childNumber++;
    edit->setWindowTitle(tr("%1 未儲存檔案").arg(childNumber));
    edit->show();
}
void MainWindow::Openfile()     //開啟檔案
{
    Newfile();
    activeEdit()->OpenFile();
}
void MainWindow::Save()     //判斷是否儲存過檔案
{
    activeEdit()->Save();
}
void MainWindow::SaveAs()   //另存為檔案
{
    activeEdit()->SaveAs();
}
void MainWindow::Savefile(QString filename)     //儲存檔案
{
    QFile file(filename);
    file.open(QFile::WriteOnly | QFile::Text);
    QTextStream out(&file);
    out << activeEdit()->toPlainText();
}
void MainWindow::Setfont(QString fontStr)   //工具欄設定字型
{
    QTextCharFormat format;
    format.setFontFamily(fontStr);
    activeEdit()->mergeCurrentCharFormat(format);
}
void MainWindow::Setfontfamily()    //編輯框設定字型
{
    bool ifok;
    QFont font = QFontDialog::getFont(&ifok,this);
    QTextCharFormat format;
    format.setFont(font);
    activeEdit()->mergeCurrentCharFormat(format);
}
void MainWindow::SetfontSize(int FontSize)  //設定字號
{
    QTextCharFormat format;
    format.setFontPointSize(FontSize);
    activeEdit()->mergeCurrentCharFormat(format);
}
void MainWindow::Font_Bold()	//設定粗體
{
    QTextCharFormat format;
    format.setFontWeight(Boldcheck ? QFont::Bold : QFont::Normal);
    activeEdit()->mergeCurrentCharFormat(format);
    Boldcheck = !Boldcheck;
}
void MainWindow::Font_Underline()	//設定下劃線
{
    QTextCharFormat format;
    format.setFontUnderline(UnderLinecheck);
    activeEdit()->mergeCurrentCharFormat(format);
    UnderLinecheck = !UnderLinecheck;
}
void MainWindow::Font_Italic()	//設定傾斜
{
    QTextCharFormat format;
    format.setFontItalic(Italiccheck);
    activeEdit()->mergeCurrentCharFormat(format);
    Italiccheck = !Italiccheck;
}
void MainWindow::Setcolor()	//設定顏色
{
    QColor color = QColorDialog::getColor(Qt::red, this);
    QTextCharFormat format;
    format.setForeground(color);
    activeEdit()->mergeCurrentCharFormat(format);
}
void MainWindow::Set_center()	//居中
{
    activeEdit()->setAlignment(Qt::AlignCenter);
}
void MainWindow::Set_left()		//左對齊
{
    activeEdit()->setAlignment(Qt::AlignLeft);
}
void MainWindow::Set_right()	//右對齊
{
    activeEdit()->setAlignment(Qt::AlignRight);
}
void MainWindow::Search()	//搜尋
{
    newDialog->show();
}
void MainWindow::Find_text()
{
    QString findtext=line->text();
    if(activeEdit()->find(findtext,QTextDocument::FindBackward))
    {
        QPalette palette = activeEdit()->palette();
        palette.setColor(QPalette::Highlight,palette.color(QPalette::Active,QPalette::Highlight));
        activeEdit()->setPalette(palette);
    }
    else
    {
        QMessageBox::information(this,tr("注意"),tr("沒有找到內容"),QMessageBox::Ok);
    }
}
childEdit *MainWindow::activeEdit()		//返回當前活動視窗指標
{
    if(QMdiSubWindow * window = ui->mdiArea->activeSubWindow()){
        return qobject_cast<childEdit *>(window->widget());
    }
    return 0;
}
void MainWindow::actionCascade()	//視窗層疊
{
    ui->mdiArea->cascadeSubWindows();
}
void MainWindow::actionTile()	//視窗平鋪
{
    ui->mdiArea->tileSubWindows();
}
void MainWindow::actionMDI()
{
    if(is_MDI){
        ui->mdiArea->setViewMode(QMdiArea::SubWindowView);
        is_MDI = false;
    }
    else{
        ui->mdiArea->setViewMode(QMdiArea::TabbedView);
        is_MDI = true;
    }
}
void MainWindow::actionPrevious()
{
    ui->mdiArea->activatePreviousSubWindow();
}
void MainWindow::actionNext()
{
    ui->mdiArea->activateNextSubWindow();
}
void MainWindow::cut()
{
    if(activeEdit()){
        activeEdit()->cut();
    }
}
void MainWindow::copy()
{
    if(activeEdit()){
        activeEdit()->copy();
    }
}
void MainWindow::paste()
{
    if(activeEdit()){
        activeEdit()->paste();
    }
}
void MainWindow::Undo()		//撤銷
{
    if(activeEdit()){
        activeEdit()->undo();
    }
}
void MainWindow::Redo()		//重做
{
    if(activeEdit()){
        activeEdit()->redo();
    }
}
void MainWindow::Close()
{
    ui->mdiArea->closeActiveSubWindow();
}
void MainWindow::CloseAll()
{
    ui->mdiArea->closeAllSubWindows();
}

childedit.h

#ifndef CHILDEDIT_H
#define CHILDEDIT_H

#include <QTextEdit>

class childEdit : public QTextEdit
{
    Q_OBJECT
public:
    explicit childEdit(QWidget *parent = nullptr);
    bool is_saved;
    QString lastfile;

    void OpenFile();
    void Save();
    void Loadfile(QString);
    void SaveAs();
    void Savefile(QString);

signals:

};

#endif // CHILDEDIT_H

childedit.cpp

#include "childedit.h"
#include<QFileDialog>
#include<QTextStream>
#include<QTextEdit>
childEdit::childEdit(QWidget *parent) : QTextEdit(parent)
{
    setAttribute(Qt::WA_DeleteOnClose);
}
void childEdit::OpenFile()	//開啟檔案
{
    QString filename = QFileDialog::getOpenFileName(this,tr("檔案開啟"),"D:/Downloads",tr("*.*"));
    if(!filename.isEmpty()){
        Loadfile(filename);
        setWindowTitle(filename);
    }
}
void childEdit::Save()	//儲存檔案
{
    if(!is_saved){
        lastfile = QFileDialog::getSaveFileName(this,tr("檔案儲存"),"D:/Downloads",tr("TextFiles(*.txt)"));
        is_saved = true;
        setWindowTitle(lastfile);
        Savefile(lastfile);
    }
    else{
        Savefile(lastfile);
    }
}
void childEdit::Loadfile(QString filename)	//載入檔案
{
    QFile file(filename);
    file.open(QIODevice::ReadOnly | QIODevice::Text);
    QTextStream in(&file);
    in.setCodec("utf-8");
    setPlainText(in.readAll());
}
void childEdit::SaveAs()
{
    QString filename = QFileDialog::getSaveFileName(this,tr("file open"),"D:/Downloads",tr("TextFiles(*.txt)"));
    Savefile(filename);
}
void childEdit::Savefile(QString filename)
{
    QFile file(filename);
    file.open(QFile::WriteOnly | QFile::Text);
    QTextStream out(&file);
    out.setCodec("utf-8");
    out <<toPlainText();
}

相關文章