关于QMessageBox的一些使用总结和避坑指南

参考学习

Qt中QMessageBox的用法---看这一篇就够了
Qt:使用QMessageBox弹出标准对话框
QMessageBox模态与非模态及QT中的exec()
如何调整QMessageBox的大小
QSS 自定义QMessageBox
python QMessageBox设置标签和按钮居中、中文按钮

使用建议

经过查看多方的资料,并结合个人的使用与配置,个人觉得把QMessageBox的每个child当做独立的子部件进行设置和处理是比较好的方式

可以通过findChildren函数来获取和查看QMessageBox当前的子部件

cpp 复制代码
#include <QApplication>
#include <QMessageBox>
#include <QLabel>
#include <QDebug>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // 创建 QMessageBox
    QMessageBox msgBox;
    msgBox.setText("This is the main text.");  // 主文本
    msgBox.setInformativeText("This is the informative text.");  // 附加文本
    msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
    msgBox.setDefaultButton(QMessageBox::Ok);

    // 列出所有子部件及其对象名
    QList<QWidget *> children = msgBox.findChildren<QWidget *>();
    for (QWidget *child : children) {
        qDebug() << "Class:" << child->metaObject()->className()
                 << "Object Name:" << child->objectName();
    }

    msgBox.exec();

    return app.exec();
}

输出如下

cpp 复制代码
Class: QLabel Object Name: "qt_msgboxex_icon_label"
Class: QLabel Object Name: "qt_msgbox_label"
Class: QDialogButtonBox Object Name: "qt_msgbox_buttonbox"
Class: QPushButton Object Name: ""
Class: QLabel Object Name: "qt_msgbox_informativelabel"

获取并操作子部件

可以先用findChild函数获取QMessageBox的子部件,然后再按子对象的类型操作即可,这在设置子部件的格式时是比较方便的,示意代码如下

cpp 复制代码
void MainWindow::initMessageBox()
{
    m_messageBox = new QMessageBox();
    m_messageBox->setIcon(QMessageBox::Icon::Critical);
    m_messageBox->setModal(false);
    m_messageBox->setStandardButtons(QMessageBox::Ok);
    m_messageBox->setWindowTitle("Device Connect");
    QLabel* mainLabel = m_messageBox->findChild<QLabel*>("qt_msgbox_label");
    if (mainLabel != nullptr) {
        mainLabel->setAlignment(Qt::AlignCenter);
        mainLabel->setText("The device connection is abnormal");
        mainLabel->setStyleSheet("font-size:20px; color:red");
        mainLabel->setFixedWidth(500);
    }
    QDialogButtonBox* buttonBox = m_messageBox->findChild<QDialogButtonBox*>("qt_msgbox_buttonbox");
    if (buttonBox != nullptr) {
        buttonBox->setStandardButtons(QDialogButtonBox::Ok);
        buttonBox->setCenterButtons(true);
        buttonBox->setStyleSheet("font-size:16px;");
    }
}

一些坑

避免设置全局的样式

cpp 复制代码
m_messageBox.setStyleSheet("QLabel{min-width:500 px; font-size: 24px;} QPushButton{ width:250px; font-size: 18px; }");

上面的这种方式,对QLabel样式的设计是作用到有所Label的,即qt_msgboxex_icon_labelqt_msgbox_label等,这样可能导致不是想要的效果

需要先设置Label的内容才可以获取到该Label

这个问题比较隐蔽,实际开发中发现,如果不设置Label内容的话,用findChild函数可能是获取不到该Label,因此操作前最好进行一下非空的判断

cpp 复制代码
 QLabel* mainLabel = m_messageBox->findChild<QLabel*>("qt_msgbox_label");
    if (mainLabel != nullptr) {
        // 操作mainLabel
    }

QMessageBox的模态与非模态

模态对话框

默认创建的QMessageBox都是模态的,用静态方法创建的QMessageBox也是模态的

cpp 复制代码
QMessageBox::warning(this, tr("提示"), text, tr("是"),tr("否"));

非模态对话框

要创建一个非模态(消息)对话框,只能创建一个新的QMessageBox对象

然后调用setModal方法设置为非模态

cpp 复制代码
QMessageBox* msgBox = new QMessageBox(QMessageBox::Warning,"警告",warnMsg);//参数 Icon icon, const QString &title, const QString &text,
msgBox->setModal(false);//设置为非模态
msgBox->setAttribute(Qt::WA_DeleteOnClose); //关掉消息框后删除指针
msgBox->show();
// msgBox->exec();//使用exec()默认是模态的

也可以用msgBox->open();方法显示QMessageBox对话框

如果使用msgBox->exec();程序运行后显示的对话框是模态

关于exec()

  • **QMessageBox::exec()**是重写了QDialog::exec()。调用这个方法会显示模态消息对话框,直到用户关闭了这个对话框
  • 使用带有标准按钮QMessageBox时,函数返回一个StandardButton值,指示单击的标准按钮
  • 当使用带有自定义按钮QMessageBox时,此函数返回一个不透明值;使用clickedButton()确定单击了哪个按钮
cpp 复制代码
QPushButton* btn = msgBox->addButton("查看",QMessageBox::AcceptRole);//添加按钮到消息对话框
if(msgBox->clickedButton()==btn)//如果btn这个按钮被选中
//后续操作

结语

源于工作中的一点思考,不足之处,还请指正

相关推荐
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz8 天前
QML Hello World 入门示例
qt
xcyxiner11 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner12 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner12 天前
DicomViewer (添加模型类)3
qt
xcyxiner13 天前
DicomViewer (目录调整) 2
qt
xcyxiner13 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能15 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G15 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt