对话框的模态与非模态

在Qt中,对话框根据与用户交互的方式,分为模态对话框和非模态对话框。

1、模态对话框(Modal Dialog)

定义:模态对话框在打开时会阻塞父窗口,直到对话框关闭。用户必须先处理对话框(如输入信息、按下按钮等)才能返回窗口。

使用场景:常用于需要用户确认或输入信息的场景。例如确认删除、输入用户名和密码等。

创建方式:使用QDialog创建对象,并设置其模式。

QDialog dialog(this);//创建对话框并设置this为依赖的父窗体
dialog.exec(); // 弹出对话框并阻塞当前线程   

如果不添加dialog.exec()的话,我们的对话框就会一闪而过。这个阻塞的函数,我们在主函数中也可以看得到。它的目的就是起阻塞功能,不然,当对象被创建,运行结束之后一瞬间就被释放掉,这样就无法看到图形界面了。 

2、非模态对话框(Non-modal Dialog)


定义: 非模态对话框不会阻塞父窗口。用户可以同时与父窗口和对话框进行交互。  
使用场景: 常用于不需要用户立即响应的情境,例如帮助窗口、设置窗口等。  
创建方式: 同样使用 `QDialog`,但不调用 `exec()` 方法,而是直接调用 `show()` 方法:  

QDialog *dialog = new QDialog(this);  
dialog->show(); // 弹出非模态对话框,不会阻塞  

 这里使用new创建对象的目的也是为了防止对象创建即被释放,所以这里我们需要将对象建立在堆区。如果我们还是使用exec方法的话,虽然可以防止被释放,但是这样,就不是非模态的对话框了。这里我们使用show方法显示对话框。

但是这时我们有个问题,那就是,对象是在堆区创建的,当我点击关闭后,对象资源并没有被释放。如果有一个人三天三夜一直选择这个选项不停歇,造成的内存泄露将会使程序崩溃。虽然很少有人会这么做,但是这始终是一个潜在的危险、bug。

这时我们可以这样干:

    connect(ui->actionregister,&QAction::triggered,[=]()
    {
        QDialog *dia=new QDialog(this);
        dia->setAttribute(Qt::WA_DeleteOnClose);
        dia->show();
    });

通过setAttribute方法,传入一个参数,参数由qt提供。意思是:当close按钮被按下时,delete释放资源。 

总结

模态对话框: 阻塞父窗口,用户必须处理。  
非模态对话框: 不阻塞,用户可以自由切换。  

标准对话框

1、QMessageBox(消息对话框)

QMessageBox是Qt框架中的一个类,用于创建标准化的消息框,常用来向用户显示信息、警告或询问用户的选择。它提供了几种不同类型的消息框,比如:信息框、警告框、询问框和错误框。

使用的基本步骤

包含头文件:在使用 QMessageBox之前,你需要包含相应的头文件。

创建消息框:你可以使用 QMessageBox 的静态方法来创建不同类型的消息框。以下是一些示例:

QMessageBox::critical(this,"错误","critical");//错误消息框
QMessageBox::information(this,"提示","information");//信息提示框
QMessageBox::warning(this,"警告","warning");//警告信息框

QMessageBox::question(this,"询问","question");//询问消息框
//对于消息提示框,会默认生成两个按钮选项,我们如何确认选择了什么按钮呢?
//创建一个对象接收返回值:返回值是一个按钮类型,不知道就使用auto
auto reply = QMessageBox::question(this,"询问","111111111111",QMessageBox::Yes|QMessageBox::No);
if(reply==QMessageBox::Yes){
    qDebug()<<"点击了yes";
}
else {
    qDebug()<<"no";
}

除了使用这些基本内容以外,我们还可以使用一些api接口去设置按钮和图标:

QMessageBox msgBox(this);
msgBox.setWindowTitle("自定义标题");  
msgBox.setText("这是自定义消息框的内容。");  
msgBox.setIcon(QMessageBox::Information);  
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);  
msgBox.setDefaultButton(QMessageBox::Ok);  
int ret = msgBox.exec();  
if (ret == QMessageBox::Ok) {  
// 用户点击了“确定”  
} else {  
// 用户点击了“取消”  
}

自定义时的常用方法:

  • setText(const QString &text):设置消息框的文本内容。
  • setInformativeText(const QString &text):设置更详细的信息文本。
  • setStandardButtons(QMessageBox::StandardButtons buttons):设置标准按钮。
  • setIcon(QMessageBox::Icon icon):设置消息框的图标。
  • exec():显示消息框并等待用户响应。

2、QFileDialog(文件对话框)

QFileDialog 是 Qt 框架中的一个类,它提供了一个标准的文件对话框,用户可以用来选择文件或目录。该类可以用来打开文件、保存文件或选择目录,具有友好的用户界面,便于用户进行文件系统的交互。

基本步骤

包含头文件:在使用 QFileDialog 前,你需要包含相应的头文件。 

打开对话框:QFileDialog 提供了多个静态方法来显示对话框。例如,打开文件对话框:

QFileDialog *fd=new QFileDialog(this);
fd->setWindowTitle("打开文件");
fd->show();

QFileDialog *fd=new QFileDialog(this);
fd->setWindowTitle("打开文件");
fd->open();

上面两种打开的方法分别对应非模态对话框模态对话框

下面来说一种更加常用的方法:

文件对话框中的getOpenFileName方法。

QString fileName = QFileDialog::getOpenFileName(this, "打开文件", "", "所有文件 (*.*);;文本文件 (*.txt)");

 该方法的返回值类型:QString:文件路径。

传参-》参数1:父窗体,参数2:标题,参数3:文件路径,参数4:过滤后缀名。

自定义的QFileDialog:

dialog.setFileMode(QFileDialog::ExistingFiles);  
dialog.setNameFilter("图片文件 (*.png *.jpg *.gif);;所有文件 (*)");  
dialog.setViewMode(QFileDialog::List);  

if (dialog.exec()) {  
QStringList fileNames = dialog.selectedFiles();  
//处理选择的文件 
}

setFileMode() 可以设置对话框的文件模式,例如:

  • QFileDialog::AnyFile:用户可以选择任何文件。

  • QFileDialog::ExistingFiles:用户可以选择一个或多个已存在的文件。

  • QFileDialog::Directory:用户选择一个目录。

  • 设置文件过滤器setNameFilter() 可以设置文件类型过滤器,帮助用户快速找到所需文件。

  • 获取选择结果:使用 selectedFiles() 和 selectedNameFilter() 方法获取用户所选文件或名称过滤器。

  • 视图模式setViewMode() 可以设置对话框的显示模式,例如 QFileDialog::ListQFileDialog::Detail等。

3、QFontDialog(字体对话框)

在 Qt 中,没有名为 QFintDialog 的类,可能是由于输入错误或误拼写。您可能想询问的是 QFontDialog,这是 Qt 提供的一个类,用于显示字体选择对话框,让用户选择字体。

你可以使用 getFont() 方法来显示选择字体的对话框。例如:

bool ok;  
font = QFontDialog::getFont(&ok, QFont("Times",10), this);  
if (ok) {  
// 用户选择了字体 
} 
else {  
// 用户取消了选择 
}

 你也可以创建一个自定义的 QFontDialog 实例,并设置一些选项,例如设置当前字体和字体选项:

fontDialog.setCurrentFont(QFont("Arial",12));  
fontDialog.setOption(QFontDialog::ShowSample, true);  
fontDialog.setOption(QFontDialog::DontUseNativeDialog, true); // 使用非原生对话框 if (fontDialog.exec() == QDialog::Accepted) {  
QFont selectedFont = fontDialog.selectedFont();  
//处理所选字体 }

主要方法和特点- getFont():显示字体选择对话框并返回用户选择的字体。

  • setCurrentFont(const QFont &font):设置对话框中将显示的当前字体。
  • setOption():设置对话框的选项,例如:
  • QFontDialog::ShowSample:显示字体样本。
  • QFontDialog::DontUseNativeDialog:使用 Qt 自带的对话框,而不是操作系统的原生对话框。

4、QColorDialog(颜色对话框)

QColorDialog 是 Qt 框架中的一个类,用于显示一个标准的颜色选择对话框,允许用户选择颜色。它非常灵活且易于使用,可以集成到 Qt 应用程序中。

QColorDialog 提供了多个静态方法来显示颜色选择对话框。最常用的方法是 getColor()

QColorDialog * dia = new QColorDialog(this);
QColor color =getColor();

if (color.isValid()) {  
    // 用户选择了有效颜色 
    qDebug()<<color.red()<<color.green()<<color.blue();
}

 你可以创建一个自定义的 QColorDialog 实例,并设置一些选项,例如指定初始颜色:

dialog.setCurrentColor(Qt::blue); // 设置当前颜色 dialog.setOption(QColorDialog::ShowAlphaChannel, true); // 显示alpha通道 if (dialog.exec() == QDialog::Accepted) {  
QColor selectedColor = dialog.selectedColor(); // 获取选中的颜色 //处理所选颜色 }

主要方法和特点- getColor():显示颜色选择对话框并返回用户选择的颜色。

  • setCurrentColor(const QColor &color):设置对话框中将显示的当前颜色。
  • setOption():设置对话框的选项,例如:
  • QColorDialog::ShowAlphaChannel:显示 alpha 通道,用于选择透明度。
  • QColorDialog::DontUseNativeDialog:使用 Qt 自带的对话框,而不是操作系统的原生对话框。

5、OtherDialog(其它对话框)

QErrorMessage、QInputDialog、QProgressDialog......


课后思考:设计一个qq群聊(只需要一个聊天对话框就行),可以发消息,消息的字体可以改变颜色、大小等。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐