自定义QMessageBox

最近做的项目需要用到消息对话框,但是qt默认的QMessageBox有点难看,即使使用了QSS来美化,也显得有点难看。因此决定自己实现一个MessageBox。

思路

消息对话框的功能一般都比较简单,主要是弹出一个对话框聊表现当前消息的状态。主要的功能要求有必须是modal的。界面上面主要显示一个主要的文字内容和2个或一个button按钮。 那么我们就可以继承QDialog来实现,去掉QDialog的边框这些,然后自己添加鼠标拖动对话框的时间就可以了。

代码实现

    explicit MessageBox(QWidget *parent = 0,
                        Icon icon = Messsage,
                        const QString &title = "",
                        const QString &text = "",
                        QMessageBox::StandardButtons  = QMessageBox::Ok,
                        QMessageBox::StandardButton defaultButton = QMessageBox::Ok);

MessageBox::MessageBox(QWidget *parent,
                       Icon icon,
                       const QString &title,
                       const QString &text,
                       QMessageBox::StandardButtons standButtons,
                       QMessageBox::StandardButton defaultButton)
    :QDialog(parent)
    ,m_lIconTitle(new QLabel(this))
    ,m_lTitle(new QLabel(this))
    ,m_lIconMain(new QLabel(this))
    ,m_lText(new QLabel(this))
    ,m_layout(new QVBoxLayout())
    ,m_pButtonBox(new QDialogButtonBox(this))
    ,m_mouserPressed(false)
{
    setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
    setFixedSize(QSize(606, 286));

    m_layout->setContentsMargins(20, 20, 20, 20);

    QHBoxLayout *titleLayout = new QHBoxLayout();
    titleLayout->setContentsMargins(8, 0, 0, 0);
    titleLayout->setSpacing(20);
    titleLayout->addWidget(m_lIconTitle);
    titleLayout->addWidget(m_lTitle);
    titleLayout->addStretch(1);
    m_lIconTitle->setFixedHeight(20);
    m_lTitle->setFixedHeight(20);
    m_layout->addLayout(titleLayout);

    QGroupBox *groupBox = new QGroupBox(this);
    groupBox->setFixedHeight(200);
    m_layout->addWidget(groupBox);
    QVBoxLayout *vBoxLayout = new QVBoxLayout();
    groupBox->setLayout(vBoxLayout);
    vBoxLayout->setContentsMargins(20, 20, 20, 20);
    vBoxLayout->setSpacing(20);

    QHBoxLayout *hLayout  = new QHBoxLayout();
    m_lIconMain->setFixedSize(QSize(90, 90));
    m_lText->setFixedHeight(90);
    hLayout->addWidget(m_lIconMain);
    hLayout->addWidget(m_lText);
    hLayout->addStretch(1);
    hLayout->setSpacing(10);
    vBoxLayout->addLayout(hLayout);

    QHBoxLayout *hLayoutButtons  = new QHBoxLayout();
    hLayoutButtons->addStretch(1);
    hLayoutButtons->addWidget(m_pButtonBox);
    vBoxLayout->addLayout(hLayoutButtons);
    m_pButtonBox->setFixedHeight(55);
    m_layout->addWidget(groupBox);
    setLayout(m_layout);

    m_pButtonBox->setStandardButtons(QDialogButtonBox::StandardButtons((int)standButtons));
    setDefaultButton(defaultButton);

    QList<QAbstractButton *> buttons =  m_pButtonBox->buttons();
    for(int i = 0; i < buttons.size(); i++) {
        QDialogButtonBox::StandardButton button = m_pButtonBox->standardButton(buttons.at(i));
        QPushButton *pushButton = m_pButtonBox->button(button);
        pushButton->setFixedSize(QSize(135, 55));
        if(button == QDialogButtonBox::Ok || button == QDialogButtonBox::Yes) {
            pushButton->setText("确定");
        } else {
            pushButton->setText("取消");
        }
        pushButton->setStyleSheet("QPushButton{border:3px solid rgb(176,181,185);"
                                  "border-radius:5px;"
                                  "font-family:微软雅黑;font-size:18px;}");
    }

    IconHelper::Instance()->SetIcon(m_lIconTitle, QChar(0xf05a), 20);
    m_lTitle->setText(title);
    m_lTitle->setStyleSheet("font-family:微软雅黑;font-size:20px;");
    m_lText->setText(text);
    m_lText->setStyleSheet("font-family:微软雅黑;font-size:18px;");

    if(icon == Messsage) {
        m_lIconMain->setStyleSheet("border-image:url(:/message)");
    } else if(icon == Question) {
        m_lIconMain->setStyleSheet("border-image:url(:/question)");
    } else if(icon == Warning) {
        m_lIconMain->setStyleSheet("border-image:url(:/warning)");
    } else if(icon == Error) {
        m_lIconMain->setStyleSheet("border-image:url(:/error)");
    }

    this->setStyleSheet("QDialog{border:1px solid black;background-color:rgb(212,217,221);}");

    connect(m_pButtonBox, SIGNAL(clicked(QAbstractButton*)), this,
            SLOT(onButtonClicked(QAbstractButton*)));
}

在这个里面我们主要自定义了QDialog的布局和样式。同时我们通过QDialogButtonBox来保存点击的按钮。这样的好处是我们可以使用QMessageBox中的StandButton类型,来处理QDialog中的exec()的返回值。而不用自己处理或者是只能是用accept或reject。我们也可以遍历QDialogButtonBox来设置其中QPushButton的样式。
代码中我们把QDialogButtonBox的clicked信号连接到了一个onButtonClicked的槽上面。
在这槽中我们可以调用QDialog的done来处理返回值的问题。

void MessageBox::onButtonClicked(QAbstractButton *button)
{
    done(execReturnCode(button));
}

我们再来看看QDialog中的done的源代码:

void QDialog::done(int r)
{
    Q_D(QDialog);
    hide();
    setResult(r);

    d->close_helper(QWidgetPrivate::CloseNoEvent);
    d->resetModalitySetByOpen();

    emit finished(r);
    if (r == Accepted)
        emit accepted();
    else if (r == Rejected)
        emit rejected();
}

首先看官方的注释:关闭对话框并且设置返回值r,如果对话框是通过exec显示的,那么调用done0完成本地的时间循环,并且返回r值。
代码中不难看出,在done中,关闭了对画框设置了r值,其中r为exec的返回值。这样我们就可以有多个的返回值来判断结果。例如点击的是Yes,no,ok,cancle等button,返回的值不同,尽管实际上我们可能只会用到2个值,yes和ok的作用基本一致,但是多个放在这里也不见得有坏处。
源码地址:http://download.csdn.net/detail/lwei3600103/9614674

题外话:代码中用到了fontawesome,这个可以通过字体来设置图标,好处是不用ui,缺点是颜色单调。当我把这个widget做成dll在其它地方引用的时候,图标也显示不出来的,目前还没有找到原因。qt的源代码安装的时候就有,如果不想安装也可以去找些镜像站里面的qt的部分一般都会有源代码,例如http://mirrors.ustc.edu.cn/qtproject/archive/qt/5.7/5.7.0/submodules/。下面参考资料里面的2位大神应该算是qt中贡献很多的,好多问题都可以在这两个大神的博客里面找到答案。向大神致敬。

参考资料

QT开发的视频监管平台分享
Qt自定义界面QMessageBox

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值