前言
MessageDialog是QML中的一个消息弹窗组件,它可以提供简单的消息提示,也可以实现简单的yes or no的选择。它在Qt6中会有几种模式,需要根据不同的场景灵活选择。它也和QWidget中的QMessageBox是同一个层级的产物。
一、代码例子
cpp
import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtQuick.Dialogs 1.3
Window {
visible: true
width: 640
height: 480
title: qsTr("QmlMessageDialog")
Row {
anchors.centerIn: parent
spacing: 10
Button {
text: "询问"
onClicked: askDlg.open()
}
Button {
text: "警告"
onClicked: warnDlg.open()
}
}
MessageDialog {
id: askDlg
title: "提示"
text: "确定要执行操作吗?"
informativeText: "此操作不可撤销"
icon: MessageDialog.Question
standardButtons: MessageDialog.Yes | MessageDialog.No
onYes: console.log("用户点了 Yes")
onNo: console.log("用户点了 No")
}
MessageDialog {
id: warnDlg
title: "提示"
text: "确定要执行操作吗?"
informativeText: "此操作不可撤销"
icon: MessageDialog.Question
standardButtons: MessageDialog.Yes
onYes: console.log("用户点了 Yes")
}
}
如果是Qt6高版本,可以用qusetion或warning这种接口直接打开,但是我当前版本只能默认用open弹窗。
我希望实现类似QMessageBox的功能,查找帮助文档会有这种默认图标的选择:
还可以自由组合自己想要的按钮,实现对应的信号槽:
可以看到不同的按钮会对应到不同的role,比如Ok和Save对应的都是AcceptRole,对应的处理器是onAccepted。如果你足够敏锐,就应该避免两种按钮的混用,因为它们对应的都是同一个处理器。它们可没有单独的onSave、onOk这种处理器。
它的信号也就只有这么多:
值得一提的是,这些按钮的文本无法自定义,可以加载官方qm翻译文件来实现。实在不行只能放弃这种弹窗,然后自行实现。
二、对比QMessageBox
QMessageBox是QWidget中的消息弹窗,也常被称为消息盒子。
它的使用也很简单,常常在c++代码中这样写:
cpp
/* 一行弹窗,一行判断 */
int ret = QMessageBox::question(nullptr, // 父窗口
"提示", // 标题
"确定要退出吗?", // 正文
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No); // 默认按钮
if (ret == QMessageBox::Yes)
qDebug() << "用户点了 Yes";
else
qDebug() << "用户点了 No";
我们可以已制定标题、正文,也同样可以指定需要的按钮。
这种方法是快速弹窗,你可以自行new一个对象出来,然后exec模态弹出。
这里给一个kimi提供的对比总结:
维度 | QML MessageDialog | QWidget QMessageBox |
---|---|---|
模块 | QtQuick.Dialogs 1.x / labs-platform | QtWidgets |
外观 | 系统原生(Win/macOS/Linux Shell) | Qt 自绘(随 QStyle) |
按钮文字 | 随 系统语言(改不了) | 走 qt_xx.qm 可翻译 |
图标 | 系统图标 | Qt 内置图标 |
富文本 | 基本 HTML 子集 | 完整 HTML |
自定义按钮 | 只能用标准枚举 | 可任意 addButton(text, role) |
信号/槽 | accepted() / rejected() / clicked(button) |
buttonClicked(QAbstractButton*) |
使用方式 | 一行 open() |
exec() 或 static 函数 |
最小依赖 | QML 场景 | QWidget 场景 |
典型代码 | 见下 | 见下 |
三、总结
无论qml还是qwidget,消息弹窗都是非常非常非常常用的一个组件,要求不高的话我们可以直接使用默认,但如果要求较高,希望实现漂亮样式的话,我会建议我们自己重新手搓一个,因为这其实比较简单,只要有足够的时间成本。