1. 程式人生 > >【Qt】Qt之自定義介面(QMessageBox)【轉】

【Qt】Qt之自定義介面(QMessageBox)【轉】

簡述

通過前幾節的自定義窗體的學習,我們可以很容易的寫出一套屬於自己風格的介面框架,通用於各種窗體,比如:QWidget、QDialog、QMainWindow。

大多數窗體的實現都是採用控制元件堆積來完成的,只要思路清晰,再複雜的介面實現起來都遊刃有餘。下面我來列舉一個由QMessageBox擴充套件的提示框-根據其原始碼實現思路來實現!

效果

這裡寫圖片描述

這裡寫圖片描述 這裡寫圖片描述

這裡寫圖片描述 這裡寫圖片描述

自定義提示框

實現

message_box.h

#ifndef MESSAGE_BOX
#define
MESSAGE_BOX
#include <QMessageBox> #include <QDialogButtonBox> #include <QGridLayout> #include "custom_window.h" class QLabel; class MessageBox : public CustomWindow { Q_OBJECT public: explicit MessageBox(QWidget *parent = 0, const QString &title = tr("Tip"
), const QString &text = "", QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = QMessageBox::Ok); ~MessageBox(); QAbstractButton *clickedButton() const; QMessageBox::StandardButton standardButton(QAbstractButton *button) const
; // 設定預設按鈕 void setDefaultButton(QPushButton *button); void setDefaultButton(QMessageBox::StandardButton button); // 設定窗體標題 void setTitle(const QString &title); // 設定提示資訊 void setText(const QString &text); // 設定窗體圖示 void setIcon(const QString &icon); // 新增控制元件-替換提示資訊所在的QLabel void addWidget(QWidget *pWidget); protected: // 多語言翻譯 void changeEvent(QEvent *event); private slots: void onButtonClicked(QAbstractButton *button); private: void translateUI(); int execReturnCode(QAbstractButton *button); private: QLabel *m_pIconLabel; QLabel *m_pLabel; QGridLayout *m_pGridLayout; QDialogButtonBox *m_pButtonBox; QAbstractButton *m_pClickedButton; QAbstractButton *m_pDefaultButton; };

message_box.cpp

#include <QLabel>
#include <QPushButton>
#include <QMessageBox>
#include <QCheckBox>
#include <QHBoxLayout>
#include <QEvent>
#include <QApplication>
#include "message_box.h"

MessageBox::MessageBox(QWidget *parent, const QString &title, const QString &text,
                       QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
    : CustomWindow(parent)
{
    setWindowIcon(QIcon(":/Images/logo"));
    setWindowTitle(title);
    setMinimumSize(300, 130);
    setMinimizeVisible(false);
    setMaximizeVisible(false);
    setWidgetResizable(false);

    m_pButtonBox = new QDialogButtonBox(this);
    m_pButtonBox->setStandardButtons(QDialogButtonBox::StandardButtons(int(buttons)));
    setDefaultButton(defaultButton);

    QPushButton *pYesButton = m_pButtonBox->button(QDialogButtonBox::Yes);
    if (pYesButton != NULL)
    {
        pYesButton->setObjectName("blueButton");
        pYesButton->setStyle(QApplication::style());
    }

    m_pIconLabel = new QLabel(this);
    m_pLabel = new QLabel(this);

    QPixmap pixmap(":/Images/information");
    m_pIconLabel->setPixmap(pixmap);
    m_pIconLabel->setFixedSize(35, 35);
    m_pIconLabel->setScaledContents(true);

    m_pLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    m_pLabel->setObjectName("whiteLabel");
    m_pLabel->setOpenExternalLinks(true);
    m_pLabel->setText(text);

    m_pGridLayout = new QGridLayout();
    m_pGridLayout->addWidget(m_pIconLabel, 0, 0, 2, 1, Qt::AlignTop);
    m_pGridLayout->addWidget(m_pLabel, 0, 1, 2, 1);
    m_pGridLayout->addWidget(m_pButtonBox, m_pGridLayout->rowCount(), 0, 1, m_pGridLayout->columnCount());
    m_pGridLayout->setSizeConstraint(QLayout::SetNoConstraint);
    m_pGridLayout->setHorizontalSpacing(10);
    m_pGridLayout->setVerticalSpacing(10);
    m_pGridLayout->setContentsMargins(10, 10, 10, 10);
    m_pLayout->addLayout(m_pGridLayout);

    translateUI();

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

MessageBox::~MessageBox()
{

}

void MessageBox::changeEvent(QEvent *event)
{
    switch (event->type())
    {
    case QEvent::LanguageChange:
        translateUI();
        break;
    default:
        CustomWindow::changeEvent(event);
    }
}

void MessageBox::translateUI()
{
    QPushButton *pYesButton = m_pButtonBox->button(QDialogButtonBox::Yes);
    if (pYesButton != NULL)
        pYesButton->setText(tr("Yes"));

    QPushButton *pNoButton = m_pButtonBox->button(QDialogButtonBox::No);
    if (pNoButton != NULL)
        pNoButton->setText(tr("No"));

    QPushButton *pOkButton = m_pButtonBox->button(QDialogButtonBox::Ok);
    if (pOkButton != NULL)
        pOkButton->setText(tr("Ok"));

    QPushButton *pCancelButton = m_pButtonBox->button(QDialogButtonBox::Cancel);
    if (pCancelButton != NULL)
        pCancelButton->setText(tr("Cancel"));
}

QMessageBox::StandardButton MessageBox::standardButton(QAbstractButton *button) const
{
    return (QMessageBox::StandardButton)m_pButtonBox->standardButton(button);
}

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

int MessageBox::execReturnCode(QAbstractButton *button)
{
    int nResult = m_pButtonBox->standardButton(button);
    return nResult;
}

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

void MessageBox::setDefaultButton(QPushButton *button)
{
    if (!m_pButtonBox->buttons().contains(button))
        return;
    m_pDefaultButton = button;
    button->setDefault(true);
    button->setFocus();
}

void MessageBox::setDefaultButton(QMessageBox::StandardButton button)
{
    setDefaultButton(m_pButtonBox->button(QDialogButtonBox::StandardButton(button)));
}

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

void MessageBox::setText(const QString &text)
{
    m_pLabel->setText(text);
}

void MessageBox::setIcon(const QString &icon)
{
    m_pIconLabel->setPixmap(QPixmap(icon));
}

void MessageBox::addWidget(QWidget *pWidget)
{
    m_pLabel->hide();
    m_pGridLayout->addWidget(pWidget, 0, 1, 2, 1);
}

介面說明

  • CustomWindow

    主要對介面的無邊框可拖動進行了封裝

  • MessageBox

    整體介面佈局及事件處理參考了QMessageBox原始碼,介面包含:設定標題、提示資訊、預設按鈕及事件觸發等操作。

二次封裝

針對於各種提示框,我們可以再次進行封裝,將常用的提取出來,作為全域性函式來使用。

QMessageBox::StandardButton showInformation(QWidget *parent, const QString &title,
                                            const QString &text, QMessageBox::StandardButtons buttons,
                                            QMessageBox::StandardButton defaultButton)
{
    MessageBox msgBox(parent, title, text, buttons, defaultButton);
    msgBox.setIcon(":/Images/information");
    if (msgBox.exec() == -1)
        return QMessageBox::Cancel;
    return msgBox.standardButton(msgBox.clickedButton());
}

QMessageBox::StandardButton showError(QWidget *parent, const QString &title,
                                      const QString &text, QMessageBox::StandardButtons buttons,
                                      QMessageBox::StandardButton defaultButton)
{
    MessageBox msgBox(parent, title, text, buttons, defaultButton);
    msgBox.setIcon(":/Images/error");
    if (msgBox.exec() == -1)
        return QMessageBox::Cancel;
    return msgBox.standardButton(msgBox.clickedButton());
}

QMessageBox::StandardButton showSuccess(QWidget *parent, const QString &title,
                                        const QString &text, QMessageBox::StandardButtons buttons,
                                        QMessageBox::StandardButton defaultButton)
{
    MessageBox msgBox(parent, title, text, buttons, defaultButton);
    msgBox.setIcon(":/Images/success");
    if (msgBox.exec() == -1)
        return QMessageBox::Cancel;
    return msgBox.standardButton(msgBox.clickedButton());
}

QMessageBox::StandardButton showQuestion(QWidget *parent, const QString &title,
                                         const QString &text, QMessageBox::StandardButtons buttons,
                                         QMessageBox::StandardButton defaultButton)
{
    MessageBox msgBox(parent, title, text, buttons, defaultButton);
    msgBox.setIcon(":/Images/question");
    if (msgBox.exec() == -1)
        return QMessageBox::Cancel;
    return msgBox.standardButton(msgBox.clickedButton());
}

QMessageBox::StandardButton showWarning(QWidget *parent, const QString &title,
                                        const QString &text, QMessageBox::StandardButtons buttons,
                                        QMessageBox::StandardButton defaultButton)
{
    MessageBox msgBox(parent, title, text, buttons, defaultButton);
    msgBox.setIcon(":/images/warning");
    if (msgBox.exec() == -1)
        return QMessageBox::Cancel;
    return msgBox.standardButton(msgBox.clickedButton());
}

QMessageBox::StandardButton showCritical(QWidget *parent, const QString &title,
                                         const QString &text, QMessageBox::StandardButtons buttons,
                                         QMessageBox::StandardButton defaultButton)
{
    MessageBox msgBox(parent, title, text, buttons, defaultButton);
    msgBox.setIcon(":/Images/warning");
    if (msgBox.exec() == -1)
        return QMessageBox::Cancel;
    return msgBox.standardButton(msgBox.clickedButton());
}

QMessageBox::StandardButton showCheckBoxQuestion(QWidget *parent, const QString &title,
                                                 const QString &text, QMessageBox::StandardButtons buttons,
                                                 QMessageBox::StandardButton defaultButton)
{
    MessageBox msgBox(parent, title, text, buttons, defaultButton);
    msgBox.setIcon(":/Images/question");

    QCheckBox *pCheckBox = new QCheckBox(&msgBox);
    pCheckBox->setText(text);
    msgBox.addWidget(pCheckBox);
    if (msgBox.exec() == -1)
        return QMessageBox::Cancel;

    QMessageBox::StandardButton standardButton = msgBox.standardButton(msgBox.clickedButton());
    if (standardButton == QMessageBox::Yes)
    {
        return pCheckBox->isChecked() ? QMessageBox::Yes : QMessageBox::No;
    }
    return QMessageBox::Cancel;
}

使用方式

showInformation(this, QStringLiteral("提示"), QStringLiteral("這是一個普通的提示框-Information!"));
showQuestion(this, QStringLiteral("提示"), QStringLiteral("這是一個普通的提示框-Question!"));
showSuccess(this, QStringLiteral("提示"), QStringLiteral("這是一個普通的提示框-Success!"));
showError(this, QStringLiteral("提示"), QStringLiteral("這是一個普通的提示框-Error!"));

原始碼學習

其實Qt中有很多自帶的比較好的效果,裡面用了很好的實現方式,建議安裝的時候把原始碼download下來,隨時可以研究並學習。例如:D:\Qt\Qt5.5.1\5.5\Src\qtbase\src\widgets\dialogs下面包含了所有關於dialog的實現-QProgressDialog、QMessageBox、QFileDialog。。。

相關推薦

QtQt定義介面QMessageBox

簡述 通過前幾節的自定義窗體的學習,我們可以很容易的寫出一套屬於自己風格的介面框架,通用於各種窗體,比如:QWidget、QDialog、QMainWindow。 大多數窗體的實現都是採用控制元件堆積來完成的,只要思路清晰,再複雜的介面實現起來都遊刃有餘。下面我來列舉一個由QMessageBox擴充套

Qt 定義介面QMessageBox

簡述 通過前幾節的自定義窗體的學習,我們可以很容易的寫出一套屬於自己風格的介面框架,通用於各種窗體,比如:QWidget、QDialog、QMainWindow。 大多數窗體的實現都是採用控制元件堆積來完成的,只要思路清晰,再複雜的介面實現起來都遊刃有餘。下

QtQt定義介面實現無邊框、可移動

簡述 UI設計是指對軟體的人機互動、操作邏輯、介面美觀的整體設計。好的UI設計不僅是讓軟體變得有個性、有品位,還要讓軟體的操作變得舒適簡單、自由,充分體現軟體的定位和特點。 愛美之心人皆有之。其實軟體介面就像工業造型一樣,是產品的重要賣點。一個產品擁有美觀的介面會給人帶來舒適的視覺享受,拉近人與產品的

QtQt定義介面窗體縮放-跨平臺終極版

簡述 通過上一節內容,我們實現了窗體的縮放,功能很不錯,但是很遺憾-不支援跨平臺!如果對於多平臺來說,這是一個硬傷,所以,我們急需要一個能夠支援跨平臺的實現方案。 在網上看到過很多不同的實現方式,多多少少會存在一些問題-要麼融合度太高、要麼不能很好地進行移動、縮放。基於前人的分享與總結,最後,我花了很

QtQt定義介面右下角冒泡

簡述 網頁右下角上經常會出現一些提示性的資訊,桌面軟體中也比較常見,類似360新聞、QQ訊息提示一樣! 這種功能用動畫實現起來很簡單,這節我們暫時使用定時器來實現,後面章節會對動畫框架進行詳細講解。 下面我們來實現一個右下角冒泡的功能。 簡述 效果 實現原理 實現 效果

QtQt定義介面窗體縮放

簡述 通過前兩節內容,我們實現了自定義窗體的移動,以及自定義標題欄-用來顯示窗體的圖示、標題,以及控制窗體最小化、最大化、關閉。 在這之後,我們還缺少窗體的縮放-當滑鼠移動到窗體的邊框-左、上、右、下、左上角、左下角、右上角、右下角時候,滑鼠變為相應的樣式,並且窗體可以隨著滑鼠拖動而進行放大、縮小。

QtQt定義介面新增定義標題欄

簡述 通過上節內容,我們實現了自定義窗體的移動,但是我們缺少一個標題欄來顯示窗體的圖示、標題,以及控制窗體最小化、最大化、關閉的按鈕。 自定義標題欄後,所有的控制元件我們都可以定製,比如:在標題欄中新增換膚、設定按鈕以及其他控制元件。 簡述 效果 自定義標題欄 實現 介面說明

Qt 定義介面實現無邊框、可移動

簡述 UI設計是指對軟體的人機互動、操作邏輯、介面美觀的整體設計。好的UI設計不僅是讓軟體變得有個性、有品位,還要讓軟體的操作變得舒適簡單、自由,充分體現軟體的定位和特點。 愛美之心人皆有之。其實軟體介面就像工業造型一樣,是產品的重要賣點。一個產品擁有美觀的

Qt 定義介面右下角冒泡

簡述 網頁右下角上經常會出現一些提示性的資訊,桌面軟體中也比較常見,類似360新聞、QQ訊息提示一樣! 這種功能用動畫實現起來很簡單,這節我們暫時使用定時器來實現,後面章節會對動畫框架進行詳細講解。 下面我們來實現一個右下角冒泡的功能。 | 效果

Android進階定義View1實現可換行的TextView

         今天來一起學習一下最簡單的自定義view,自己動手寫一個MyTextView,當然不會像系統的TextView那麼複雜,只是實現一下TextView的簡單功能,包括分行顯示及自定義屬性的處理,主要目的是介紹自定義view的實現的基本思路和需要掌握的一些基礎知

Keras定義損失loss函式

在Keras中可以自定義損失函式,在自定義損失函式的過程中需要注意的一點是,損失函式的引數形式,這一點在Keras中是固定的,須如下形式: def my_loss(y_true, y_pred): # y_true: True labels. TensorFlow/The

h264解碼定義資訊SEI

     針對h264的解析網上優秀得博文、帖子一抓一大把,我就不在這班門弄斧了,僅僅提取一些自己在用的過程中比較有用的資訊,對於sei自定義資訊欄位,雖然網上資訊很多,但不容易精確搜到,就像我之前曾遇到一篇對我個人非常有用的文章,但後面一直找不到,現在再次看到,就把部分提取

js基礎定義屬性

aLi[i].onclick=function(){if(this.onOff){this.style.background='url(img/normal.png)';this.onOff=false}else{this.style.background='url(img/active.png)';this

js基礎定義屬性

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>無標題文件</title>

「免費開源」基於Vue和Quasar的前端SPA專案crudapi後臺管理系統實戰定義元件

# 基於Vue和Quasar的前端SPA專案實戰之序列號(四) ## 回顧 通過上一篇文章 [基於Vue和Quasar的前端SPA專案實戰之佈局選單(三)](https://www.cnblogs.com/crudapi/p/14536313.html)的介紹,我們已經完成了佈局選單,本文主要介紹序列號功能

QT-模型檢視定義委託

檢視委託(Delegate)簡介 由於模型負責組織資料,而檢視負責顯示資料,所以當用戶想修改顯示的資料時,就要通過檢視中的委託來完成 檢視委託類似於傳統的MVC設計模式裡的Controller(控制器)角色 Model(模型) - 負責資料組織 View(檢視)&n

QtQt程序間通訊QProcess

簡述 前幾節裡,分享了程序通訊的幾種方式:Windows訊息機制、Shared Memory(共享記憶體),本節講解下關於程序通訊的另外一種方式-QProcess。 簡述 命令列讀取 說明 實現 更多參考 命令列引數啟動 說明 程序A-帶參啟動

QtQt程序間通訊IPC

簡述 程序間通訊,就是在不同程序之間傳播或交換資訊。那麼不同程序之間存在著什麼雙方都可以訪問的介質呢?程序的使用者空間是互相獨立的,一般而言是不能互相訪問的,唯一的例外是共享記憶體區。但是,系統空間卻是“公共場所”,所以核心顯然可以提供這樣的條件。除此以外,那就是雙方都可以訪問的外設了。在這個意義上,兩

BLE-CC2640CC2640定義週期事件

本篇博文最後修改時間:2017年06月02日,00:29。 一、簡介 本文以SimpleBLEPeripheral工程為例,介紹如何使用系統提供的定時器執行一個自定義的週期事件。 二、實驗平臺 協議棧版本:ble_cc26xx_2_01_00_44423

Android定義裝置管理

需求:控制手機的攝像頭和錄音全部禁用~     這篇文章使用android提供的裝置管理器類DeviceAdminReceiver ,來實現禁用手機攝像頭的功能,還能夠改變密碼,鎖屏,重啟等功能,具體功能請去查API,如果我沒記錯的話有5千多行... ... 但是這篇文章主