1. 程式人生 > >Qt簡易文字編輯器

Qt簡易文字編輯器

程式碼及註釋如下:

//mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QTextEdit>
#include <QMainWindow>

//class QTextEdit;


class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);//指定這個構造器只能被明確的呼叫/使用, 不能作為型別轉換操作符被隱含的使用。
    //C++中, 一個引數的建構函式(或者除了第一個引數外其餘引數都有預設值的多參建構函式),
                //承擔了兩個角色。 1 是個構造器 ,2 是個預設且隱含的型別轉換操作符。

    //MainWindow::MainWindow(QWidget *parent) :
    //    QMainWindow(parent)
    //                      為實現的內容:MainWindow繼承QMainWindow(parent),
    //但是此時因為QMainWindow是主視窗,可以不需要繼承其他的視窗

    ~MainWindow();

private slots:
    //private slots:
    void openFile();
    void saveFile();

    //public slots:在這個區內宣告的槽意味著任何物件都可將訊號與之相連線。這對於元件程式設計非常有用,
                  //你可以建立彼此互不瞭解的物件,將它們的訊號與槽進行連線以便資訊能夠正確的傳遞。

    //protected slots:在這個區內宣告的槽意味著當前類及其子類可以將訊號與之相連線。這適用於那些槽,
                                          //它們是類實現的一部分,但是其介面介面卻面向外部。

    //private slots:在這個區內宣告的槽意味著只有類自己可以將訊號與之相連線。這適用於聯絡非常緊密的類。

private:
    QAction *openAction;
    QAction *saveAction;

    QTextEdit *textEdit;
};

#endif // MAINWINDOW_H


//mainwindow.cpp

//#include <QtGui>
#include <QtWidgets>
#include "mainwindow.h"
#include <QStatusBar>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)//
{
    openAction = new QAction(QIcon(":/images/file-open"), tr("&Open..."), this);
    openAction->setShortcuts(QKeySequence::Open);
    openAction->setStatusTip(tr("Open an existing file"));
    connect(openAction, &QAction::triggered, this, &MainWindow::openFile);


//因為沒有加入狀態列,所以第10行和第15行的程式碼無法顯示,???後面加上//
//triggered表示觸發器的意思,表示如果openAction觸發了會連線到openFile上,槽函式可以是普通的函式

    saveAction = new QAction(QIcon(":/images/file-save"), tr("&Save..."), this);
    saveAction->setShortcuts(QKeySequence::Save);
    saveAction->setStatusTip(tr("Save a new file"));
    QObject::connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);

    QMenu *file = menuBar()->addMenu(tr("&File"));
    //QMenuBar *QMainWindow::menuBar() const
    //QMenu *QMenuBar::addMenu(const QIcon &icon, const QString &title)
    file->addAction(openAction);
    file->addAction(saveAction);
//可以有多個addMenu(),但是工具欄只能有一個橫欄,只需addToolBar

//QMenuBar:就是所有視窗的選單欄,在此基礎上新增不同的QMenu和QAction
//QMenu:選單欄裡面選單,可以顯示文字和圖示,但是並不負責執行操作,有點類似label的作用
//QAction: Qt 將使用者與介面進行互動的元素抽象為一種“動作”,使用QAction類表示。QAction才是真正負責執行操作的部件。

    //QMenu與QMenuBar的區別
    QToolBar *toolBar = addToolBar(tr("&File"));//QToolBar *QMainWindow::addToolBar(const QString &title)
    toolBar->addAction(openAction);
    toolBar->addAction(saveAction);


    textEdit = new QTextEdit(this);
    setCentralWidget(textEdit);
//一個Qt主視窗應用程式必須有一箇中心視窗部件(Central Widget)。當你採用Qt Designer建立主視窗時,預設情況下,
//    系統已經為你建立了一箇中心視窗部件,它是子類化QWidget的。
//結合程式碼可以方便的設定中心視窗部件,可以呼叫主視窗類的setCentralWidget()方法,它的原型如下:
//void QMainWindow::setCentralWidget ( QWidget * widget )

    statusBar();//QStatusBar *QMainWindow::statusBar() const
}

MainWindow::~MainWindow()
{

}

void MainWindow::openFile()
{
    QString path = QFileDialog::getOpenFileName(this, tr("Open File"), ".", tr("Text Files(*.txt)"));
    //QFileDialog::getOpenFileName()返回值是選擇的檔案路徑。
    //我們將其賦值給 path。通過判斷 path 是否為空,可以確定使用者是否選擇了某一檔案。只有當用戶選擇了一個檔案時,我們才執行下面的操作。
    //QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),"/home",tr("Images (*.png *.xpm *.jpg)"));
    if(!path.isEmpty()) {//若不為空,進行操作,反之,直接彈出另一個文字框


        QFile file(path);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {                  //1110|0010
            QMessageBox::warning(this, tr("Read File"), tr("Cannot open file:\n%1").arg(path));
//[static] int QMessageBox::warning(QWidget *parent, const QString &title, const QString &text, int button0, int button1, int button2 = 0)
            return;
        }
        QTextStream in(&file);
        textEdit->setText(in.readAll());
        file.close();
        //首先,我們建立一個QFile物件,將使用者選擇的檔案路徑傳遞給這個物件。然後我們需要開啟這個檔案,使用的是QFile::open(),
        //其引數是指定的開啟方式,這裡我們使用只讀方式和文字方式開啟這個檔案(因為我們選擇的是字尾名 txt 的檔案,可以認為是文
        //本檔案。當然,在實際應用中,可能需要進行進一步的判斷)。QFile::open()開啟成功則返回 true,由此繼續進行下面的操作:
        //使用QTextStream::readAll()讀取檔案所有內容,然後將其賦值給QTextEdit顯示出來。最後不要忘記關閉檔案。

    } else {
        QMessageBox::warning(this, tr("Path"), tr("You did not select any file."));
        //第一個tr中的內容是對話方塊的標題
        //第二個tr中的內容是對話方塊的警示部分
    }


}

void MainWindow::saveFile()
{
    QString path = QFileDialog::getSaveFileName(this, tr("Save File"), ".", tr("Text Files(*.txt)"));
    if(!path.isEmpty()) {
        QFile file(path);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            QMessageBox::warning(this, tr("Write File"), tr("Cannot open file:\n%1").arg(path));
            return;
        }
        QTextStream out(&file);
        out << textEdit->toPlainText();
        file.close();
    } else {
        QMessageBox::warning(this, tr("Path"), tr("You did not select any file."));
    }
}
//main.cpp

#include <QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    MainWindow w;
    w.show();

    return a.exec();
}