QT5.4 例子學習-01-Application Example

1.類定義


class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow();

protected:
    void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE;

private slots:
    void newFile();
    void open();
    bool save();
    bool saveAs();
    void about();
    void documentWasModified();

private:
    void createActions();
    void createMenus();
    void createToolBars();
    void createStatusBar();
    void readSettings();
    void writeSettings();
    bool maybeSave();
    void loadFile(const QString &fileName);
    bool saveFile(const QString &fileName);
    void setCurrentFile(const QString &fileName);
    QString strippedName(const QString &fullFileName);

    QPlainTextEdit *textEdit;
    QString curFile;

    QMenu *fileMenu;
    QMenu *editMenu;
    QMenu *helpMenu;
    QToolBar *fileToolBar;
    QToolBar *editToolBar;
    QAction *newAct;
    QAction *openAct;
    QAction *saveAct;
    QAction *saveAsAct;
    QAction *exitAct;
    QAction *cutAct;
    QAction *copyAct;<pre name="code" class="cpp">MainWindow::MainWindow()
{
    textEdit = new QPlainTextEdit;
    setCentralWidget(textEdit);

    createActions();
    createMenus();
    createToolBars();
    createStatusBar();

    readSettings();

    connect(textEdit->document(), SIGNAL(contentsChanged()),
            this, SLOT(documentWasModified()));

    setCurrentFile("");
    setUnifiedTitleAndToolBarOnMac(true);
}

QAction *pasteAct; QAction *aboutAct; QAction *aboutQtAct;};

QWidget::closeEvent()用於監聽用戶關閉動作,提醒沒有保存修改.

#include <QtWidgets>
#include "mainwindow.h"
QtWidgets裏面包含Qt Core等類,爲什麼不把QtWidgets包含在mainwindow.h裏呢?因爲頭文件太大了,會影響性能.

MainWindow::MainWindow()
{
    textEdit = new QPlainTextEdit;
    setCentralWidget(textEdit);

    createActions();
    createMenus();
    createToolBars();
    createStatusBar();

    readSettings();

    connect(textEdit->document(), SIGNAL(contentsChanged()),
            this, SLOT(documentWasModified()));

    setCurrentFile("");
    setUnifiedTitleAndToolBarOnMac(true);
}

QMainWindow::setCentralWidget()用於告訴widget這個控件將佔用windows中間區域在tool bars和status bars中間

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (maybeSave()) {
        writeSettings();
        event->accept();
    } else {
        event->ignore();
    }
}
用戶嘗試關閉窗口的時候,maybesave詢問用戶是否存儲變化.

void MainWindow::newFile()
{
    if (maybeSave()) {
        textEdit->clear();
        setCurrentFile("");
    }
}
清空當前的東西,詢問是否存儲.

void MainWindow::open()
{
    if (maybeSave()) {
        QString fileName = QFileDialog::getOpenFileName(this);
        if (!fileName.isEmpty())
            loadFile(fileName);
    }
}
這些打開啊實際上就是要一個文件路徑.

bool MainWindow::save()
{
    if (curFile.isEmpty()) {
        return saveAs();
    } else {
        return saveFile(curFile);
    }
}
如果沒提供名字,就saveAs()

bool MainWindow::saveAs()
{
    QFileDialog dialog(this);
    dialog.setWindowModality(Qt::WindowModal);
    dialog.setAcceptMode(QFileDialog::AcceptSave);
    QStringList files;
    if (dialog.exec())
        files = dialog.selectedFiles();
    else
        return false;

    return saveFile(files.at(0));
}

Qt::WindowModal 阻塞自己的父輩.點確定得到一個文件路徑,點取消返回空,什麼都不做.

QMessageBox::about定義了一個靜態顯示關於的方便函數.使用tr()用於所有可見的地方,是個非常好的習慣,因爲可以用工具翻譯.

QAction就是一個下拉菜單裏的項,是一個動作,可以放在QMenu和QToolBar裏面,或者任意實現了QWidget::actionEvent()函數的Widget裏面

可以顯示爲菜單,圖標,快捷鍵,tip,狀態欄等方式,點了之後發送Triggered()信號


    cutAct->setEnabled(false);
    copyAct->setEnabled(false);
    connect(textEdit, SIGNAL(copyAvailable(bool)),
            cutAct, SLOT(setEnabled(bool)));
    connect(textEdit, SIGNAL(copyAvailable(bool)),
            copyAct, SLOT(setEnabled(bool)));

當你選中文字的時候發射copyAvailable(true),這個時候複製和剪切菜單就不虛,相反就是虛的.

創建了Action以後還有一個關鍵點是添加到Menu或者toolbar上面,用addAction方法就好了!

void MainWindow::readSettings()
{
    QSettings settings("QtProject", "Application Example");
    QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
    QSize size = settings.value("size", QSize(400, 400)).toSize();
    resize(size);
    move(pos);
}
從QSetting裏面讀取獨立的用戶設置,然後用QWidget::resize()在QWidget::move()之前
bool MainWindow::maybeSave()
{
    if (textEdit->document()->isModified()) {
        QMessageBox::StandardButton ret;
        ret = QMessageBox::warning(this, tr("Application"),
                     tr("The document has been modified.\n"
                        "Do you want to save your changes?"),
                     QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
        if (ret == QMessageBox::Save)
            return save();
        else if (ret == QMessageBox::Cancel)
            return false;
    }
    return true;
}
如果文檔被修改了,就彈出詢問對話框,不然就直接返回false

void MainWindow::loadFile(const QString &fileName)
{
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly | QFile::Text)) {
        QMessageBox::warning(this, tr("Application"),
                             tr("Cannot read file %1:\n%2.")
                             .arg(fileName)
                             .arg(file.errorString()));
        return;
    }

    QTextStream in(&file);
#ifndef QT_NO_CURSOR
    QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
    textEdit->setPlainText(in.readAll());
#ifndef QT_NO_CURSOR
    QApplication::restoreOverrideCursor();
#endif

    setCurrentFile(fileName);
    statusBar()->showMessage(tr("File loaded"), 2000);
}
對文件的操作都類似,先要通過名字得到文件描述符,然後在標準流來操作文件.

QTextStream 自動地轉化8bit數據到Unicode QString,並且支持多種內碼,默認支持 Latin-1 

因爲讀取可能要花些時間,把光標弄成等待的形狀.

void MainWindow::setCurrentFile(const QString &fileName)
{
    curFile = fileName;
    textEdit->document()->setModified(false);
    setWindowModified(false);

    QString shownName = curFile;
    if (curFile.isEmpty())
        shownName = "untitled.txt";
    setWindowFilePath(shownName);
}
setModified用於設置標誌,但這個標誌是自動的嗎?你編輯文本的時候,肯定有一個信號吧,那麼槽的話估計也要修改這個標誌的.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章