Qt——GodOuOEdit for neusoft

29 篇文章 1 订阅
18 篇文章 0 订阅
#ifndef MDICHILD_H
#define MDICHILD_H

#include <QTextEdit>
#include <QCloseEvent>

class MdiChild : public QTextEdit
{
    Q_OBJECT
public:
    explicit MdiChild(QWidget *parent = 0);
    void newFile();                         // 新建操作
    bool loadFile(const QString &fileName); // 加载文件
    bool save();                            // 保存操作
    bool saveAs();                          // 另存为操作
    bool saveFile(const QString &fileName); // 保存文件
    void mergeFormatOnWordOrSelection(const QTextCharFormat &format);
protected:
    void closeEvent(QCloseEvent *event);    // 关闭事件

private slots:
    void documentWasModified();             // 文档被更改时,显示更改状态标志
private:
    void setCurrentFile(const QString &fileName);  // 设置当前文件
    QString curFile;                        // 保存当前文件路径
    bool isUntitled;                        // 作为当前文件是否被保存到硬盘上的标志
};

#endif // MDICHILD_H

  • godouo.cpp
#include "godouo.h"
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QFileInfo>
#include <QApplication>
#include <QFileDialog>
#include <QCloseEvent>
#include <QPushButton>
#include <QMenu>

MdiChild::MdiChild(QWidget *parent) :
    QTextEdit(parent)
{
    setAttribute(Qt::WA_DeleteOnClose); // 这样可以在子窗口关闭时销毁这个类的对象
    isUntitled = true;  // 初始isUntitled为true
}

void MdiChild::newFile()
{
    // 设置窗口编号,因为编号一直被保存,所以需要使用静态变量
    static int sequenceNumber = 1;
    // 新建的文档没有被保存过
    isUntitled = true;
    // 将当前文件命名为未命名文档加编号,编号先使用再加1
    curFile = tr("未命名文档%1.txt").arg(sequenceNumber++);

    // 设置窗口标题,使用[*]可以在文档被更改后在文件名称后显示”*“号
    setWindowTitle(curFile + "[*]" + tr(" - 多文档编辑器"));

    // 当文档被更改时发射contentsChanged()信号,
    // 执行我们的documentWasModified()槽函数
    connect(document(), SIGNAL(contentsChanged()),this, SLOT(documentWasModified()));
}

bool MdiChild::loadFile(const QString &fileName)
{
    //打开文件
    QFile file(fileName);
    if(file.open(QFile::ReadOnly | QFile::Text))
    {
        QTextStream stream(&file);// 新建文本流对象
             stream.setCodec("GBK");
        QApplication::setOverrideCursor(Qt::WaitCursor); // 设置鼠标状态为等待状态
        setPlainText(file.readAll());  // 读取文件的全部文本内容,并添加到编辑器中
        QApplication::restoreOverrideCursor(); // 恢复鼠标状态

        setCurrentFile(fileName); // 设置当前文件

        connect(document(), SIGNAL(contentsChanged()),
                    this, SLOT(documentWasModified()));
        file.close();
        return true;
    }
    else
    {
        //打开失败
        QMessageBox::critical(this,tr("error"),file.errorString());
        return false;
    }
}

bool MdiChild::save()
{
    if (isUntitled) { // 如果文件未被保存过,则执行另存为操作
        return saveAs();
    } else {
        return saveFile(curFile); // 否则直接保存文件
    }
}

bool MdiChild::saveAs()
{
    // 获取文件路径,如果为空,则返回false
    QString fileName = QFileDialog::getSaveFileName(this, tr("另存为"),curFile);
    if (fileName.isEmpty())
        return false;

    return saveFile(fileName); // 否则保存文件
}

bool MdiChild::saveFile(const QString &fileName)
{
    if(fileName.isEmpty())
        return false;
    QFile file(fileName);
    if(file.open(QFile::WriteOnly | QFile::Text))   //以写的方式打开文件 若文件有内容 则追加内容
    {
        QTextStream stream(&file);
        stream.setCodec("GBK");
        QApplication::setOverrideCursor(Qt::WaitCursor);
        stream<<toPlainText();    //将text的内容转换为QString后,写入文件
        QApplication::restoreOverrideCursor();
        file.close();
        return true;
    }

    QMessageBox::critical(this,tr("error"),file.errorString());
    return false;
}

void MdiChild::closeEvent(QCloseEvent *event)
{
    //查看qt助帮文档 QMessageBox
    if(document()->isModified())  //textEdit内容已经被修改
    {
        QMessageBox msgBox;
        msgBox.setWindowFlags(Qt::Widget | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowStaysOnTopHint);
        msgBox.setText(tr("是否保存更改?"));
        msgBox.setInformativeText(tr("您是否要保存文件"));
        msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
        msgBox.setDefaultButton(QMessageBox::Save);
        int ret = msgBox.exec();    //执行QMessageBox

        switch (ret) {
          case QMessageBox::Save:
              // Save was clicked
            this->save();
            break;
          case QMessageBox::Discard:
              // Don't Save was clicked
            event->accept();
              break;
          case QMessageBox::Cancel:
              // Cancel was clicked
            event->ignore();
              break;
          default:
              // should never be reached
            event->ignore();
              break;
        }
    }
    else
    {
        event->accept();
    }
}

void MdiChild::documentWasModified()
{
    // 根据文档的isModified()函数的返回值,判断我们编辑器内容是否被更改了
    // 如果被更改了,就要在设置了[*]号的地方显示“*”号,这里我们会在窗口标题中显示
    setWindowModified(document()->isModified());
}

void MdiChild::setCurrentFile(const QString &fileName)
{
    // canonicalFilePath()可以除去路径中的符号链接,“.”和“..”等符号
    curFile = QFileInfo(fileName).canonicalFilePath();

    isUntitled = false; // 文件已经被保存过了
    document()->setModified(false); // 文档没有被更改过
    setWindowModified(false); // 窗口不显示被更改标志

    // 设置窗口标题,QFileInfo()返回文件名
    setWindowTitle(QFileInfo(curFile).fileName() + "[*]");

}
void MdiChild::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
{
    QTextCursor cursor = this->textCursor();
    if (!cursor.hasSelection())
        cursor.select(QTextCursor::WordUnderCursor);
    cursor.mergeCharFormat(format);
    this->mergeCurrentCharFormat(format);
}
  • mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "godouo.h"
#include <QFileDialog>
#include <QSettings>
#include <QCloseEvent>
#include <QLabel>
#include <QMdiSubWindow>
#include <QMessageBox>
#include <QFontDialog>
#include <QColorDialog>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    readSettings(); // 初始窗口时读取窗口设置信息
    initWindow(); // 初始化窗口
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actionNew_triggered()
{
    MdiChild *child = createMdiChild(); // 创建MdiChild
    // 新建文件
    child->newFile();
   // 显示子窗口
    child->show();
}

void MainWindow::on_actionOpen_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this,tr("打开文件")); // 获取文件路径
    if(fileName.isEmpty())
        return;

    //打开文件
    MdiChild *child = createMdiChild(); // 如果没有打开,则新建子窗口
    if (child->loadFile(fileName)) {
        ui->statusBar->showMessage(tr("打开文件成功"), 2000);
        child->show();
    } else {
        child->close();
    }
}

void MainWindow::on_actionSave_triggered()
{
    if(activeMdiChild() && activeMdiChild()->save())
           ui->statusBar->showMessage(tr("文件保存成功"),2000);
}

void MainWindow::on_actionSaveAs_triggered()
{
    if(activeMdiChild() && activeMdiChild()->saveAs())
            ui->statusBar->showMessage(tr("文件保存成功"),2000);
}

void MainWindow::on_actionExit_triggered()// 退出菜单
{
    qApp->closeAllWindows();
}

MdiChild *MainWindow::createMdiChild()
{
    MdiChild *child = new MdiChild; // 创建MdiChild部件
    ui->mdiArea->addSubWindow(child); // 向多文档区域添加子窗口,child为中心部件

    // 根据QTextEdit类的是否可以复制信号设置剪切复制动作是否可用
    connect(child,SIGNAL(copyAvailable(bool)),ui->actionCut,
            SLOT(setEnabled(bool)));
    connect(child,SIGNAL(copyAvailable(bool)),ui->actionCopy,
            SLOT(setEnabled(bool)));

    // 每当编辑器中的光标位置改变,就重新显示行号和列号
    connect(child,SIGNAL(cursorPositionChanged()),this,SLOT(showTextRowAndCol()));

    return child;
}

void MainWindow::readSettings()
{
    QSettings settings("Neusoft-neuedu/neutech", "GodOuO");
    QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
    QSize size = settings.value("size", QSize(600, 400)).toSize();
    move(pos);
    resize(size);
}

void MainWindow::writeSettings()
{
    QSettings settings("Neusoft-neuedu/neutech", "GodOuO");
    settings.setValue("pos", pos());   // 写入位置信息
    settings.setValue("size", size()); // 写入大小信息
}

void MainWindow::initWindow()
{
    setWindowTitle(tr("GodOuOEdit"));

    // 我们在工具栏上单击鼠标右键时,可以关闭工具栏
    ui->mainToolBar->setWindowTitle(tr("工具栏"));

    // 当多文档区域的内容超出可视区域后,出现滚动条
    ui->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    ui->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);

    ui->statusBar->showMessage(tr("Welcome To GodOuOEdit"));

    QLabel *label = new QLabel(this);
    label->setFrameStyle(QFrame::Box | QFrame::Sunken);
    label->setText(tr("人机交互应用开发技术"));
    label->setTextFormat(Qt::RichText); // 标签文本为富文本
    label->setOpenExternalLinks(true);  // 可以打开外部链接
    ui->statusBar->addPermanentWidget(label);

    // 动作的状态提示
    ui->actionNew->setStatusTip(tr("创建一个文件"));
    ui->actionOpen->setStatusTip(tr("打开一个已经存在的文件"));
    ui->actionSave->setStatusTip(tr("保存文档到硬盘"));
    ui->actionSaveAs->setStatusTip(tr("以新的名称保存文档"));
    ui->actionExit->setStatusTip(tr("退出应用程序"));
    ui->actionUndo->setStatusTip(tr("撤销先前的操作"));
    ui->actionRedo->setStatusTip(tr("恢复先前的操作"));
    ui->actionCut->setStatusTip(tr("剪切选中的内容到剪贴板"));
    ui->actionCopy->setStatusTip(tr("复制选中的内容到剪贴板"));
    ui->actionPaste->setStatusTip(tr("粘贴剪贴板的内容到当前位置"));
    ui->actionClose->setStatusTip(tr("关闭活动窗口"));
    ui->actionCloseAll->setStatusTip(tr("关闭所有窗口"));
    ui->actionTile->setStatusTip(tr("平铺所有窗口"));
    ui->actionCascade->setStatusTip(tr("层叠所有窗口"));
    ui->actionNext->setStatusTip(tr("将焦点移动到下一个窗口"));
    ui->actionPrevious->setStatusTip(tr("将焦点移动到前一个窗口"));
    ui->actionAbout->setStatusTip(tr("显示本软件的介绍"));
    ui->actionAboutQt->setStatusTip(tr("显示Qt的介绍"));
}

MdiChild *MainWindow::activeMdiChild()
{
    // 如果有活动窗口,则将其内的中心部件转换为MdiChild类型
    if(QMdiSubWindow *activeSubWindow = ui->mdiArea->activeSubWindow())
        return qobject_cast<MdiChild*>(activeSubWindow->widget());
    return 0;// 没有活动窗口,直接返回0
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    ui->mdiArea->closeAllSubWindows(); // 先执行多文档区域的关闭操作
    if (ui->mdiArea->currentSubWindow()) {
        event->ignore(); // 如果还有窗口没有关闭,则忽略该事件
    } else {
        writeSettings(); // 在关闭前写入窗口设置
        event->accept();
    }
}

void MainWindow::on_actionUndo_triggered()// 撤销菜单
{
    if(activeMdiChild())
        activeMdiChild()->undo();
}

void MainWindow::on_actionRedo_triggered()// 恢复菜单
{
    if(activeMdiChild()) activeMdiChild()->redo();
}

void MainWindow::on_actionCut_triggered()// 剪切菜单
{
    if(activeMdiChild()) activeMdiChild()->cut();
}

void MainWindow::on_actionCopy_triggered() // 复制菜单
{
    if(activeMdiChild()) activeMdiChild()->copy();
}

void MainWindow::on_actionPaste_triggered()// 粘贴菜单
{
    if(activeMdiChild()) activeMdiChild()->paste();
}

void MainWindow::on_actionClose_triggered() // 关闭菜单
{
    ui->mdiArea->closeActiveSubWindow();
}

void MainWindow::on_actionCloseAll_triggered()// 关闭所有窗口菜单
{
    ui->mdiArea->closeAllSubWindows();
}

void MainWindow::showTextRowAndCol()
{
    // 如果有活动窗口,则显示其中光标所在的位置
    if(activeMdiChild()){

    // 因为获取的行号和列号都是从0开始的,所以我们这里进行了加1
    int rowNum = activeMdiChild()->textCursor().blockNumber()+1;
    int colNum = activeMdiChild()->textCursor().columnNumber()+1;

    ui->statusBar->showMessage(tr("%1行 %2列")
                               .arg(rowNum).arg(colNum),2000);
    }
}

void MainWindow::on_actionNext_triggered()// 下一个菜单
{
    ui->mdiArea->activateNextSubWindow();
}

void MainWindow::on_actionTile_triggered()// 平铺菜单
{
    ui->mdiArea->tileSubWindows();
}

void MainWindow::on_actionCascade_triggered()// 层叠菜单
{
    ui->mdiArea->cascadeSubWindows();
}

void MainWindow::on_actionPrevious_triggered()// 前一个菜单
{
    ui->mdiArea->activatePreviousSubWindow();
}

void MainWindow::on_actionAbout_triggered() // 关于菜单
{
     QMessageBox::about(this,tr("关于本软件"),tr("人机交互应用开发技术\n姓名:宋明桥\n学号:181203616"));
}

void MainWindow::on_actionAboutQt_triggered()// 关于Qt菜单
{
    qApp->aboutQt(); // 这里的qApp是QApplication对象的全局指针,这行代码相当于QApplication::aboutQt();
}




void MainWindow::on_boldAct_triggered()
{
    QFont bold;
    bold.setBold(true);
    ui->boldAct->setFont(bold);
    QTextCharFormat fmt;
    fmt.setFontWeight(ui->boldAct->isChecked() ? QFont::Bold : QFont::Normal);
    if(activeMdiChild())
        activeMdiChild()->mergeFormatOnWordOrSelection(fmt);
}

void MainWindow::on_italicAct_triggered()
{
    QTextCharFormat fmt;
    fmt.setFontItalic(ui->italicAct->isChecked());
    if(activeMdiChild())
        activeMdiChild()->mergeFormatOnWordOrSelection(fmt);
}

void MainWindow::on_underlineAct_triggered()
{
    QTextCharFormat fmt;
    fmt.setFontUnderline(ui->underlineAct->isChecked());
    if(activeMdiChild())
        activeMdiChild()->mergeFormatOnWordOrSelection(fmt);
}


void MainWindow::on_action_yangshi_triggered()
{
    bool ok = false;
        QFont font = QFontDialog::getFont(&ok,this);
        if(ok)
        {
            this->activeMdiChild()->setFont(font);
}
}

void MainWindow::on_actioncolor_triggered()
{
    if(activeMdiChild())
    {
        QColor col = QColorDialog::getColor(activeMdiChild()->textColor(), this);
        if (!col.isValid())
            return;
        QTextCharFormat fmt;
        fmt.setForeground(col);
        activeMdiChild()->mergeFormatOnWordOrSelection(fmt);
    }
}

效果图:

在这里插入图片描述
在这里插入图片描述

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GodOuO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值