Qt: 多文档应用程序源码解析及下载

来源:互联网 发布:java中json出现 u003d 编辑:程序博客网 时间:2024/05/29 04:45

如果有代码看不懂,可以留言,我会回复大家的留言(Qt、C++纯技术交流群:302558294)

效果图如下:



项目结构:



程序主要功能:

1、新建文本文件。

2、多文档编辑文本文件。

3、打开已有文件。

4、文件另存为。


解析:

1、 Editor 类继承自 QTextEdit,主要用于文本编辑和处理功能。

2、MainWindow继承自QMainWindow,主要用于创建主界面,界面布局等功能。


源码:

//main.cpp

#include <QApplication>#include "mainwindow.h"int main(int argc, char *argv[]){    QApplication app(argc, argv);    MainWindow mainWin; //创建一个程序实例    mainWin.show();    return app.exec();}

//Editor.h

#ifndef EDITOR_H#define EDITOR_H#include <QTextEdit>class Editor : public QTextEdit{    Q_OBJECTpublic:    Editor(QWidget *parent = 0);    void newFile(); //新建文件    bool save();  //文件保存    bool saveAs(); //文件另存为    QSize sizeHint() const;  //获取窗口的推荐大小    QAction *windowMenuAction() const { return action; }    static Editor *open(QWidget *parent = 0); //打开窗口    static Editor *openFile(const QString &fileName, QWidget *parent = 0);  //打开文件protected:    void closeEvent(QCloseEvent *event);  //关闭事件,在程序关闭之前执行此函数private slots:    void documentWasModified(); //设置窗口显示状态,修改和未修改两种private:    bool okToContinue();    bool saveFile(const QString &fileName); //保存文件    void setCurrentFile(const QString &fileName);  //设置当前文件    bool readFile(const QString &fileName); //读文件    bool writeFile(const QString &fileName); //写文件    QString strippedName(const QString &fullFileName);  //从文件路径中剥取文件名    QString curFile;    bool isUntitled;    QAction *action;};#endif

//Editor.cpp

#include <QApplication>#include <QtGui>#include <QAction>#include <QMessageBox>#include <QFileDialog>#include "editor.h"Editor::Editor(QWidget *parent)    : QTextEdit(parent){    action = new QAction(this);    action->setCheckable(true);    connect(action, SIGNAL(triggered()), this, SLOT(show()));    connect(action, SIGNAL(triggered()), this, SLOT(setFocus()));    isUntitled = true;  //记录文件是否已经存在    connect(document(), SIGNAL(contentsChanged()), this, SLOT(documentWasModified())); //文档内容发生改变时,触发槽    setWindowIcon(QPixmap(":/images/document.png"));  //设置子窗口图标    setWindowTitle("[*]");    setAttribute(Qt::WA_DeleteOnClose); //窗口关闭的时候删除}void Editor::newFile(){    static int documentNumber = 1; //记录打开子窗口的个数    curFile = tr("document%1.txt").arg(documentNumber);    setWindowTitle(curFile + "[*]");    action->setText(curFile);    isUntitled = true;    ++documentNumber;}bool Editor::save(){    if (isUntitled)        return saveAs();    else        return saveFile(curFile);}bool Editor::saveAs(){    QString fileName =  QFileDialog::getSaveFileName(this, tr("Save As"), curFile);    if (fileName.isEmpty())        return false;    return saveFile(fileName);}QSize Editor::sizeHint() const{    return QSize(72 * fontMetrics().width('x'), 25 * fontMetrics().lineSpacing());}Editor *Editor::open(QWidget *parent) //弹出“打开”打开窗口,获取路径和文件名{    QString fileName = QFileDialog::getOpenFileName(parent, tr("Open"), ".");    if (fileName.isEmpty())        return 0;    return openFile(fileName, parent);}Editor *Editor::openFile(const QString &fileName, QWidget *parent){    Editor *editor = new Editor(parent);    if (editor->readFile(fileName))    {        editor->setCurrentFile(fileName);        return editor;    }    else    {        delete editor;        return 0;    }}void Editor::closeEvent(QCloseEvent *event)  //关闭事件发生时{    if (okToContinue())        event->accept(); //接受关闭事件    else        event->ignore(); //忽视关闭事件}void Editor::documentWasModified() //设置窗口为被修改状态{    setWindowModified(true);}bool Editor::okToContinue() //是否继续{    if (document()->isModified()) //判断文件是否被修改    {        int r = QMessageBox::warning(this, tr("MDI Editor"),                                     tr("File %1 has been modified.\n" "Do you want to save your changes?")                                     .arg(strippedName(curFile)),                                     QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);        if (r == QMessageBox::Yes)        {            return save();        }        else if (r == QMessageBox::Cancel)        {            return false;        }    }    return true;}bool Editor::saveFile(const QString &fileName) //保存文件{    if (writeFile(fileName))    {        setCurrentFile(fileName);        return true;    }    else    {        return false;    }}void Editor::setCurrentFile(const QString &fileName)  //设置当前文件{    curFile = fileName;    isUntitled = false;    action->setText(strippedName(curFile));    document()->setModified(false);    setWindowTitle(strippedName(curFile) + "[*]");    setWindowModified(false);}bool Editor::readFile(const QString &fileName) //读文件{    QFile file(fileName);    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))    {        QMessageBox::warning(this, tr("MDI Editor"),                             tr("Cannot read file %1:\n%2.")                             .arg(file.fileName())                             .arg(file.errorString()));        return false;    }    QTextStream in(&file);    QApplication::setOverrideCursor(Qt::WaitCursor);    setPlainText(in.readAll());    QApplication::restoreOverrideCursor();    return true;}bool Editor::writeFile(const QString &fileName) //写文件{    QFile file(fileName);    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))    {        QMessageBox::warning(this, tr("MDI Editor"),                             tr("Cannot write file %1:\n%2.")                             .arg(file.fileName())                             .arg(file.errorString()));        return false;    }    QTextStream out(&file);    QApplication::setOverrideCursor(Qt::WaitCursor);    out << toPlainText();    QApplication::restoreOverrideCursor();    return true;}QString Editor::strippedName(const QString &fullFileName) //从路径中剥离文件名{    return QFileInfo(fullFileName).fileName();}

//mainwindow.h

#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>class QAction;class QActionGroup;class QLabel;class QMdiArea;class QMenu;class QToolBar;class Editor;class MainWindow : public QMainWindow{    Q_OBJECTpublic:    MainWindow();public slots:    void newFile();    void openFile(const QString &fileName);protected:    void closeEvent(QCloseEvent *event);private slots:    void open();    void save();    void saveAs();    void cut();    void copy();    void paste();    void about();    void updateActions();    void loadFiles();private:    void createActions();    void createMenus();    void createToolBars();    void createStatusBar();    void addEditor(Editor *editor);    Editor *activeEditor();    QMdiArea *mdiArea;    QLabel *readyLabel;    QWidgetList windows;    QMenu *fileMenu;    QMenu *editMenu;    QMenu *windowMenu;    QMenu *helpMenu;    QToolBar *fileToolBar;    QToolBar *editToolBar;    QActionGroup *windowActionGroup;    QAction *newAction;    QAction *openAction;    QAction *saveAction;    QAction *saveAsAction;    QAction *exitAction;    QAction *cutAction;    QAction *copyAction;    QAction *pasteAction;    QAction *closeAction;    QAction *closeAllAction;    QAction *tileAction;    QAction *cascadeAction;    QAction *nextAction;    QAction *previousAction;    QAction *separatorAction;    QAction *aboutAction;    QAction *aboutQtAction;};#endif

//mainwindow.cpp

#include <QToolBar>#include <QLabel>#include <QtGui>#include <QMdiArea>#include <QApplication>#include <QMessageBox>#include <QAction>#include <QMenuBar>#include <QStatusBar>#include <QMdiSubWindow>#include "editor.h"#include "mainwindow.h"MainWindow::MainWindow(){    mdiArea = new QMdiArea;    setCentralWidget(mdiArea);    connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),this, SLOT(updateActions()));    createActions();    createMenus();    createToolBars();    createStatusBar();    setWindowIcon(QPixmap(":/images/icon.png"));    setWindowTitle(tr("MDI Editor"));    QTimer::singleShot(0, this, SLOT(loadFiles()));}void MainWindow::loadFiles(){    QStringList args = QApplication::arguments();    args.removeFirst();    if (!args.isEmpty())    {        foreach (QString arg, args)            openFile(arg);        mdiArea->cascadeSubWindows();    }    else    {        newFile();    }    mdiArea->activateNextSubWindow();}void MainWindow::newFile(){    Editor *editor = new Editor;    editor->newFile();    addEditor(editor);}void MainWindow::openFile(const QString &fileName){    Editor *editor = Editor::openFile(fileName, this);    if (editor)        addEditor(editor);}void MainWindow::closeEvent(QCloseEvent *event){    mdiArea->closeAllSubWindows();    if (!mdiArea->subWindowList().isEmpty())    {        event->ignore();    }    else    {        event->accept();    }}void MainWindow::open(){    Editor *editor = Editor::open(this);    if (editor)        addEditor(editor);}void MainWindow::save(){    if (activeEditor())        activeEditor()->save();}void MainWindow::saveAs(){    if (activeEditor())        activeEditor()->saveAs();}void MainWindow::cut(){    if (activeEditor())        activeEditor()->cut();}void MainWindow::copy(){    if (activeEditor())        activeEditor()->copy();}void MainWindow::paste(){    if (activeEditor())        activeEditor()->paste();}void MainWindow::about(){    QMessageBox::about(this, tr("About MDI Editor"),            tr("<h2>Editor 1.1</h2>"               "<p>Copyright &copy; 2007 Software Inc."               "<p>MDI Editor is a small application that demonstrates "               "QMdiArea."));}void MainWindow::updateActions(){    bool hasEditor = (activeEditor() != 0);    bool hasSelection = activeEditor() && activeEditor()->textCursor().hasSelection();    saveAction->setEnabled(hasEditor);    saveAsAction->setEnabled(hasEditor);    cutAction->setEnabled(hasSelection);    copyAction->setEnabled(hasSelection);    pasteAction->setEnabled(hasEditor);    closeAction->setEnabled(hasEditor);    closeAllAction->setEnabled(hasEditor);    tileAction->setEnabled(hasEditor);    cascadeAction->setEnabled(hasEditor);    nextAction->setEnabled(hasEditor);    previousAction->setEnabled(hasEditor);    separatorAction->setVisible(hasEditor);    if (activeEditor())        activeEditor()->windowMenuAction()->setChecked(true);}void MainWindow::createActions(){    newAction = new QAction(tr("&New"), this);    newAction->setIcon(QIcon(":/images/new.png"));    newAction->setShortcut(QKeySequence::New);    newAction->setStatusTip(tr("Create a new file"));    connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));    openAction = new QAction(tr("&Open..."), this);    openAction->setIcon(QIcon(":/images/open.png"));    openAction->setShortcut(QKeySequence::Open);    openAction->setStatusTip(tr("Open an existing file"));    connect(openAction, SIGNAL(triggered()), this, SLOT(open()));    saveAction = new QAction(tr("&Save"), this);    saveAction->setIcon(QIcon(":/images/save.png"));    saveAction->setShortcut(QKeySequence::Save);    saveAction->setStatusTip(tr("Save the file to disk"));    connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));    saveAsAction = new QAction(tr("Save &As..."), this);    saveAsAction->setStatusTip(tr("Save the file under a new name"));    connect(saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()));    exitAction = new QAction(tr("E&xit"), this);    exitAction->setShortcut(tr("Ctrl+Q"));    exitAction->setStatusTip(tr("Exit the application"));    connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));    cutAction = new QAction(tr("Cu&t"), this);    cutAction->setIcon(QIcon(":/images/cut.png"));    cutAction->setShortcut(QKeySequence::Cut);    cutAction->setStatusTip(tr("Cut the current selection to the "                               "clipboard"));    connect(cutAction, SIGNAL(triggered()), this, SLOT(cut()));    copyAction = new QAction(tr("&Copy"), this);    copyAction->setIcon(QIcon(":/images/copy.png"));    copyAction->setShortcut(QKeySequence::Copy);    copyAction->setStatusTip(tr("Copy the current selection to the "                                "clipboard"));    connect(copyAction, SIGNAL(triggered()), this, SLOT(copy()));    pasteAction = new QAction(tr("&Paste"), this);    pasteAction->setIcon(QIcon(":/images/paste.png"));    pasteAction->setShortcut(QKeySequence::Paste);    pasteAction->setStatusTip(tr("Paste the clipboard's contents at "                                 "the cursor position"));    connect(pasteAction, SIGNAL(triggered()), this, SLOT(paste()));    closeAction = new QAction(tr("Cl&ose"), this);    closeAction->setShortcut(QKeySequence::Close);    closeAction->setStatusTip(tr("Close the active window"));    connect(closeAction, SIGNAL(triggered()), mdiArea, SLOT(closeActiveSubWindow()));    closeAllAction = new QAction(tr("Close &All"), this);    closeAllAction->setStatusTip(tr("Close all the windows"));    connect(closeAllAction, SIGNAL(triggered()), this, SLOT(close()));    tileAction = new QAction(tr("&Tile"), this);    tileAction->setStatusTip(tr("Tile the windows"));    connect(tileAction, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows()));    cascadeAction = new QAction(tr("&Cascade"), this);    cascadeAction->setStatusTip(tr("Cascade the windows"));    connect(cascadeAction, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows()));    nextAction = new QAction(tr("Ne&xt"), this);    nextAction->setShortcut(QKeySequence::NextChild);    nextAction->setStatusTip(tr("Move the focus to the next window"));    connect(nextAction, SIGNAL(triggered()), mdiArea, SLOT(activateNextSubWindow()));    previousAction = new QAction(tr("Pre&vious"), this);    previousAction->setShortcut(QKeySequence::PreviousChild);    previousAction->setStatusTip(tr("Move the focus to the previous " "window"));    connect(previousAction, SIGNAL(triggered()),mdiArea, SLOT(activatePreviousSubWindow()));    separatorAction = new QAction(this);    separatorAction->setSeparator(true);    aboutAction = new QAction(tr("&About"), this);    aboutAction->setStatusTip(tr("Show the application's About box"));    connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));    aboutQtAction = new QAction(tr("About &Qt"), this);    aboutQtAction->setStatusTip(tr("Show the Qt library's About box"));    connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));    windowActionGroup = new QActionGroup(this);}void MainWindow::createMenus(){    fileMenu = menuBar()->addMenu(tr("&File"));    fileMenu->addAction(newAction);    fileMenu->addAction(openAction);    fileMenu->addAction(saveAction);    fileMenu->addAction(saveAsAction);    fileMenu->addSeparator();    fileMenu->addAction(exitAction);    editMenu = menuBar()->addMenu(tr("&Edit"));    editMenu->addAction(cutAction);    editMenu->addAction(copyAction);    editMenu->addAction(pasteAction);    windowMenu = menuBar()->addMenu(tr("&Window"));    windowMenu->addAction(closeAction);    windowMenu->addAction(closeAllAction);    windowMenu->addSeparator();    windowMenu->addAction(tileAction);    windowMenu->addAction(cascadeAction);    windowMenu->addSeparator();    windowMenu->addAction(nextAction);    windowMenu->addAction(previousAction);    windowMenu->addAction(separatorAction);    menuBar()->addSeparator();    helpMenu = menuBar()->addMenu(tr("&Help"));    helpMenu->addAction(aboutAction);    helpMenu->addAction(aboutQtAction);}void MainWindow::createToolBars(){    fileToolBar = addToolBar(tr("File"));    fileToolBar->addAction(newAction);    fileToolBar->addAction(openAction);    fileToolBar->addAction(saveAction);    editToolBar = addToolBar(tr("Edit"));    editToolBar->addAction(cutAction);    editToolBar->addAction(copyAction);    editToolBar->addAction(pasteAction);}void MainWindow::createStatusBar(){    readyLabel = new QLabel(tr(" Ready"));    statusBar()->addWidget(readyLabel, 1);}void MainWindow::addEditor(Editor *editor){    connect(editor, SIGNAL(copyAvailable(bool)),            cutAction, SLOT(setEnabled(bool)));    connect(editor, SIGNAL(copyAvailable(bool)),            copyAction, SLOT(setEnabled(bool)));    QMdiSubWindow *subWindow = mdiArea->addSubWindow(editor);    windowMenu->addAction(editor->windowMenuAction());    windowActionGroup->addAction(editor->windowMenuAction());    subWindow->show();}Editor *MainWindow::activeEditor(){    QMdiSubWindow *subWindow = mdiArea->activeSubWindow();    if (subWindow)        return qobject_cast<Editor *>(subWindow->widget());    return 0;}


源码下载地址:

2 0