[QT] How to customize the window size of QMessageBox, and re-implement beautiful pop-up windows by inheriting QDialog

1. The original pop-up window of QMessageBox

  QMessageBox messageBox(QMessageBox::Question, "提示", "是否保存当前项目?", QMessageBox::Yes | QMessageBox::No);
  messageBox.exec();

insert image description here
It can be seen that the original pop-up window of QMessageBox looks very ugly, sometimes it is big and sometimes small, only the icon that comes with QMessageBox can be used, and the size of the window cannot be customized , that is because the pop-up window is added in the source code The size is set to a more appropriate size, so you cannot customize the size of the pop-up window. The following codes will not work:

   messageBox.setGeometry(800, 300, 450, 225);  //(500,300)设置其位置是有效的,但是设置其大小(450, 225)是无效的
   messageBox.resize(450, 225);                 //resize大小也是无效的

2. The first method on the Internet: change the size of the pop-up window through the style sheet setStyleSheet (the overall appearance is not beautiful)

  QMessageBox messageBox(QMessageBox::Question, "提示", "是否保存当前项目?", QMessageBox::Yes | QMessageBox::No);
  messageBox.setStyleSheet("QLabel{"
                             "min-width:150px;"
                             "min-height:120px;"
                             "font-size:16px;"
                             "}");
  messageBox.exec();

insert image description here
It can be seen that the method through the style sheet is not very beautiful, and the text is not centered.

3. The second method on the Internet: rewrite ShowEvent() to change the size of the pop-up window (it is not beautiful overall)

First implement the code:
MyMessageBox.h

#include <QLabel>
#include <QMessageBox>
#include <QWidget>

class MyMessageBox : public QMessageBox {
    
    
    Q_OBJECT

public:
    MyMessageBox(Icon icon, const QString& title, const QString& text,
                 StandardButtons buttons, QWidget* parent = 0);
    ~MyMessageBox();

protected:
    void showEvent(QShowEvent* event) override;
};

MyMessageBox.cpp

#include "mymessagebox.h"

MyMessageBox::MyMessageBox(Icon icon, const QString& title, const QString& text,
                           StandardButtons buttons, QWidget* parent) :
    QMessageBox(icon, title, text, buttons, parent) {
    
    
}

MyMessageBox::~MyMessageBox() {
    
    
}

void MyMessageBox::showEvent(QShowEvent* event) {
    
    
    QWidget* textLabel = findChild<QWidget*>("qt_msgbox_label");       //获取源码中text的label组件
    QWidget* iconLabel = findChild<QWidget*>("qt_msgbox_icon_label");  //获取源码中icon的label组件

    if (textLabel != nullptr) {
    
      //使用指针之前先判断是否为空
        textLabel->setMinimumSize(450, 255);
        // textLabel->setFixedSize(450, 255);
    }
    if (iconLabel != nullptr) {
    
    
        iconLabel->setMinimumHeight(255);
        iconLabel->setFixedSize(450, 255);
    }
    QMessageBox::showEvent(event);
}

main.cpp

#include <QApplication>

#include "mymessagebox.h"

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

    MyMessageBox messageBox(QMessageBox::Question, "提示", "是否保存当前项目?", QMessageBox::Yes | QMessageBox::No);
    messageBox.exec();

    //w.show();

    return a.exec();
}

解释一下上面的一些代码
Let's take a look at some source codes in QMessageBox:
insert image description here
After setting the setObjectName() property on a certain component, we can get the component outside through the objectName, as follows:

//QLabel继承于QWidget,所以用QWidget*是可以的
QWidget* textLabel = findChild<QWidget*>("qt_msgbox_label");  //获取源码中text的label组件

Then adjust the size of the label component to achieve the purpose of adjusting the size of the pop-up window. You can see that the size of the pop-up window has changed, but it is still not beautiful. The main reason is that the icon is not centered, and it is still in the upper left corner, as shown in the following figure:

insert image description here
So what is the reason for the above problem? Then take a look at some source codes about layout Layout in QMessageBox:
insert image description here
It can be seen that during layout, its icon is always in the position of row 0, column 0, and its Aliment is set to Top, which leads to the icon of QMessageBox Always in the upper left corner.
Therefore, the method of rewriting ShowEvent() does not meet the expectations of achieving a beautiful pop-up window.

4. The best way: Inherit QDialog and reimplement the pop-up window interface (with complete code) (v1.0)

Rewrite a pop-up window TipDialog class, inherited from the QDialog class.
First look at the effect:
insert image description here
directly on the code:
TipDialog.h

#ifndef TIPDIALOG_H
#define TIPDIALOG_H

#include <QDialog>
#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QIcon>
#include <QLabel>
#include <QMessageBox>
#include <QMetaEnum>
#include <QPixmap>
#include <QPushButton>
#include <QVBoxLayout>

class TipDialog : public QDialog {
    
    
    Q_OBJECT

public:
    enum TipIcon {
    
    
        NoIcon = 0,
        Information = 1,
        Question = 2,
        Success = 3,
        Warning = 4,
        Critical = 5
    };
    Q_ENUM(TipIcon)  //使用Q_ENUM注册枚举

    enum StandardButton {
    
    
        //保持与 QDialogButtonBox::StandardButton 一致,后面在创建按钮时会用到 & 运算
        NoButton = 0x00000000,
        Ok = 0x00000400,
        Save = 0x00000800,
        SaveAll = 0x00001000,
        Open = 0x00002000,
        Yes = 0x00004000,
        YesToAll = 0x00008000,
        No = 0x00010000,
        NoToAll = 0x00020000,
        Abort = 0x00040000,
        Retry = 0x00080000,
        Ignore = 0x00100000,
        Close = 0x00200000,
        Cancel = 0x00400000,
        Discard = 0x00800000,
        Help = 0x01000000,
        Apply = 0x02000000,
        Reset = 0x04000000,
        RestoreDefaults = 0x08000000,

        FirstButton = Ok,
        LastButton = RestoreDefaults
    };
    Q_ENUM(StandardButton)
    Q_DECLARE_FLAGS(StandardButtons, StandardButton)
    Q_FLAG(StandardButtons)

    enum ButtonRole {
    
    
        //保持与 QDialogButtonBox::ButtonRole 一致
        InvalidRole = -1,
        AcceptRole,
        RejectRole,
        DestructiveRole,
        ActionRole,
        HelpRole,
        YesRole,
        NoRole,
        ResetRole,
        ApplyRole,

        NRoles
    };

    explicit TipDialog(QWidget* parent = nullptr);
    TipDialog(TipIcon icon, const QString& title, const QString& text, StandardButtons buttons,
              QWidget* parent = nullptr);  //构造函数有默认值的要放后面
    ~TipDialog();

    static void information(QWidget* parent, const QString& title, const QString& text, StandardButtons buttons = Ok);
    static void question(QWidget* parent, const QString& title, const QString& text, StandardButtons buttons = StandardButtons(Yes | No));
    static void success(QWidget* parent, const QString& title, const QString& text, StandardButtons buttons = Ok);
    static void warning(QWidget* parent, const QString& title, const QString& text, StandardButtons buttons = Ok);
    static void critical(QWidget* parent, const QString& title, const QString& text, StandardButtons buttons = Ok);

private:
    void init(const QString& title = QString(), const QString& text = QString());
    void setupLayout();
    QPixmap standardIcon(TipDialog::TipIcon icon);
    void setIcon(TipIcon icon);
    void createButton(StandardButton button);
    void createStandardButtons(StandardButtons buttons);
    void setStandardButtons(StandardButtons buttons);
    //    QString standardTitle(TipDialog::TipIcon icon);
    QString getEnumKey(StandardButton button);
    void addButton(StandardButton button, QDialogButtonBox::ButtonRole buttonRole);

private:
    QLabel* m_pIconLabel;
    QLabel* m_pTextLabel;
    QDialogButtonBox* m_pButtonBox;
    //    QList<QPushButton*> m_pButtonList;
    QString m_text;
};

//在全局任意地方使用"|"操作符计算自定义的枚举量,需要使用Q_DECLARE_OPERATORS_FOR_FLAGS宏
Q_DECLARE_OPERATORS_FOR_FLAGS(TipDialog::StandardButtons)

#endif  // TIPDIALOG_H

TipDialog.cpp

#include "tipdialog.h"

#define fontFamily "宋体"
#define fontSize 12

TipDialog::TipDialog(QWidget* parent) :
    QDialog(parent) {
    
    
    init();
}

TipDialog::TipDialog(TipIcon icon, const QString& title, const QString& text, StandardButtons buttons, QWidget* parent) :
    QDialog(parent) {
    
    
    init(title, text);
    setWindowTitle(title);
    setIcon(icon);
    setStandardButtons(buttons);
    //    setupLayout();
}

TipDialog::~TipDialog() {
    
    }

void TipDialog::information(QWidget* parent, const QString& title, const QString& text, StandardButtons buttons) {
    
    
    TipDialog tip(Information, title, text, buttons, parent);
    tip.exec();
}

void TipDialog::question(QWidget* parent, const QString& title, const QString& text, StandardButtons buttons) {
    
    
    TipDialog tip(Question, title, text, buttons, parent);
    tip.exec();
}

void TipDialog::success(QWidget* parent, const QString& title, const QString& text, StandardButtons buttons) {
    
    
    TipDialog tip(Success, title, text, buttons, parent);
    tip.exec();
}

void TipDialog::warning(QWidget* parent, const QString& title, const QString& text, StandardButtons buttons) {
    
    
    TipDialog tip(Warning, title, text, buttons, parent);
    tip.exec();
}

void TipDialog::critical(QWidget* parent, const QString& title, const QString& text, StandardButtons buttons) {
    
    
    TipDialog tip(Critical, title, text, buttons, parent);
    tip.exec();
}

void TipDialog::init(const QString& title, const QString& text) {
    
    
    resize(QSize(450, 225));
    setWindowIcon(QIcon(":/new/prefix1/Icon/项目.png"));
    setWindowTitle("operation tip...");
    setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);  //设置右上角按钮
    //setAttribute(Qt::WA_DeleteOnClose);                                   //关闭窗口时将窗口释放掉即释放内存

    m_pIconLabel = new QLabel(this);
    m_pIconLabel->setObjectName(QLatin1String("iconLabel"));
    m_pTextLabel = new QLabel(this);
    m_pTextLabel->setObjectName(QLatin1String("textLabel"));
    m_pTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);  //label中的内容可用鼠标选择文本复制,链接激活
    m_pTextLabel->setOpenExternalLinks(true);                           //label中的内容若为链接,可直接点击打开
    m_pButtonBox = new QDialogButtonBox(this);
    m_pButtonBox->setObjectName(QLatin1String("buttonBox"));

    if (!title.isEmpty() || !text.isEmpty()) {
    
    
        setWindowTitle(title);
        m_pTextLabel->setFont(QFont(fontFamily, fontSize));
        m_pTextLabel->setText(text);
    }

    m_text = text;

    setupLayout();
}

void TipDialog::setupLayout() {
    
    
    QHBoxLayout* HLay = new QHBoxLayout;
    HLay->addWidget(m_pIconLabel, 1, Qt::AlignVCenter | Qt::AlignRight);
    HLay->addWidget(m_pTextLabel, 5, Qt::AlignCenter);
    QVBoxLayout* VLay = new QVBoxLayout;
    VLay->addLayout(HLay);
    VLay->addWidget(m_pButtonBox);
    setLayout(VLay);
}

QPixmap TipDialog::standardIcon(TipDialog::TipIcon icon) {
    
    
    QPixmap pixmap;
    switch (icon) {
    
    
        case TipDialog::Information:
            pixmap.load(":/new/prefix1/Image/Information.png");
            break;
        case TipDialog::Question:
            pixmap.load(":/new/prefix1/Image/Question.png");
            break;
        case TipDialog::Success:
            pixmap.load(":/new/prefix1/Image/Success.png");
            break;
        case TipDialog::Warning:
            pixmap.load(":/new/prefix1/Image/Warning.png");
            break;
        case TipDialog::Critical:
            pixmap.load(":/new/prefix1/Image/Critical.png");
            break;
        default:
            break;
    }
    if (!pixmap.isNull())
        return pixmap;
    return QPixmap();
}

void TipDialog::setIcon(TipDialog::TipIcon icon) {
    
    
    m_pIconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    m_pIconLabel->setPixmap(standardIcon(icon));
}

void TipDialog::createButton(StandardButton button) {
    
    
    switch (button) {
    
    
        case TipDialog::Ok:
            addButton(button, QDialogButtonBox::AcceptRole);
            break;
        case TipDialog::Save:
            addButton(button, QDialogButtonBox::AcceptRole);
            break;
        case TipDialog::Yes:
            addButton(button, QDialogButtonBox::YesRole);
            break;
        case TipDialog::No:
            addButton(button, QDialogButtonBox::NoRole);
            break;
        case TipDialog::Cancel:
            addButton(button, QDialogButtonBox::RejectRole);
            break;
        default:
            break;
    }
}
void TipDialog::createStandardButtons(StandardButtons buttons) {
    
    
    //TipDialog::StandardButtons 与 QDialogButtonBox::StandardButtons 的枚举是一样的
    uint i = QDialogButtonBox::FirstButton;  //枚举值为非负整数,使用uint
    while (i <= QDialogButtonBox::LastButton) {
    
    
        if (i & buttons) {
    
    
            createButton(StandardButton(i));
        }
        i = i << 1;
    }
}

void TipDialog::setStandardButtons(StandardButtons buttons) {
    
    
    if (buttons != NoButton)
        createStandardButtons(buttons);
}

//QString TipDialog::standardTitle(TipDialog::TipIcon icon) {
    
    
//    QString title;
//    switch (icon) {
    
    
//        case TipDialog::Information:
//            title = "Information";
//            break;
//        case TipDialog::Question:
//            title = "Question";
//            break;
//        case TipDialog::Success:
//            title = "Success";
//            break;
//        case TipDialog::Warning:
//            title = "Warning";
//            break;
//        case TipDialog::Critical:
//            title = "Critical";
//            break;
//        default:
//            break;
//    }
//    if (!title.isEmpty())
//        return title;
//    return QString();
//}

QString TipDialog::getEnumKey(StandardButton button) {
    
    
    QMetaEnum metaEnum = QMetaEnum::fromType<StandardButton>();  //获取QMetaEnum对象,为了获取枚举值
    QString str = metaEnum.valueToKey(button);
    if (!str.isEmpty())
        return str;
    return QString();
}

void TipDialog::addButton(TipDialog::StandardButton button, QDialogButtonBox::ButtonRole buttonRole) {
    
    
    QString buttonText = getEnumKey(button);
    QPushButton* pushButton = m_pButtonBox->addButton(buttonText, buttonRole);
    //    if (pushButton->text() == QLatin1String("Yes") && m_text.contains("save", Qt::CaseSensitive)) {
    
    
    //        pushButton->setText("Save");
    //    } else if (pushButton->text() == QLatin1String("Yes") && m_text.contains("delete", Qt::CaseSensitive)) {
    
    
    //        pushButton->setText("Delete");
    //    }
    //    m_pButtonList.append(pushButton);
    connect(pushButton, &QPushButton::clicked, this, &TipDialog::close);
}

main.cpp

#include <QApplication>
#include <QMessageBox>

#include "tipdialog.h"

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

    //TipDialog aa(TipDialog::Question, "Question", "The current project has been modified.\nDo you want to save it?", TipDialog::Yes | TipDialog::No);
    //TipDialog aa(TipDialog::Success, "Success", "Project saved successfully!", TipDialog::Ok);
    //TipDialog aa(TipDialog::Warning, "Warning", "Parsed file not found! Please reconfigure!", TipDialog::Ok);
    TipDialog aa(TipDialog::Critical, "Critical", "Loading failed.Please tryagain!", TipDialog::Ok);

    aa.show();

    return a.exec();
}

注意:You need to manually add icon pictures in the Resources file.

5. Improvement of v1.0: Reimplement the pop-up window interface (with complete code) (v2.0)

Renderings:
insert image description here

Many interfaces have been added, and the button added in the previous v1.0 version was implemented by itself. In fact, it is not necessary. It is more convenient to use the interface of QDialogButtonBox directly.
MyMessageBox.h

#ifndef MyMessageBox_H
#define MyMessageBox_H

#include <QApplication>
#include <QDebug>
#include <QDialog>
#include <QDialogButtonBox>
#include <QFile>
#include <QHBoxLayout>
#include <QIcon>
#include <QLabel>
#include <QMetaEnum>
#include <QPixmap>
#include <QPushButton>
#include <QVBoxLayout>

class MyMessageBox : public QDialog {
    
    
    Q_OBJECT

public:
    enum Icon {
    
    
        NoIcon = 0,
        Information = 1,
        Question = 2,
        Success = 3,
        Warning = 4,
        Critical = 5
    };
    Q_ENUM(Icon)  //使用Q_ENUM注册枚举

    enum StandardButton {
    
    
        //尽量保持与 QDialogButtonBox::StandardButton 一致,在创建按钮时可能会用到 & 运算
        NoButton = 0x00000000,
        Ok = 0x00000400,
        Save = 0x00000800,
        SaveAll = 0x00001000,
        Open = 0x00002000,
        Yes = 0x00004000,
        YesToAll = 0x00008000,
        No = 0x00010000,
        NoToAll = 0x00020000,
        Abort = 0x00040000,
        Retry = 0x00080000,
        Ignore = 0x00100000,
        Close = 0x00200000,
        Cancel = 0x00400000,
        Discard = 0x00800000,
        Help = 0x01000000,
        Apply = 0x02000000,
        Reset = 0x04000000,
        RestoreDefaults = 0x08000000,

        FirstButton = Ok,
        LastButton = RestoreDefaults
    };
    Q_ENUM(StandardButton)
    Q_DECLARE_FLAGS(StandardButtons, StandardButton)
    Q_FLAG(StandardButtons)

    enum ButtonRole {
    
    
        //保持与 QDialogButtonBox::ButtonRole 一致
        InvalidRole = -1,
        AcceptRole,
        RejectRole,
        DestructiveRole,
        ActionRole,
        HelpRole,
        YesRole,
        NoRole,
        ResetRole,
        ApplyRole,

        NRoles
    };

    explicit MyMessageBox(QWidget* parent = nullptr);
    MyMessageBox(Icon icon, const QString& title, const QString& text, StandardButtons buttons,
                 QWidget* parent = nullptr);  //构造函数有默认值的要放后面
    ~MyMessageBox();

    void setTitle(const QString& title);

    Icon icon() const;
    void setIcon(Icon icon);

    QPixmap iconPixmap() const;
    void setIconPixmap(const QPixmap& pixmap);

    QString text() const;
    void setText(const QString& text);

    StandardButtons standardButtons() const;
    void setStandardButtons(StandardButtons buttons);
    StandardButton standardButton(QAbstractButton* button) const;
    QAbstractButton* button(StandardButton which) const;

    ButtonRole buttonRole(QAbstractButton* button) const;

    QAbstractButton* clickedButton() const;

    static StandardButton information(QWidget* parent, const QString& text, QString title = "Message", StandardButtons buttons = Ok);
    static StandardButton question(QWidget* parent, const QString& text, QString title = "Message", StandardButtons buttons = StandardButtons(Yes | No));
    static StandardButton success(QWidget* parent, const QString& text, QString title = "Message", StandardButtons buttons = Ok);
    static StandardButton warning(QWidget* parent, const QString& text, QString title = "Message", StandardButtons buttons = Ok);
    static StandardButton critical(QWidget* parent, const QString& text, QString title = "Message", StandardButtons buttons = Ok);

    static StandardButton showMessageBox(QWidget* parent, Icon icon, const QString& text, QString title, StandardButtons buttons);
    static void setMessageBoxGeometry(QWidget* parent, MyMessageBox& msgBox);

private slots:
    void slotPushButtonClicked(QAbstractButton* button);

private:
    void init();
    void setupLayout();
    QPixmap standardIcon(Icon icon);
    void setClickedButton(QAbstractButton* button);
    void finalize(QAbstractButton* button);
    int dialogCodeForButton(QAbstractButton* button) const;
    void setPushButtonProperty(QList<QAbstractButton*> buttonList);

private:
    QLabel* m_pIconLabel;
    MyMessageBox::Icon m_icon;
    QLabel* m_pTextLabel;
    QLabel* m_pLineLabel;
    QDialogButtonBox* m_pButtonBox;
    QAbstractButton* m_pClickedButton;
};

//在全局任意地方使用"|"操作符计算自定义的枚举量,需要使用Q_DECLARE_OPERATORS_FOR_FLAGS宏
Q_DECLARE_OPERATORS_FOR_FLAGS(MyMessageBox::StandardButtons)

#endif  // MyMessageBox_H

};

//在全局任意地方使用"|"操作符计算自定义的枚举量,需要使用Q_DECLARE_OPERATORS_FOR_FLAGS宏
Q_DECLARE_OPERATORS_FOR_FLAGS(MyMessageBox::StandardButtons)

#endif  // MyMessageBox_H

MyMessageBox.cpp

#include "MyMessageBox.h"

#define MESSAGEWIDTH 450  //界面的大小
#define MESSAGEHEIGHT 225

#define TEXTFONTFAMILY "微软雅黑"  //text的字体样式和大小
#define TEXTFONTSIZE 12

#define BUTTONFONTFAMILY "微软雅黑"  //按钮的字体样式和大小
#define BUTTONFONTSIZE 10

#define BUTTONWIDTH 100  //按钮的大小
#define BUTTONHEIGHT 30

MyMessageBox::MyMessageBox(QWidget* parent) :
    QDialog(parent) {
    
    
    init();
}

MyMessageBox::MyMessageBox(Icon icon, const QString& title, const QString& text, StandardButtons buttons, QWidget* parent) :
    QDialog(parent) {
    
    
    init();
    setTitle(title);
    setIcon(icon);
    setText(text);
    if (buttons != NoButton)
        setStandardButtons(buttons);
}

MyMessageBox::~MyMessageBox() {
    
    }

void MyMessageBox::setTitle(const QString& title) {
    
    
    setWindowTitle(title);
}

MyMessageBox::Icon MyMessageBox::icon() const {
    
    
    return m_icon;
}

void MyMessageBox::setIcon(MyMessageBox::Icon icon) {
    
    
    setIconPixmap(standardIcon(icon));
    m_icon = icon;
}

QPixmap MyMessageBox::iconPixmap() const {
    
    
    return *m_pIconLabel->pixmap();
}

void MyMessageBox::setIconPixmap(const QPixmap& pixmap) {
    
    
    //    m_pIconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    m_pIconLabel->setPixmap(pixmap);
    m_icon = NoIcon;
}

QString MyMessageBox::text() const {
    
    
    return m_pTextLabel->text();
}

void MyMessageBox::setText(const QString& text) {
    
    
    m_pTextLabel->setFont(QFont(TEXTFONTFAMILY, TEXTFONTSIZE));
    m_pTextLabel->setText(text);
}

MyMessageBox::StandardButtons MyMessageBox::standardButtons() const {
    
    
    QDialogButtonBox::StandardButtons standardButtons = m_pButtonBox->standardButtons();
    return MyMessageBox::StandardButtons(int(standardButtons));  //不同类型的枚举转换
}

void MyMessageBox::setStandardButtons(StandardButtons buttons) {
    
    
    QDialogButtonBox::StandardButtons standardButtons = QDialogButtonBox::StandardButtons(int(buttons));
    m_pButtonBox->setStandardButtons(standardButtons);
    //    m_pButtonBox->setStandardButtons(QDialogButtonBox::StandardButtons(int(buttons)));  //上面两句归为一句
    setPushButtonProperty(m_pButtonBox->buttons());
}

MyMessageBox::StandardButton MyMessageBox::standardButton(QAbstractButton* button) const {
    
    
    QDialogButtonBox::StandardButton standardButton = m_pButtonBox->standardButton(button);
    return (MyMessageBox::StandardButton)standardButton;  //转化为当前类的StandardButton类型
}

QAbstractButton* MyMessageBox::button(MyMessageBox::StandardButton which) const {
    
    
    QDialogButtonBox::StandardButton standardButton = QDialogButtonBox::StandardButton(which);
    return m_pButtonBox->button(standardButton);
}

MyMessageBox::ButtonRole MyMessageBox::buttonRole(QAbstractButton* button) const {
    
    
    QDialogButtonBox::ButtonRole buttonRole = m_pButtonBox->buttonRole(button);
    return MyMessageBox::ButtonRole(buttonRole);
}

QAbstractButton* MyMessageBox::clickedButton() const {
    
    
    return m_pClickedButton;
}

MyMessageBox::StandardButton MyMessageBox::information(QWidget* parent, const QString& text, QString title, StandardButtons buttons) {
    
    
    return showMessageBox(parent, Information, text, title, buttons);
}

MyMessageBox::StandardButton MyMessageBox::question(QWidget* parent, const QString& text, QString title, StandardButtons buttons) {
    
    
    return showMessageBox(parent, Question, text, title, buttons);
}

MyMessageBox::StandardButton MyMessageBox::success(QWidget* parent, const QString& text, QString title, StandardButtons buttons) {
    
    
    return showMessageBox(parent, Success, text, title, buttons);
}

MyMessageBox::StandardButton MyMessageBox::warning(QWidget* parent, const QString& text, QString title, StandardButtons buttons) {
    
    
    return showMessageBox(parent, Warning, text, title, buttons);
}

MyMessageBox::StandardButton MyMessageBox::critical(QWidget* parent, const QString& text, QString title, StandardButtons buttons) {
    
    
    return showMessageBox(parent, Critical, text, title, buttons);
}

MyMessageBox::StandardButton MyMessageBox::showMessageBox(QWidget* parent, Icon icon, const QString& text, QString title, StandardButtons buttons) {
    
    
    MyMessageBox msgBox(icon, title, text, buttons, parent);
    //静态函数只能调用静态函数,setMessageBoxGeometry()必须声明为静态函数
    setMessageBoxGeometry(parent, msgBox);
    if (msgBox.exec() == -1)
        return MyMessageBox::Cancel;
    return msgBox.standardButton(msgBox.clickedButton());
}

void MyMessageBox::setMessageBoxGeometry(QWidget* parent, MyMessageBox& msgBox) {
    
    
    QRect rect = parent->geometry();
    int x = rect.x() + (rect.width() - msgBox.geometry().width()) / 2;
    int y = rect.y() + (rect.height() - msgBox.geometry().height()) / 2;
    msgBox.setGeometry(x, y, msgBox.geometry().width(), msgBox.geometry().height());
    msgBox.move(x, y);
}

void MyMessageBox::slotPushButtonClicked(QAbstractButton* button) {
    
    
    setClickedButton(button);
    finalize(button);
    close();
}

void MyMessageBox::init() {
    
    
    resize(QSize(MESSAGEWIDTH, MESSAGEHEIGHT));
    setWindowIcon(QIcon(":/new/prefix1/Icon/project.ico"));
    setWindowTitle("Message");
    //对于继承的QDialog,其Flags必须包含Qt::Dialog,不能自定义CustomizeWindowHint
    //否则在构造中指定了parent之后会出现:标题栏消失以及窗口不在正中间
    //setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);  //设置右上角按钮
    Qt::WindowFlags flags = Qt::Dialog;
    flags |= Qt::WindowCloseButtonHint;
    setWindowFlags(flags);  //去掉标题栏右上角的问号
    //setAttribute(Qt::WA_DeleteOnClose);                                   //关闭窗口时将窗口释放掉即释放内存

    m_pIconLabel = new QLabel(this);
    m_pIconLabel->setObjectName(QLatin1String("iconLabel"));
    m_pIconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);  //图标不可拉伸和缩小,固定大小
    m_pTextLabel = new QLabel(this);
    m_pTextLabel->setObjectName(QLatin1String("textLabel"));
    m_pTextLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);  //label中的内容可用鼠标选择文本复制,链接激活
    m_pTextLabel->setOpenExternalLinks(true);                           //label中的内容若为链接,可直接点击打开
    m_pLineLabel = new QLabel(this);
    m_pLineLabel->setFrameStyle(QFrame::HLine | QFrame::Sunken);  //Sunken:凹陷,Raised:凸起
    m_pButtonBox = new QDialogButtonBox(this);                    //默认按钮为水平布局Qt::Horizontal
    m_pButtonBox->setObjectName(QLatin1String("buttonBox"));
    connect(m_pButtonBox, &QDialogButtonBox::clicked, this, &MyMessageBox::slotPushButtonClicked);

    setupLayout();

    setModal(true);

    setStyleSheet("QDialog{background-color:rgb(255 , 255 , 255);}"
                  "QPushButton{background-color:#E0E0E0;border: 1px solid #A6A6A6;border-radius:5px;}"
                  "QPushButton:hover{color:white;background-color:#4188FF;border-radius:5px;border: 0px}"
                  //                  "QPushButton{background-color:#E0E0E0;border: 1px solid #C2C2C2;border-radius:5px;}"
                  //                  "QPushButton:hover{background-color:#C2C2C2;border-radius:5px;border: 0px}"
                  "QPushButton:pressed{padding-left:3px;padding-top:3px;}");
}

void MyMessageBox::setupLayout() {
    
    
    QHBoxLayout* HLay = new QHBoxLayout;
    HLay->addWidget(m_pIconLabel, 1, Qt::AlignVCenter | Qt::AlignRight);
    HLay->addWidget(m_pTextLabel, 5, Qt::AlignCenter);
    QHBoxLayout* HLay1 = new QHBoxLayout;
    HLay1->addWidget(m_pButtonBox, Qt::AlignRight);
    //    QMargins margin;
    //    margin.setRight(9);
    //    HLay1->setContentsMargins(margin);  //调节按钮不要太靠右
    QVBoxLayout* VLay = new QVBoxLayout;
    VLay->addLayout(HLay, 10);
    VLay->addWidget(m_pLineLabel, 1);
    VLay->addLayout(HLay1, 4);
    VLay->setSpacing(0);

    setLayout(VLay);
}

QPixmap MyMessageBox::standardIcon(Icon icon) {
    
    
    QPixmap pixmap;
    switch (icon) {
    
    
        case MyMessageBox::Information:
            pixmap.load(":/new/prefix1/Image/Information.png");
            break;
        case MyMessageBox::Question:
            pixmap.load(":/new/prefix1/Image/Question.png");
            break;
        case MyMessageBox::Success:
            pixmap.load(":/new/prefix1/Image/Success.png");
            break;
        case MyMessageBox::Warning:
            pixmap.load(":/new/prefix1/Image/Warning.png");
            break;
        case MyMessageBox::Critical:
            pixmap.load(":/new/prefix1/Image/Critical.png");
            break;
        default:
            break;
    }
    if (!pixmap.isNull())
        return pixmap;
    return QPixmap();
}

void MyMessageBox::setClickedButton(QAbstractButton* button) {
    
    
    m_pClickedButton = button;
}

void MyMessageBox::finalize(QAbstractButton* button) {
    
    
    int dialogCode = dialogCodeForButton(button);
    if (dialogCode == QDialog::Accepted) {
    
    
        emit accepted();
    } else if (dialogCode == QDialog::Rejected) {
    
    
        emit rejected();
    }
}

int MyMessageBox::dialogCodeForButton(QAbstractButton* button) const {
    
    
    switch (buttonRole(button)) {
    
    
        case MyMessageBox::AcceptRole:
        case MyMessageBox::YesRole:
            return QDialog::Accepted;
        case MyMessageBox::RejectRole:
        case MyMessageBox::NoRole:
            return QDialog::Rejected;
        default:
            return -1;
    }
}

void MyMessageBox::setPushButtonProperty(QList<QAbstractButton*> buttonList) {
    
    
    for (int i = 0; i < buttonList.size(); i++) {
    
    
        QPushButton* pushButton = qobject_cast<QPushButton*>(buttonList.at(i));
        pushButton->setMinimumSize(BUTTONWIDTH, BUTTONHEIGHT);
        pushButton->setFont(QFont(BUTTONFONTFAMILY, BUTTONFONTSIZE));
    }
}

注意:You need to manually add icon pictures in the Resources file.

Guess you like

Origin blog.csdn.net/WL0616/article/details/131393932