【Qt筆記】文件對話框

在前面的章節中,咱們討論了 Qt 標準對話框QMessageBox的使用。所謂標準對話框,其實也就是一個普通的對話框。所以,咱們一樣能夠將QDialog所提供的其它特性應用到這種標準對話框上面。今天,咱們繼續討論另一個標準對話框:QFileDialog,也就是文件對話框。在本節中,咱們將嘗試編寫一個簡單的文本文件編輯器,咱們將使用QFileDialog來打開一個文本文件,並將修改過的文件保存到硬盤。這或許是咱們在本系列中所提供的第一個帶有實際功能的實例。瀏覽器

 

首先,咱們須要建立一個帶有文本編輯功能的窗口。借用咱們前面的程序代碼,應該能夠很方便地完成:編輯器

openAction = new QAction(QIcon(":/images/file-open"), tr("&Open..."), this);
openAction->setShortcuts(QKeySequence::Open);
openAction->setStatusTip(tr("Open an existing file"));

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

QMenu *file = menuBar()->addMenu(tr("&File"));
file->addAction(openAction);
file->addAction(saveAction);

QToolBar *toolBar = addToolBar(tr("&File"));
toolBar->addAction(openAction);
toolBar->addAction(saveAction);

textEdit = new QTextEdit(this);
setCentralWidget(textEdit);

咱們在菜單和工具欄添加了兩個動做:打開和保存。接下來是一個QTextEdit類,這個類用於顯示富文本文件。也就是說,它不只僅用於顯示文本,還能夠顯示圖片、表格等等。不過,咱們如今只用它顯示純文本文件。QMainWindow有一個setCentralWidget()函數,能夠將一個組件做爲窗口的中心組件,放在窗口中央顯示區。顯然,在一個文本編輯器中,文本編輯區就是這個中心組件,所以咱們將QTextEdit做爲這種組件。函數

咱們使用connect()函數,爲這兩個QAction對象添加響應的動做:工具

/// !!!Qt5
connect(openAction, &QAction::triggered, this, &MainWindow::openFile);
connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
 
/// !!!Qt4
connect(openAction, SIGNAL(triggered()), this, SLOT(openFile()));
connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile()));

這些應該都不是問題。咱們應該可以很清楚這些代碼的含義。下面是最主要的openFile()saveFile()這兩個函數的代碼:this

void MainWindow::openFile()
{
    QString path = QFileDialog::getOpenFileName(this,
                                                tr("Open File"),
                                                ".",
                                                tr("Text Files(*.txt)"));
    if(!path.isEmpty()) {
        QFile file(path);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QMessageBox::warning(this, tr("Read File"),
                                 tr("Cannot open file:\n%1").arg(path));
            return;
        }
        QTextStream in(&file);
        textEdit->setText(in.readAll());
        file.close();
    } else {
        QMessageBox::warning(this, tr("Path"),
                             tr("You did not select any file."));
    }
}

void MainWindow::saveFile()
{
    QString path = QFileDialog::getSaveFileName(this,
                                                tr("Open 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."));
    }
}

openFile()函數中,咱們使用QFileDialog::getOpenFileName()來獲取須要打開的文件的路徑。這個函數具備一個長長的簽名:code

QString getOpenFileName(QWidget * parent = 0,
                        const QString & caption = QString(),
                        const QString & dir = QString(),
                        const QString & filter = QString(),
                        QString * selectedFilter = 0,
                        Options options = 0)

不過注意,它的全部參數都是可選的,所以在必定程度上說,這個函數也是簡單的。這六個參數分別是:對象

  • parent:父窗口。咱們前面介紹過,Qt 的標準對話框提供靜態函數,用於返回一個模態對話框(在必定程度上這就是外觀模式的一種體現);
  • caption:對話框標題;
  • dir:對話框打開時的默認目錄,「.」 表明程序運行目錄,「/」 表明當前盤符的根目錄(特指 Windows 平臺;Linux 平臺固然就是根目錄),這個參數也能夠是平臺相關的,好比「C:\\」等;
  • filter:過濾器。咱們使用文件對話框能夠瀏覽不少類型的文件,可是,不少時候咱們僅但願打開特定類型的文件。好比,文本編輯器但願打開文本文件,圖片瀏覽器但願打開圖片文件。過濾器就是用於過濾特定的後綴名。若是咱們使用「Image Files(*.jpg *.png)」,則只能顯示後綴名是 jpg 或者 png 的文件。若是須要多個過濾器,使用「;;」分割,好比「JPEG Files(*.jpg);;PNG Files(*.png)」;
  • selectedFilter:默認選擇的過濾器;
  • options:對話框的一些參數設定,好比只顯示文件夾等等,它的取值是enum QFileDialog::Option,每一個選項可使用 | 運算組合起來。

QFileDialog::getOpenFileName()返回值是選擇的文件路徑。咱們將其賦值給 path。經過判斷 path 是否爲空,能夠肯定用戶是否選擇了某一文件。只有當用戶選擇了一個文件時,咱們才執行下面的操做。在saveFile()中使用的QFileDialog::getSaveFileName()也是相似的。使用這種靜態函數,在 Windows、Mac OS 上面都是直接調用本地對話框,可是 Linux 上則是QFileDialog本身的模擬。這暗示了,若是你不使用這些靜態函數,而是直接使用QFileDialog進行設置,就像咱們前面介紹的 QMessageBox 的設置同樣,那麼獲得的對話框極可能與系統對話框的外觀不一致。這一點是須要注意的。圖片

首先,咱們建立一個QFile對象,將用戶選擇的文件路徑傳遞給這個對象。而後咱們須要打開這個文件,使用的是QFile::open(),其參數是指定的打開方式,這裏咱們使用只讀方式和文本方式打開這個文件(由於咱們選擇的是後綴名 txt 的文件,能夠認爲是文本文件。固然,在實際應用中,可能須要進行進一步的判斷)。QFile::open()打開成功則返回 true,由此繼續進行下面的操做:使用QTextStream::readAll()讀取文件全部內容,而後將其賦值給QTextEdit顯示出來。最後不要忘記關閉文件。另外,saveFile()函數也是相似的,只不過最後一步,咱們使用<<重定向,將QTextEdit的內容輸出到一個文件中。關於文件操做,咱們會在後面的章節中進一步介紹。ip

這裏須要注意一點:咱們的代碼僅僅是用於演示,不少必須的操做並無進行。好比,咱們沒有檢查這個文件的實際類型是否是一個文本文件。而且,咱們使用了QTextStream::readAll()直接讀取文件全部內容,若是這個文件有 100M,程序會馬上死掉,這些都是實際程序必須考慮的問題。不過這些內容已經超出咱們本章的介紹,也就再也不詳細說明。get

至此,咱們的代碼已經介紹完畢,立刻能夠編譯運行一下了:

相關文章
相關標籤/搜索