鱼C论坛

 找回密码
 立即注册
查看: 1671|回复: 0

[技术交流] Qt-006对话框

[复制链接]
发表于 2018-11-24 19:19:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 moc 于 2018-11-25 18:38 编辑

1、基本概念
对话框通常是一个顶层窗口,出现在程序最上层,用于实现短期任务或者简洁的用户交互。
Qt 中使用QDialog类实现对话框。
QDialog(及其子类,以及所有Qt::Dialog类型的类)类,对于其 parent 指针都有额外的解释
        如果 parent 为 NULL,则该对话框会作为一个顶层窗口,否则则作为其父组件的子对话框(此时,其默认出现的位置是 parent 的中心)。
顶层窗口与非顶层窗口的区别:
        顶层窗口与非顶层窗口的区别在于,顶层窗口在任务栏会有自己的位置,而非顶层窗口则会共享其父组件的位置。
对话框分为模态对话框和非模态对话框。
模态对话框:
        该对话框会阻塞同一应用程序中其它窗口的输入。比如“打开文件”功能,当打开文件对话框出现时,我们是不能对除此对话框之外的窗口部分进行操作的。
非模态对话框:
        与模态对话框相反。如查找对话框,我们可以在显示着查找对话框的同时,继续对记事本的内容进行编辑。
2、标准对话框
        标准对话框,是 Qt 内置的一系列对话框,用于简化开发。事实上,有很多对话框都是通用的,比如打开文件、设置颜色、打印设置等;这些对话框在所有程序中几乎相同,因此没有必要在每一个程序中都自己实现这么一个对话框。
Qt 的内置对话框大致分为以下几类:
标准对话框功能
QColorDialog选择颜色
QFileDialog选择文件或者目录
QFontDialog选择字体
QInputDialog允许用户输入一个值,并将其值返回
QMessageBox模态对话框,用于显示信息、询问问题等
QPageSetupDialog为打印机提供纸张相关的选项
QPrintDialog打印机配置
QPrintPreviewDialog打印预览
QProgressDialog显示操作过程
3、自定义消息框
模态与非模态的实现:
QDialog::exec()   ==>  实现应用程序级别的模态对话框
QDialog::open()   ==>  实现窗口级别的模态对话框
QDialog::show()   ==>  实现非模态对话框。
模态对话框:
Qt 有两种级别的模态对话框:
应用程序级别的模态
        当该种模态的对话框出现时,用户必须首先对对话框进行交互,直到关闭对话框,然后才能访问程序中其他的窗口。
窗口级别的模态
        该模态仅仅阻塞与对话框关联的窗口,但是依然允许用户与程序中其它窗口交互。窗口级别的模态尤其适用于多窗口模式。
一般默认是应用程序级别的模态。如在下面的示例中,调用了exec()将对话框显示出来,因此这就是一个模态对话框;当对话框出现时,我们不能与主窗口进行任何交互,直到我们关闭了该对话框。
void MainWindow::open()
{
            QDialog dialog;
            dialog.setWindowTitle(tr("Hello, dialog!"));
dialog.exec();
}
非模态对话框:
void MainWindow::open()
{
    QDialog dialog(this);
    dialog.setWindowTitle(tr("Hello, dialog!"));
    dialog.show();
}
上面创建的非模态对话框竟然一闪而过!这是因为,show()函数不会阻塞当前线程,对话框会显示出来,然后函数立即返回,代码继续执行。
注意:  =>dialog 是建立在栈上的,show()函数返回,MainWindow::open()函数结束,dialog 超出作用域被析构,因此对话框消失了。将 dialog 改成堆上建立,当然就没有这个问题了.
void MainWindow::open()
{
    QDialog *dialog = new QDialog;
    dialog->setWindowTitle(tr("Hello, dialog!"));
    dialog->show();
}
如果足够细心,应该发现上面的代码是有问题的:dialog 存在内存泄露!dialog 使用 new 在堆上分配空间,却一直没有 delete。解决方案也很简单:将 MainWindow 的指针赋给 dialog 即可。
不过,这样做有一个问题:如果对话框不是在一个界面类中出现呢?由于QWidget的 parent 必须是QWidget指针,那就限制了我们不能将一个普通的 C++ 类指针传给 Qt 对话框。另外,如果对内存占用有严格限制的话,当我们将主窗口作为 parent 时,主窗口不关闭,对话框就不会被销毁,所以会一直占用内存。在这种情景下,我们可以设置 dialog 的WindowAttribute:
void MainWindow::open()
{
    QDialog *dialog = new QDialog;
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setWindowTitle(tr("Hello, dialog!"));
    dialog->show();
}
setAttribute()函数设置对话框关闭时,自动销毁对话框。
4、消息对话框
QMessageBox用于显示消息提示,它的几个 static 函数:
显示关于对话框:
原型: void about(QWidget * parent, const QString & title, const QString & text)
最简单的对话框,其标题是 title,内容是 text,父窗口是 parent;对话框只有一个 OK 按钮。
显示关于 Qt 对话框:
原型: void aboutQt(QWidget * parent, const QString & title = QString())
用于显示有关 Qt 的信息。
显示严重错误对话框:
原型: StandardButton critical(QWidget * parent, const QString & title, const QString & text,
                        StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)

这个对话框将显示一个红色的错误符号。我们可以通过 buttons 参数指明其显示的按钮。默认情况下只有一个 Ok 按钮,我们可以使用StandardButtons类型指定多种按钮。
提示信息对话框:
原型: StandardButton information(QWidget * parent, const QString & title, const QString & text,
                        StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)

与错误提示对话框类似,不同的是对话框提供一个普通信息图标。
询问对话框:
原型: StandardButton question(QWidget * parent,const QString & title, const QString & text,
                         StandardButtons buttons = StandardButtons( Yes | No ), StandardButton defaultButton = NoButton)

对话框提供一个问号图标,并且其显示的按钮是“是”和“否”。
警告对话框:
原型: StandardButton warning(QWidget * parent, const QString & title, const QString & text,
                        StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)

对话框提供一个黄色叹号图标。
示例:
if (QMessageBox::Yes == QMessageBox::question(this,
              tr("Question"), tr("Are you OK?"),
              QMessageBox::Yes | QMessageBox::No,
              QMessageBox::Yes)) 
{
    QMessageBox::information(this, tr("Hmmm..."), tr("I'm glad to hear that!"));
} 
else 
{
    QMessageBox::information(this, tr("Hmmm..."), tr("I'm sorry!"));
}
使用QMessageBox::question()来询问一个问题。
这个对话框的父窗口是 this。
QMessageBox是QDialog的子类,这意味着它的初始显示位置将会是在 parent 窗口的中央。
第二个参数是对话框的标题。
第三个参数是我们想要显示的内容。

这里就是我们需要询问的文字。下面,我们使用或运算符(|)指定对话框应该出现的按钮。这里我们希望是一个 Yes 和一个 No。
最后一个参数指定默认选择的按钮。
这个函数有一个返回值,用于确定用户点击的是哪一个按钮。按照我们的写法,应该很容易的看出,这是一个模态对话框,因此我们可以直接获取其返回值。
QMessageBox类的 static 函数优点是方便使用,缺点也很明显:非常不灵活。我们只能使用简单的几种形式。为了能够定制QMessageBox细节,必须使用QMessageBox的属性设置 API。
5、标准文件对话框
QFileDialog,也就是文件对话框。
原型: 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,每个选项可以使用 | 运算组合起来。
返回值: 选择的文件路径。
将返回值其赋值给 path。通过判断 path 是否为空,可以确定用户是否选择了某一文件。只有当用户选择了一个文件时,我们才执行后续的操作。

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-23 18:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表