【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

至此,咱们的代码已经介绍完毕,立刻能够编译运行一下了:

相关文章
相关标签/搜索