欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt項(xiàng)目實(shí)戰(zhàn)之實(shí)現(xiàn)多文本編輯器

 更新時(shí)間:2023年03月17日 08:57:58   作者:音視頻開(kāi)發(fā)老舅  
這篇文章主要為大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)簡(jiǎn)易的多文本編輯器,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以了解一下

首先先來(lái)看實(shí)驗(yàn)成果圖,大概就是這么個(gè)多文檔編輯器。

首先需要在設(shè)計(jì)模式里進(jìn)行設(shè)計(jì)器的設(shè)置:

然后就是新建類(lèi)MdiChild的聲明和實(shí)現(xiàn)

mdichild.h

#ifndef MDICHILD_H
#define MDICHILD_H
 
#include<QTextEdit>
 
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); //保存文件
    QString userFriendlyCurrentFile(); //提取文件名
    QString currentFile(){return curFile;} //返回當(dāng)前文件路徑
 
protected:
    void closeEvent(QCloseEvent *event); //關(guān)閉事件
    void contextMenuEvent(QContextMenuEvent *e); //右鍵菜單事件
 
private slots:
    void documentWasModified(); //文檔被更改時(shí),窗口顯示更改狀態(tài)標(biāo)志
 
private:
    bool maybeSave(); //是否需要保存
    void setCurrentFile(const QString &fileName); //設(shè)置當(dāng)前文件
    QString curFile;  //保存當(dāng)前文件路徑
    bool isUntitled;  //作為當(dāng)前文件是否被保存到硬盤(pán)上的標(biāo)志
 
};
 
#endif // MDICHILD_H

mdichild.cpp

#include "mdichild.h"
#include<QFile>
#include<QMessageBox>
#include<QTextStream>
#include<QApplication>
#include<QFileInfo>
#include<QFileDialog>
#include<QCloseEvent>
#include<QPushButton>
#include<QMenu>
 
MdiChild::MdiChild(QWidget *parent):QTextEdit (parent)
{
    //設(shè)置在子窗口關(guān)閉時(shí)銷(xiāo)毀這個(gè)類(lèi)的對(duì)象
    setAttribute(Qt::WA_DeleteOnClose);
 
    //初始isUntitled為true
    isUntitled = true;
}
 
/*
 * 設(shè)置窗口編號(hào)
 * 保存文件未被保存過(guò)“isUntitled = true”
 * 保存文件路徑,給curFile賦初值
 * 設(shè)置子窗口標(biāo)題
 * 關(guān)聯(lián)文檔內(nèi)容改變信號(hào)到顯示文檔更改狀態(tài)
*/
void MdiChild::newFile()
{
    //設(shè)置窗口編號(hào),因?yàn)榫幪?hào)一致被保存,所以需要使用靜態(tài)變量
    static int sequenceNumber =1;
 
    //新建的文檔沒(méi)有被保存過(guò)
    isUntitled =true;
 
    //將當(dāng)前文件命名為未命名文檔加編號(hào),編號(hào)先使用再加1
    curFile = tr("未命名文檔%1.txt").arg(sequenceNumber++);
 
    //設(shè)置窗口標(biāo)題,使用[*]可以再文檔被更改后再文件名稱(chēng)后顯示“*”號(hào)
    setWindowTitle(curFile +"[*]"+tr(" - 多文檔編輯器"));
 
    //文檔更改時(shí)發(fā)射contentsChanged()信號(hào),執(zhí)行documentWasModified()槽
    connect(document(),SIGNAL(contentsChanged()),this,SLOT(documentWasModified()));
 
 
}
 
/*
 * 打開(kāi)指定的文件,并讀取文件內(nèi)容到編輯器
 * 設(shè)置當(dāng)前文件setCurrentFile(),該函數(shù)可以獲取文件路徑,完成文件和窗口狀態(tài)的設(shè)置
 * 關(guān)聯(lián)文檔內(nèi)容改變信號(hào)到顯示文檔更改狀態(tài)槽documentWasModified()
*/
bool MdiChild::loadFile(const QString &fileName)
{
    //新建QFile對(duì)象
    QFile file(fileName);
    //只讀方式打開(kāi)文件,出錯(cuò)則提示,并返回false
    if(!file.open(QFile::ReadOnly|QFile::Text))
    {
        QMessageBox::warning(this,tr("多文檔編輯器"),tr("無(wú)法讀取文件%1:\n%2.").arg(fileName).arg(file.errorString()));
        return false;
    }
 
    //新建文本流對(duì)象
    QTextStream in(&file);
    //設(shè)置鼠標(biāo)狀態(tài)為等待狀態(tài)
    QApplication::setOverrideCursor(Qt::WaitCursor);
    //讀取文件的全部文本內(nèi)容,并添加到編輯器中
    setPlainText(in.readAll());
    //恢復(fù)鼠標(biāo)狀態(tài)
    QApplication::restoreOverrideCursor();
    //設(shè)置當(dāng)前文件
    setCurrentFile(fileName);
    connect(document(),SIGNAL(contentsChanged()),this,SLOT(documentWasChanged()));
    return true;
 
}
 
bool MdiChild::save()
{
    //如果文件未被保存過(guò),則執(zhí)行另存為操作,否則直接保存文件
    if(isUntitled)
    {
        return saveAs();
    }
    else {
        return saveFile(curFile);
    }
}
 
bool MdiChild::saveAs()
{
   QString fileName = QFileDialog::getSaveFileName(this,tr("另存為"),curFile);
   //獲取文件路徑,如果為空,則返回false,否則保存文件
   if(fileName.isEmpty())
       return false;
   return saveFile(fileName);
}
 
bool MdiChild::saveFile(const QString &fileName)
{
    QFile file(fileName);
    if(!file.open(QFile::WriteOnly|QFile::Text))
    {
        QMessageBox::warning(this,tr("多文檔編輯器"),tr("無(wú)法寫(xiě)入文件%1:\n%2").arg(fileName).arg(file.errorString()));
        return false;
    }
    QTextStream out(&file);
    QApplication::setOverrideCursor(Qt::WaitCursor);
    //以純文本文件寫(xiě)入
    out<<toPlainText();
    QApplication::restoreOverrideCursor();
    setCurrentFile(fileName);
}
 
QString MdiChild::userFriendlyCurrentFile()
{
    //從文件路徑中提取文件名
    return QFileInfo(curFile).fileName();
}
 
void MdiChild::closeEvent(QCloseEvent *event)
{
    //如果maybeSave()函數(shù)返回true,則關(guān)閉窗口,否則忽略該事件
    if(maybeSave())
    {
        event->accept();
    }
    else {
        event->ignore();
    }
}
 
void MdiChild::contextMenuEvent(QContextMenuEvent *e)
{
    //創(chuàng)建菜單,并向其中添加動(dòng)作
    QMenu *menu = new QMenu;
    QAction *undo =menu->addAction(tr("撤銷(xiāo)(&U)"),this,SLOT(undo()),QKeySequence::Undo);
    undo->setEnabled(document()->isUndoAvailable());
    QAction *redo =menu->addAction(tr("恢復(fù)(&R)"),this,SLOT(redo()),QKeySequence::Redo);
    redo->setEnabled((document()->isRedoAvailable()));
    menu->addSeparator();
    QAction *cut =menu->addAction(tr("剪切(&T)"),this,SLOT(cut()),QKeySequence::Cut);
    cut->setEnabled(textCursor().hasSelection());
    QAction *copy = menu->addAction(tr("復(fù)制(&C)"),this,SLOT(copy()),QKeySequence::Copy);
    copy->setEnabled(textCursor().hasSelection());
    QAction *clear = menu->addAction(tr("清空"),this,SLOT(clear()));
    clear->setEnabled(!document()->isEmpty());
    menu->addSeparator();
    QAction *select = menu->addAction(tr("全選"),this,SLOT(selectAll()),QKeySequence::SelectAll);
    select->setEnabled(!document()->isEmpty());
 
    //獲取鼠標(biāo)的位置,然后在這個(gè)位置顯示菜單
    menu->exec(e->globalPos());
 
    //最后銷(xiāo)毀這個(gè)菜單
    delete menu;
}
 
void MdiChild::documentWasModified()
{
    //根據(jù)文檔的isModified()函數(shù)的返回值,判斷編輯器內(nèi)容是否被更改了
    //如果被更改了,就要在設(shè)置[*]號(hào)的地方顯示“*”號(hào),這里會(huì)在窗口標(biāo)題中顯示
    setWindowModified(document()->isModified());
}
 
bool MdiChild::maybeSave()
{
    //如果文檔被更改過(guò)
    if(document()->isModified())
    {
        QMessageBox box;
        box.setWindowTitle(tr("多文檔編輯器"));
        box.setText(tr("是否保存為“%1”的更改?").arg(userFriendlyCurrentFile()));
        box.setIcon(QMessageBox::Warning);
        //添加按鈕,QMessageBox::YesRole可以表明這個(gè)按鈕的行為
        QPushButton *yesBtn = box.addButton(tr("是(&Y)"),QMessageBox::YesRole);
        box.addButton(tr("否(&N)"),QMessageBox::NoRole);
        QPushButton *cancelBtn = box.addButton(tr("取消"),QMessageBox::RejectRole);
 
        //彈出對(duì)話(huà)框,讓用戶(hù)選擇是否保存修改,或者取消關(guān)閉操作
        box.exec();
 
        //如果用戶(hù)選擇是,則返回保存操作的結(jié)果;如果選擇取消,則返回false
        if(box.clickedButton() ==yesBtn)
            return save();
        else if(box.clickedButton() ==cancelBtn){
            return false;
        }
 
 
    }
    //如果文檔沒(méi)有更改過(guò),則直接返回true;
    return true;
}
 
void MdiChild::setCurrentFile(const QString &fileName)
{
    //canonicalFilePath()可以除去路徑中的符號(hào)鏈接,"."和".."等符號(hào)
    curFile = QFileInfo(fileName).canonicalFilePath();
    //文件已經(jīng)被保存過(guò)了
    isUntitled = false;
 
    //文檔沒(méi)有被更改過(guò)
    document()->setModified(false);
 
    //窗口不顯示被更改標(biāo)志
    setWindowModified(false);
 
    //設(shè)置窗口標(biāo)題,userFriendlyCurrentFile()返回文件名
    setWindowTitle(userFriendlyCurrentFile()+"[*]");
 
}

然后是mainwindow類(lèi)的聲明與實(shí)現(xiàn)

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
class QMdiSubWindow;
class MdiChild;
class QSignalMapper;
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
 
private slots:
 
    void updateMenus(); //更新菜單
    MdiChild* createMdiChild(); //創(chuàng)建子窗口
    void setActiveSubWindow(QWidget *window); //設(shè)置活動(dòng)子窗口
    void updateWindowMenu(); //更新窗口菜單
    void showTextRowAndCol(); //顯示文本的行號(hào)和列號(hào)
 
    void on_actionNew_triggered();
 
    void on_actionOpen_triggered();
 
    void on_actionSave_triggered();
 
    void on_actionSaveAs_triggered();
 
    void on_actionUndo_triggered();
 
    void on_actionRedo_triggered();
 
    void on_actionCut_triggered();
 
    void on_actionCopy_triggered();
 
    void on_actionPaste_triggered();
 
    void on_actionClose_triggered();
 
    void on_actionCloseAll_triggered();
 
    void on_actionAbout_triggered();
 
    void on_actionAboutQt_triggered();
 
    void on_actionExit_triggered();
 
private:
    QMdiSubWindow *findMdiChild(const QString &fileName);//查找子窗口
    void readSettings(); //讀取窗口設(shè)置
    void writeSettings(); //寫(xiě)入窗口設(shè)置
    void initWindow(); //初始化窗口
 
 
protected:
    void closeEvent(QCloseEvent* event); //關(guān)閉事件
 
 
private:
    Ui::MainWindow *ui;
    QAction *actionSeparator; //間隔器
    MdiChild *activeMdiChild(); //活動(dòng)窗口
    QSignalMapper *windowMapper; //信號(hào)映射器
};
 
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"mdichild.h"
#include<QFileDialog>
#include<QMdiSubWindow>
#include<QSignalMapper>
#include<QMessageBox>
#include<QSettings>
#include<QCloseEvent>
#include<QLabel>
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    /*
     * 初始化actionSeparator動(dòng)作,然后執(zhí)行更新菜單函數(shù),并關(guān)聯(lián)多文檔區(qū)域的活動(dòng)子窗口信號(hào)到更新菜單槽上
     * 每當(dāng)更換子窗口時(shí),都會(huì)更新菜單狀態(tài)
     */
    //創(chuàng)建間隔期動(dòng)作并在其中設(shè)置間隔期
    actionSeparator = new QAction(this);
    actionSeparator->setSeparator(true);
    //更新菜單
    updateMenus();
 
    //當(dāng)有活動(dòng)窗口時(shí)更新菜單
    connect(ui->mdiArea,SIGNAL(subWindowActivated(QMdiSubWindow*)),this,SLOT(updateMenus()));
 
    //創(chuàng)建信號(hào)映射器
    windowMapper = new QSignalMapper(this);
    //映射器重新發(fā)射信號(hào),更具信號(hào)設(shè)置活動(dòng)窗口
    connect(windowMapper,SIGNAL(mapped(QWidget *)),this,SLOT(setActiveSubWindow(QWidget *)));
 
    //更新窗口菜單,并且設(shè)置當(dāng)窗口菜單將要顯示的時(shí)候更新窗口菜單
    updateWindowMenu();
    connect(ui->menu_W,SIGNAL(aboutToShow()),this,SLOT(updateWindowMenu()));
 
    readSettings(); //初始窗口時(shí)讀取窗口設(shè)置信息
 
    //初始化窗口
    initWindow();
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::on_actionNew_triggered()
{
    //創(chuàng)建MdiChild
    MdiChild *child = createMdiChild();
    //新建文件
    child->newFile();
    //顯示子窗口
    child->show();
}
 
/*
 * 更新菜單函數(shù):根據(jù)是否有活動(dòng)子窗口設(shè)置各個(gè)菜單動(dòng)作是否可用
 * 這里剪切復(fù)制操作和撤銷(xiāo)恢復(fù)操作的設(shè)置還要進(jìn)行特殊情況的判斷
*/
void MainWindow::updateMenus()
{
    //根據(jù)是否有活動(dòng)窗口來(lái)設(shè)置各個(gè)動(dòng)作是否可用
    bool hasMdiChild = (activeMdiChild()!= 0);
    ui->actionSave->setEnabled(hasMdiChild);
    ui->actionSaveAs->setEnabled(hasMdiChild);
    ui->actionPaste->setEnabled(hasMdiChild);
    ui->actionClose->setEnabled(hasMdiChild);
    ui->actionCloseAll->setEnabled(hasMdiChild);
    ui->actionTile->setEnabled(hasMdiChild);
    ui->actionCascade->setEnabled(hasMdiChild);
    ui->actionNext->setEnabled(hasMdiChild);
    ui->actionPrevious->setEnabled(hasMdiChild);
 
    //有活動(dòng)窗口且有被選擇的文本,剪切復(fù)制才可用
    bool hasSelection =(activeMdiChild() &&activeMdiChild()->textCursor().hasSelection());
    ui->actionCut->setEnabled(hasSelection);
    ui->actionPaste->setEnabled(hasSelection);
 
    //有活動(dòng)窗口且有撤銷(xiāo)操作時(shí)撤銷(xiāo)動(dòng)作可用
    ui->actionUndo->setEnabled(activeMdiChild()&&activeMdiChild()->document()->isUndoAvailable());
 
    //有活動(dòng)窗口且文檔有恢復(fù)操作時(shí)恢復(fù)動(dòng)作可用
    ui->actionRedo->setEnabled(activeMdiChild()&&activeMdiChild()->document()->isRedoAvailable());
}
 
/*
 * 這個(gè)函數(shù)中創(chuàng)建了MdiChild部件,并將它作為子窗口的中心部件,然后添加到多文檔區(qū)域。
 * 下面關(guān)聯(lián)了編輯器的信號(hào)和我們的菜單動(dòng)作,讓它們可以隨著文檔的改變而改變狀態(tài)
 * 最后返回了MdiChild對(duì)象指針。
 * 之所以要添加這樣一個(gè)函數(shù),是因?yàn)樵谙旅娴拇蜷_(kāi)操作中還要使用到這個(gè)函數(shù)中的功能,所以將它們從新建文件菜單的觸發(fā)信號(hào)槽中提取出來(lái),另寫(xiě)了這樣一個(gè)函數(shù)
*/
MdiChild *MainWindow::createMdiChild()
{
    //創(chuàng)建MdiChild部件
    MdiChild *child = new MdiChild;
    //向多文檔區(qū)域添加子窗口,child為中心部件
    ui->mdiArea->addSubWindow(child);
 
    //根據(jù)QTextEdit類(lèi)的是否可以復(fù)制信號(hào)設(shè)置剪切復(fù)制動(dòng)作是否可用
    connect(child,SIGNAL(copyAvailable(bool)),ui->actionCut,SLOT(setEnabled(bool)));
    connect(child,SIGNAL(copyAvailable(bool)),ui->actionCopy,SLOT(setEnabled(bool)));
    //根據(jù)QTextDocument類(lèi)的是否可以撤銷(xiāo)恢復(fù)信號(hào)設(shè)置撤銷(xiāo)恢復(fù)動(dòng)作是否可用
    connect(child->document(),SIGNAL(undoAvailable(bool)),ui->actionUndo,SLOT(setEnabled(bool)));
    connect(child->document(),SIGNAL(redoAvailable(bool)),ui->actionRedo,SLOT(setEnabled(bool)));
 
    connect(child,SIGNAL(cursorPositionChanged()),this,SLOT(showTextRowAndCol()));
 
    return child;
}
 
/*
 * 函數(shù)功能:將傳遞過(guò)來(lái)的窗口部件設(shè)置為活動(dòng)窗口
*/
void MainWindow::setActiveSubWindow(QWidget *window)
{
    //如果傳遞了窗口部件,則將其設(shè)置為活動(dòng)窗口
    if(!window)
        return;
    ui->mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow*>(window));
}
 
void MainWindow::on_actionOpen_triggered()
{
    //獲取文件路勁
    QString fileName = QFileDialog::getOpenFileName(this);
    //如果路徑不為空,則查看該文件是否已經(jīng)打開(kāi)
    if(!fileName.isEmpty())
    {
        QMdiSubWindow *existing = findMdiChild(fileName);
        //如果已經(jīng)存在,則將對(duì)應(yīng)的子窗口設(shè)置為活動(dòng)窗口
        if(existing)
        {
            ui->mdiArea->setActiveSubWindow(existing);
            return;
        }
        //如果沒(méi)有打開(kāi),則新建子窗口
        MdiChild *child = createMdiChild();
        if(child->loadFile(fileName))
        {
            ui->statusBar->showMessage(tr("打開(kāi)文件成功"),2000);
            child->show();
        }
        else {
            child->close();
        }
    }
}
 
void MainWindow::updateWindowMenu()
{
    //先清空菜單,然后在添加各個(gè)菜單動(dòng)作
    ui->menu_W->clear();
    ui->menu_W->addAction(ui->actionClose);
    ui->menu_W->addAction(ui->actionCloseAll);
    ui->menu_W->addSeparator();
    ui->menu_W->addAction(ui->actionTile);
    ui->menu_W->addAction(ui->actionCascade);
    ui->menu_W->addSeparator();
    ui->menu_W->addAction(ui->actionNext);
    ui->menu_W->addAction(ui->actionPrevious);
    ui->menu_W->addAction(actionSeparator);
 
    //如果有活動(dòng)窗口,則顯示間隔器
    QList<QMdiSubWindow*> windows =ui->mdiArea->subWindowList();
    actionSeparator->setVisible(!windows.isEmpty());
 
    //遍歷各個(gè)子窗口
    for(int i=0;i<windows.size();++i)
    {
        MdiChild *child = qobject_cast<MdiChild*>(windows.at(i)->widget());
        QString text;
        //如果窗口數(shù)小于9,則設(shè)置編號(hào)為快捷鍵
        if(i<9)
        {
            text=tr("&%1 %2").arg(i+1).arg(child->userFriendlyCurrentFile());
        }
        else {
            text=tr("%1 %2").arg(i+1).arg(child->userFriendlyCurrentFile());
        }
 
        //添加動(dòng)作到菜單,設(shè)置動(dòng)作可以選擇
        QAction *action = ui->menu_W->addAction(text);
        action->setCheckable(true);
        //設(shè)置當(dāng)前活動(dòng)窗口動(dòng)作為選中狀態(tài)
        action->setChecked(child ==activeMdiChild());
        //關(guān)聯(lián)動(dòng)作的觸發(fā)信號(hào)到信號(hào)映射器的map()槽,這個(gè)槽會(huì)發(fā)射mapped()信號(hào)
        connect(action,SIGNAL(triggered()),windowMapper,SLOT(map()));
 
        //將動(dòng)作與相應(yīng)的窗口部件進(jìn)行映射
        //在發(fā)射mappedd()信號(hào)時(shí)就會(huì)以這個(gè)窗口部件為參數(shù)
        windowMapper->setMapping(action,windows.at(i));
    }
}
 
void MainWindow::showTextRowAndCol()
{
    //如果有活動(dòng)窗口,則顯示其中光標(biāo)所在的位置
    if(activeMdiChild())
    {
        //因?yàn)楂@取的行號(hào)和列號(hào)都是從0開(kāi)始的,所以我們這里進(jìn)行了加1
        int rowNum = activeMdiChild()->textCursor().blockNumber()+1;
        int colNum = activeMdiChild()->textCursor().blockNumber()+1;
 
        ui->statusBar->showMessage(tr("%1行 %2列").arg(rowNum).arg(colNum),2000);
    }
}
 
 
QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName)
{
    QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();
    //利用foreach語(yǔ)句遍歷子窗口列表,如果其文件路徑和要查找的路徑相同,則返回該窗口
    foreach(QMdiSubWindow* window,ui->mdiArea->subWindowList())
    {
        MdiChild* mdiChild = qobject_cast<MdiChild*>(window->widget());
        if(mdiChild->currentFile() ==canonicalFilePath)
            return window;
    }
    return 0;
}
 
void MainWindow::readSettings()
{
    QSettings settings("yafeilinux","myMdi");
    QPoint pos =settings.value("pos",QPoint(200,200)).toPoint();
    QSize size =settings.value("size",QSize(400,200)).toSize();
    move(pos);
    resize(size);
}
 
void MainWindow::writeSettings()
{
    QSettings settings("yafeilinux","myMdi");
    //寫(xiě)入位置信息和大小
    settings.setValue("pos",pos());
    settings.setValue("size",size());
 
}
 
void MainWindow::initWindow()
{
    setWindowTitle(tr("多文檔編輯器"));
 
    //在工具欄右擊時(shí),可以關(guān)閉該工具欄
    ui->mainToolBar->setWindowTitle(tr("工具欄"));
    //當(dāng)多文檔區(qū)域的內(nèi)容超出可是區(qū)域后,出現(xiàn)滾動(dòng)條
    ui->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    ui->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
 
    ui->statusBar->showMessage(tr("歡迎使用多文檔編輯器"));
    QLabel *label =new QLabel(this);
    label->setFrameStyle(QFrame::Box|QFrame::Sunken);
    label->setText(tr("<a href=\"http://www.yafeilinux.com\">yafeilinux.com</a>"));
 
    //標(biāo)簽文字為富文本
    label->setTextFormat(Qt::RichText);
 
    //可以打開(kāi)外部鏈接
    label->setOpenExternalLinks(true);
    ui->statusBar->addPermanentWidget(label);
    ui->actionNew->setStatusTip(tr("創(chuàng)建一個(gè)文件"));
    ui->actionOpen->setStatusTip(tr("打開(kāi)一個(gè)文件"));
 
}
 
void MainWindow::closeEvent(QCloseEvent *event)
{
    //先執(zhí)行多文檔區(qū)域的關(guān)閉操作
    ui->mdiArea->closeAllSubWindows();
    //如果還有窗口沒(méi)有關(guān)閉,則忽略該事件
    if(ui->mdiArea->currentSubWindow())
        event->ignore();
    else {
        //在關(guān)閉前寫(xiě)入窗口設(shè)置
        writeSettings();
        event->accept();
    }
}
/*
 * 這個(gè)函數(shù)中使用了QMdiArea類(lèi)的activeSubWindow()函數(shù)來(lái)獲得多文檔區(qū)域的活動(dòng)子窗口,
 * 然后使用了T qobject_cast()函數(shù)來(lái)進(jìn)行類(lèi)型轉(zhuǎn)換。這個(gè)函數(shù)時(shí)QObject類(lèi)的函數(shù),它將object對(duì)象指針轉(zhuǎn)換為T(mén)類(lèi)型的對(duì)象指針
 * 這里將活動(dòng)窗口的中心部件QWidget類(lèi)型指針轉(zhuǎn)換為MdiChild類(lèi)型的指針
 * 這里的T類(lèi)型必須是直接或者間接繼承自QObject類(lèi),并且在其定義中要有Q_OBJECT宏變量
*/
MdiChild *MainWindow::activeMdiChild()
{
    //如果有活動(dòng)窗口,則將其內(nèi)的中心部件轉(zhuǎn)換為MdiChild類(lèi)型,沒(méi)有則直接返回0
    if(QMdiSubWindow *activeSubWindow = ui->mdiArea->activeSubWindow())
        return qobject_cast<MdiChild*>(activeSubWindow->widget());
    return 0;
}
 
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_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::on_actionAbout_triggered()
{
    QMessageBox::about(this,"關(guān)于",tr("致力于多文檔編輯器普及工作"));
}
 
void MainWindow::on_actionAboutQt_triggered()
{
    QMessageBox::about(this,"關(guān)于Qt",tr("Qt是一個(gè)1991年由Qt Company開(kāi)發(fā)的跨平臺(tái)C++圖形用戶(hù)界面應(yīng)用程序開(kāi)發(fā)框架。它既可以開(kāi)發(fā)GUI程序,也可用于開(kāi)發(fā)非GUI程序,比如控制臺(tái)工具和服務(wù)器。Qt是面向?qū)ο蟮目蚣?,使用特殊的代碼生成擴(kuò)展(稱(chēng)為元對(duì)象編譯器(Meta Object Compiler, moc))以及一些宏,Qt很容易擴(kuò)展,并且允許真正地組件編程。"));
}
 
void MainWindow::on_actionExit_triggered()
{
    //等價(jià)于QApplication::closeAllWindows();
    qApp->closeAllWindows();
}

最后是main函數(shù)

#include "mainwindow.h"
#include <QApplication>
 
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
 
    return a.exec();
}

以上就是Qt項(xiàng)目實(shí)戰(zhàn)之實(shí)現(xiàn)多文本編輯器的詳細(xì)內(nèi)容,更多關(guān)于Qt多文本編輯器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++使用waveIn實(shí)現(xiàn)聲音采集

    C++使用waveIn實(shí)現(xiàn)聲音采集

    在Windows上實(shí)現(xiàn)錄音比較簡(jiǎn)單的方法是使用winmm,其中的waveIn模塊就可以打開(kāi)錄音設(shè)備,這篇文章主要為大家介紹了C++如何使用waveIn實(shí)現(xiàn)聲音采集,需要的可以了解下
    2023-10-10
  • C++代碼和可執(zhí)行程序在x86和arm上的區(qū)別介紹

    C++代碼和可執(zhí)行程序在x86和arm上的區(qū)別介紹

    這篇文章主要介紹了C++代碼和可執(zhí)行程序在x86和arm上的區(qū)別,X86和ARM是占據(jù)CPU市場(chǎng)的兩大處理器,各有優(yōu)劣,本文給大家詳細(xì)介紹了兩者的區(qū)別,需要的朋友可以參考下
    2022-07-07
  • Windows安裝配置C/C++(VS2017)OpenSSL開(kāi)發(fā)環(huán)境配置教程

    Windows安裝配置C/C++(VS2017)OpenSSL開(kāi)發(fā)環(huán)境配置教程

    這篇文章主要為大家詳細(xì)介紹了Windows安裝配置C/C++,OpenSSL開(kāi)發(fā)環(huán)境配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • c++ 巧開(kāi)平方的實(shí)現(xiàn)代碼

    c++ 巧開(kāi)平方的實(shí)現(xiàn)代碼

    如果沒(méi)有計(jì)算器,我們?nèi)绾吻?的平方根
    2013-05-05
  • C語(yǔ)言實(shí)現(xiàn)發(fā)牌洗牌

    C語(yǔ)言實(shí)現(xiàn)發(fā)牌洗牌

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)發(fā)牌洗牌,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)與算法之單鏈表

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)與算法之單鏈表

    單鏈表是一種鏈?zhǔn)酱嫒〉臄?shù)據(jù)結(jié)構(gòu),用一組地址任意的存儲(chǔ)單元存放線性表中的數(shù)據(jù)元素。本文將為大家介紹C語(yǔ)言中單鏈表的基本概念與讀取數(shù)據(jù)元素,需要的可以參考一下
    2021-12-12
  • C++中new和delete的使用方法詳解

    C++中new和delete的使用方法詳解

    這篇文章主要介紹了C++中new和delete的使用方法詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • C語(yǔ)言大小端模式、判斷大小端、大小端轉(zhuǎn)換方法詳解

    C語(yǔ)言大小端模式、判斷大小端、大小端轉(zhuǎn)換方法詳解

    這篇文章主要介紹了C語(yǔ)言大小端模式、判斷大小端、大小端轉(zhuǎn)換的相關(guān)資料,大端和小端是數(shù)據(jù)在內(nèi)存中的存儲(chǔ)方式,大端模式下高字節(jié)存于低地址,小端模式則相反,大小端問(wèn)題由數(shù)據(jù)類(lèi)型多字節(jié)存儲(chǔ)引起,不同選擇形成不同存儲(chǔ)模式,需要的朋友可以參考下
    2024-10-10
  • C語(yǔ)言實(shí)現(xiàn)猜數(shù)字小項(xiàng)目

    C語(yǔ)言實(shí)現(xiàn)猜數(shù)字小項(xiàng)目

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)實(shí)現(xiàn)猜數(shù)字小項(xiàng)目,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C++11如何引入的尾置返回類(lèi)型

    C++11如何引入的尾置返回類(lèi)型

    C++11 標(biāo)準(zhǔn)引入的尾置返回類(lèi)型,可以讓返回復(fù)雜類(lèi)型的函數(shù)聲明更加清晰易讀,在無(wú)法使用C++14 標(biāo)準(zhǔn)的情況下,通過(guò)尾置返回類(lèi)型的語(yǔ)法來(lái)推導(dǎo)函數(shù)模板的返回類(lèi)型無(wú)疑是最簡(jiǎn)便的方法,這篇文章主要介紹了C++11引入的尾置返回類(lèi)型,需要的朋友可以參考下
    2023-01-01

最新評(píng)論