1. 程式人生 > >11.文件對話框

11.文件對話框

geb num pop () https size popu tools tps

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

首先,我們需要創建一個帶有文本編輯功能的窗口。借用我們前面的程序代碼,應該可以很方便地完成:

123456789101112131415161718openAction = 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對象添加響應的動作:

1234567/// !!!Qt5connect(openAction, &QAction::triggered, this, &MainWindow::openFile);connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile); /// !!!Qt4connect(openAction, SIGNAL(triggered()), this, SLOT(openFile()));connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile()));

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

12345678910111213141516171819202122232425262728293031323334353637383940414243void 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()來獲取需要打開的文件的路徑。這個函數具有一個長長的簽名:

123456QString 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的內容輸出到一個文件中。關於文件操作,我們會在後面的章節中進一步介紹。

這裏需要註意一點:我們的代碼僅僅是用於演示,很多必須的操作並沒有進行。比如,我們沒有檢查這個文件的實際類型是不是一個文本文件。並且,我們使用了QTextStream::readAll()直接讀取文件所有內容,如果這個文件有 100M,程序會立刻死掉,這些都是實際程序必須考慮的問題。不過這些內容已經超出我們本章的介紹,也就不再詳細說明。

至此,我們的代碼已經介紹完畢,馬上可以編譯運行一下了:

技術分享圖片

來源: https://www.devbean.net/2012/09/qt-study-road-2-file-dialog/


11.文件對話框