在前面的章節中,咱們討論了 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)
不過注意,它的全部參數都是可選的,所以在必定程度上說,這個函數也是簡單的。這六個參數分別是:對象
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
至此,咱們的代碼已經介紹完畢,立刻能夠編譯運行一下了: