自定义Qt对话框

时间:2022-07-22
本文章向大家介绍自定义Qt对话框,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

今天就简单简单写个自定义对话框分享给大家。

演示

上代码!

  1. 自定义对话框的使用:
#include <QApplication>
#include <QDebug>

#include "Dialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    
    Dialog dialog;
    dialog.resize(380, 240);
    dialog.setText(QStringLiteral("Hello world! @Qt君"));

    if (dialog.exec() == QDialog::Accepted) {
        qDebug() << "Click the 'Yes' button.";
    }
    else {
        qDebug() << "Click the 'No' or 'Close' button.";
    }

    return a.exec();
}
  1. 头文件
#include <QDialog>

class QLabel;
class QPushButton;

class Dialog : public QDialog
{
    Q_OBJECT
public:
    Dialog(QWidget *parent = nullptr);

    /* 设置对话框内容文本 */
    void setText(const QString &text);

protected:
    /**
     * 1.绘图事件
     * 2.绘制圆角矩形对话框(背景)
     */
    void paintEvent(QPaintEvent *);

    /**
     * 1.鼠标按下事件
     * 2.记录鼠标按下的坐标位置,用于移动窗口
     */
    void mousePressEvent(QMouseEvent *event);

    /**
     * 1.鼠标移动事件
     * 2.计算移动窗口
     */
    void mouseMoveEvent(QMouseEvent *event);

private:
    QLabel      *m_contentText;
    QPushButton *m_okButton;
    QPushButton *m_cancelButton;
    QPushButton *m_closeButton;

    /* 记录鼠标按下的坐标位置 */
    QPoint       m_startPoint;
};
  1. 使用XPM字符图像加载右上角关闭图标。
/**
 * 1.XPM字符图像,可用于QPixmap加载为图像。
 * 2.关于更多:
 *    2.1 Qt君公众号文章:《Qt加载XPM图像》
 *    2.2 png转xpm格式工具: https://cn.office-converter.com/PNG-to-XPM
 */
static const char *s_close_xpm[] = {
    {"32 32 11 1"},
    {". c None"},
    {"d c #000000"},
    {"b c #000000"},
    {"e c #000000"},
    {"c c #000000"},
    {"f c #000000"},
    {"g c #000000"},
    {"# c #000000"},
    {"h c #000000"},
    {"i c #000000"},
    {"a c #000000"},
    {"................................"},
    {"................................"},
    {"................................"},
    {"................................"},
    {"................................"},
    {"................................"},
    {"................................"},
    {".......aa..............aa......."},
    {".......aaa............aaa......."},
    {"........aaa..........aaa........"},
    {".........aaa........aaa........."},
    {"..........aaa......aaa.........."},
    {"...........aaa....aaa..........."},
    {"............aaa..aaa............"},
    {".............aaaaaa............."},
    {"..............aaaa.............."},
    {"..............aaaa.............."},
    {".............aaaaaa............."},
    {"............aaa..aaa............"},
    {"...........aaa....aaa..........."},
    {"..........aaa......aaa.........."},
    {".........aaa........aaa........."},
    {"........aaa..........aaa........"},
    {".......aaa............aaa......."},
    {".......aa..............aa......."},
    {"................................"},
    {"................................"},
    {"................................"},
    {"................................"},
    {"................................"},
    {"................................"},
    {"................................"}
};
  1. 构造函数初始化按钮,内容文本布局管理。
Dialog::Dialog(QWidget *parent) :
    QDialog(parent)
{
    /* 设置无标题栏和无边框窗口 */
    this->setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
    this->setAttribute(Qt::WA_TranslucentBackground);
    this->setAutoFillBackground(true);

    /* 设置背景颜色 */
    QPalette palette = this->palette();
    palette.setColor(QPalette::Background, "white");
    this->setPalette(palette);

    /* 设置对话框样式表 */
    this->setStyleSheet(R"(
        QDialog {
            border-radius: 5px;
            border-width: 2px;
        }
        )");

    /* 创建对话框内容文本 */
    m_contentText = new QLabel(this);
    QFont font = m_contentText->font();
    font.setPixelSize(18);
    m_contentText->setFont(font);

    /* 创建Yes(ok)按钮并通过样式表美化 */
    m_okButton = new QPushButton("Yes", this);
    m_okButton->setFixedSize(80, 30);
    m_okButton->setStyleSheet(QString(R"(
        QPushButton {
            border-radius: 5px;
            border-width: 1px;
            border-color: #1ABC9B;
            border-style: solid;
            margin: 0px;
            padding: 0px;
            font-size: %1px;
            color: black;
            background: white;
            outline: none;
        }
        QPushButton:hover {
            outline: none;
            background: #1ABC9B;
            color: white;
            text-decoration:underline;
        }
        )").arg(15));

    /* 创建No(cancel)按钮并通过样式表美化 */
    m_cancelButton = new QPushButton("No", this);
    m_cancelButton->setFixedSize(80, 30);
    m_cancelButton->setStyleSheet(QString(R"(
        QPushButton {
            border-radius: 5px;
            border-width: 1px;
            border-color: #1ABC9B;
            border-style: solid;
            margin: 0px;
            padding: 0px;
            font-size: %1px;
            color: black;
            background: white;
            outline: none;
        }
        QPushButton:hover{
            outline: none;
            background: #1ABC9B;
            color: white;
            text-decoration:underline;
        }
        )").arg(15));

    /* 加载关闭按钮的图标 */
    QPixmap closePixmap(s_close_xpm);
    QIcon closeIcon(closePixmap);

    /* 创建右上角的关闭按钮并通过样式表美化 */
    m_closeButton = new QPushButton(closeIcon, "");
    m_closeButton->setIconSize(QSize(24, 24));
    m_closeButton->setStyleSheet(QString(R"(
        QPushButton {
            border-radius: 5px;
            border-width: 1px;
            border-color: #1ABC9B;
            border-style: solid;
            margin: 0px;
            padding: 0px;
            font-size: %1px;
            color: black;
            background: white;
            outline: none;
        }
        QPushButton:hover{
            outline: none;
            background: #1ABC9B;
            color: white;
            text-decoration:underline;
        }
        )").arg(15));

    /* 布局管理[start] */
    /* 布局关闭按钮与内容栏 */
    QVBoxLayout *vLayout = new QVBoxLayout;
    vLayout->addWidget(m_closeButton, 0, Qt::AlignRight);
    vLayout->addWidget(m_contentText, 0, Qt::AlignHCenter);

    /* 布局Yes和No按钮 */
    QHBoxLayout *hLayout = new QHBoxLayout;
    hLayout->addStretch();
    hLayout->addWidget(m_okButton);
    hLayout->addWidget(m_cancelButton);

    vLayout->addLayout(hLayout);

    setLayout(vLayout);
    /* 布局管理[end] */

    /* 绑定按钮的事件通知 */
    /* 注意:accept和close被调用后自动关闭对话框 */
    connect(m_okButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
    connect(m_cancelButton, SIGNAL(clicked(bool)), this, SLOT(close()));
    connect(m_closeButton, SIGNAL(clicked(bool)), this, SLOT(close()));
}
  1. 设置对话框内容文本。
void Dialog::setText(const QString &text)
{
    m_contentText->setText(text);
}
  1. 绘制圆角矩形对话框(背景)。
void Dialog::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    QPen pen(QColor("black"));
    pen.setWidth(1);
    painter.setPen(pen);
    painter.setBrush(QBrush(QColor("white")));
    painter.drawRoundedRect(0, 0, width(), height(), 5, 5);
}
  1. 鼠标按下事件,记录鼠标按下的坐标位置,用于移动窗口实现。
void Dialog::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        /* 记录鼠标按下的坐标位置,用于移动窗口实现 */
        m_startPoint = frameGeometry().topLeft() - event->globalPos();
    }
}
  1. 鼠标移动事件,用于移动对话框窗口。
void Dialog::mouseMoveEvent(QMouseEvent *event)
{
    /* 移动窗口 */
    this->move(event->globalPos() + m_startPoint);
}