1. 程式人生 > >Qt之自定義控制元件(開關按鈕)

Qt之自定義控制元件(開關按鈕)

簡述

接觸過iOS系統的童鞋們應該對開關按鈕很熟悉,在設定裡面經常遇到,切換時候的滑動效果比較帥氣。

通常說的開關按鈕,有兩個狀態:on、off。

下面,我們利用自定義控制元件來實現一個開關按鈕。

原理

重寫滑鼠按下事件(mousePressEvent)、釋放事件(mouseReleaseEvent),用於切換開關狀態。
重寫繪製事件(paintEvent),用於繪製開關效果。
使用QTimer,定時重新整理,讓開關切換時產生動畫效果。
其餘介面用於擴充套件,也可自己擴充。

原始碼

SwitchControl.h

#ifndef SWITCH_CONTROL
#define
SWITCH_CONTROL
#include <QWidget> #include <QTimer> class SwitchControl : public QWidget { Q_OBJECT public: explicit SwitchControl(QWidget *parent = 0); // 返回開關狀態 - 開啟:true 關閉:false bool isToggled() const; // 設定開關狀態 void setToggle(bool checked); // 設定背景顏色 void
setBackgroundColor(QColor color); // 設定選中顏色 void setCheckedColor(QColor color); // 設定不可用顏色 void setDisbaledColor(QColor color); protected: // 繪製開關 void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; // 滑鼠按下事件 void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; // 滑鼠釋放事件 - 切換開關狀態、發射toggled()訊號
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; // 大小改變事件 void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; // 預設大小 QSize sizeHint() const Q_DECL_OVERRIDE; QSize minimumSizeHint() const Q_DECL_OVERRIDE; signals: // 狀態改變時,發射訊號 void toggled(bool checked); private slots: // 狀態切換時,用於產生滑動效果 void onTimeout(); private: bool m_bChecked; // 是否選中 QColor m_background; // 背景顏色 QColor m_checkedColor; // 選中顏色 QColor m_disabledColor; // 不可用顏色 QColor m_thumbColor; // 拇指顏色 qreal m_radius; // 圓角 qreal m_nX; // x點座標 qreal m_nY; // y點座標 qint16 m_nHeight; // 高度 qint16 m_nMargin; // 外邊距 QTimer m_timer; // 定時器 }; #endif // SWITCH_CONTROL

SwitchControl.cpp

#include <QPainter>
#include <QMouseEvent>
#include "SwitchControl.h"

SwitchControl::SwitchControl(QWidget *parent)
    : QWidget(parent),
      m_nHeight(16),
      m_bChecked(false),
      m_radius(8.0),
      m_nMargin(3),
      m_checkedColor(0, 150, 136),
      m_thumbColor(Qt::white),
      m_disabledColor(190, 190, 190),
      m_background(Qt::black)
{
    // 滑鼠滑過游標形狀 - 手型
    setCursor(Qt::PointingHandCursor);

    // 連線訊號槽
    connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}

// 繪製開關
void SwitchControl::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QPainter painter(this);
    painter.setPen(Qt::NoPen);
    painter.setRenderHint(QPainter::Antialiasing);

    QPainterPath path;
    QColor background;
    QColor thumbColor;
    qreal dOpacity;
    if (isEnabled()) { // 可用狀態
        if (m_bChecked) { // 開啟狀態
            background = m_checkedColor;
            thumbColor = m_checkedColor;
            dOpacity = 0.600;
        } else { //關閉狀態
            background = m_background;
            thumbColor = m_thumbColor;
            dOpacity = 0.800;
        }
    } else {  // 不可用狀態
        background = m_background;
        dOpacity = 0.260;
        thumbColor = m_disabledColor;
    }
    // 繪製大橢圓
    painter.setBrush(background);
    painter.setOpacity(dOpacity);
    path.addRoundedRect(QRectF(m_nMargin, m_nMargin, width() - 2 * m_nMargin, height() - 2 * m_nMargin), m_radius, m_radius);
    painter.drawPath(path.simplified());

    // 繪製小橢圓
    painter.setBrush(thumbColor);
    painter.setOpacity(1.0);
    painter.drawEllipse(QRectF(m_nX - (m_nHeight / 2), m_nY - (m_nHeight / 2), height(), height()));
}

// 滑鼠按下事件
void SwitchControl::mousePressEvent(QMouseEvent *event)
{
    if (isEnabled()) {
        if (event->buttons() & Qt::LeftButton) {
            event->accept();
        } else {
            event->ignore();
        }
    }
}

// 滑鼠釋放事件 - 切換開關狀態、發射toggled()訊號
void SwitchControl::mouseReleaseEvent(QMouseEvent *event)
{
    if (isEnabled()) {
        if ((event->type() == QMouseEvent::MouseButtonRelease) && (event->button() == Qt::LeftButton)) {
            event->accept();
            m_bChecked = !m_bChecked;
            emit toggled(m_bChecked);
            m_timer.start(10);
        } else {
            event->ignore();
        }
    }
}

// 大小改變事件
void SwitchControl::resizeEvent(QResizeEvent *event)
{
    m_nX = m_nHeight / 2;
    m_nY = m_nHeight / 2;
    QWidget::resizeEvent(event);
}

// 預設大小
QSize SwitchControl::sizeHint() const
{
    return minimumSizeHint();
}

// 最小大小
QSize SwitchControl::minimumSizeHint() const
{
    return QSize(2 * (m_nHeight + m_nMargin), m_nHeight + 2 * m_nMargin);
}

// 切換狀態 - 滑動
void SwitchControl::onTimeout()
{
    if (m_bChecked) {
        m_nX += 1;
        if (m_nX >= width() - m_nHeight)
            m_timer.stop();
    } else {
        m_nX -= 1;
        if (m_nX <= m_nHeight / 2)
            m_timer.stop();
    }
    update();
}

// 返回開關狀態 - 開啟:true 關閉:false
bool SwitchControl::isToggled() const
{
    return m_bChecked;
}

// 設定開關狀態
void SwitchControl::setToggle(bool checked)
{
    m_bChecked = checked;
    m_timer.start(10);
}

// 設定背景顏色
void SwitchControl::setBackgroundColor(QColor color)
{
    m_background = color;
}

// 設定選中顏色
void SwitchControl::setCheckedColor(QColor color)
{
    m_checkedColor = color;
}

// 設定不可用顏色
void SwitchControl::setDisbaledColor(QColor color)
{
    m_disabledColor = color;
}

示例

下面,我們來實現一組開關按鈕。

效果

這裡寫圖片描述

原始碼

為了演示,可以設定開關的樣式、以及狀態等效果。

SwitchControl *pSwitchControl = new SwitchControl(this);
SwitchControl *pGreenSwitchControl = new SwitchControl(this);
SwitchControl *pDisabledSwitchControl = new SwitchControl(this);

// 設定狀態、樣式
pGreenSwitchControl->setToggle(true);
pGreenSwitchControl->setCheckedColor(QColor(0, 160, 230));
pDisabledSwitchControl->setDisabled(true);
pDisabledSwitchControl->setToggle(true);

// 連線訊號槽
connect(pSwitchControl, SIGNAL(toggled(bool)), this, SLOT(onToggled(bool)));

相關推薦

Qt定義控制元件開關按鈕

簡述 接觸過iOS系統的童鞋們應該對開關按鈕很熟悉,在設定裡面經常遇到,切換時候的滑動效果比較帥氣。 通常說的開關按鈕,有兩個狀態:on、off。 下面,我們利用自定義控制元件來實現一個開關按鈕。 原理 重寫滑鼠按下事件(mousePres

Qt編寫定義控制元件開關按鈕

從2010年進入網際網路+智慧手機時代以來,各種各樣的APP大行其道,手機上面的APP有很多流行的元素,開關按鈕個人非常喜歡,手機QQ、360衛士、金山毒霸等,都有很多開關控制一些操作,在Qt widgets應用專案上,在專案中應用些類似的開關按鈕,估計也會為專案增添不少新鮮

編寫Qt Designer定義控制元件——編寫定義控制元件介面

        既然是控制元件,就應該有介面,預設生成的控制元件類只是一個繼承了QWidget的類,如下: #ifndef LOGLATEDIT_H #define LOGLATEDIT_H #include <QWidget> class LogLat

編寫Qt Designer定義控制元件——如何建立並使用Qt定義控制元件

    http://blog.csdn.net/giselite/article/details/12622429   在使用Qt Designer設計窗體介面時,我們可以使用Widget Box裡的窗體控制元件非常方便的繪製介面,比如拖進去一個按鈕,一個文字編輯器等。雖然Qt Designer裡的控制元

Qt編寫定義控制元件37-發光按鈕會呼吸的痛

一、前言 這個控制元件是好早以前寫的,已經授權過好幾個人開源過此控制元件程式碼,比如紅磨坊小胖,此控制元件並不是來源於真實需求,而

定義控制元件Dialog篇

自定義控制元件實現方式 本文中初步討論了關於原生Dialog實現方式,自定義Dialog樣式實現以及注意細節 基於Android Studio API 23開發 - 原生Dialog三種樣式實現方式 - 自定義Dialog實現方式 - 結束語

Qt編寫定義控制元件9-導航按鈕控制元件

前言 導航按鈕控制元件,主要用於各種漂亮精美的導航條,我們經常在web中看到導航條都非常精美,都是html+css+js實現的,還

定義控制元件6---PorterDuffXfermode圖形過濾器橡皮擦應用

activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schema

android定義控制元件_完全定義控制元件定義開關

前面總結到自定義控制元件分為 組合控制元件 繼承已有控制元件 比如自定義SmartImageView繼承ImageView 完全自定義控制元件 上一篇寫了自定義控制元件的自定義屬性深入理解點選連結檢視,是自定控制元件比較難以理解的地方,但是是很重

Qt編寫定義控制元件外掛開放動態庫dll使用永久免費

這套控制元件陸陸續續完善了四年多,目前共133個控制元件,除了十幾個控制元件參考網友開源的程式碼寫的,其餘全部原創,在釋出之初就有

WPF定義控制元件控制元件分類

原文: WPF自定義控制元件(一)の控制元件分類 一、什麼是控制元件(Controls)         控制元件是指對資料和方法的封裝。控制元件可以有自己的屬性和方法,其中屬性是控制元件資料的簡單訪問者,方法則是控制元件的一些簡單而可見的功能、控制元件建

WPF 定義控制元件的坑蠢的:定義控制元件內容不顯示

原文: WPF 自定義控制元件的坑(蠢的:自定義控制元件內容不顯示) 自定義控制元件不顯示內容 由於工作需要在寫WPF,其中想要實現一些自己的控制元件所以直接自定義了控制元件博主是繼承了ContenControl的控制元件開始寫的但是發現不管設定Content屬性為任何都是不顯示

WPF定義控制元件定義控制元件

原文: WPF自定義控制元件(四)の自定義控制元件 在實際工作中,WPF提供的控制元件並不能完全滿足不同的設計需求。這時,需要我們設計自定義控制元件。 這裡LZ總結一些自己的思路,特性如下: Coupling UITemplate Behaviour Function Package

WPF定義控制元件の使用者控制元件完結

原文: WPF自定義控制元件(五)の使用者控制元件(完結) 使用者控制元件,WPF中是繼承自UserControl的控制元件,我們可以在裡面融合我們的業務邏輯。 示例:(一個厭惡選擇的使用者控制元件) 後端: using iMicClassBase; using iMicClassBase.B

Android 開發定義控制元件開發-01

最近一直在忙於公司的專案,因為要去現場測試正式使用,專案不大但是經手了三個人,到我這裡只能去填坑了,不說這個了,說一下今天得主題,自定義控制元件之基本圖形繪製。 我們平時畫圖需要兩種工具:紙和筆。在Android中 Paint 就是畫筆,而Canvas類就是紙,在這裡叫做畫布。 所以

Qt編寫定義控制元件屬性設計器

以前做.NET開發中,.NET直接就集成了屬性設計器,VS不愧是宇宙第一IDE,你能夠想到的都給你封裝好了,用起來不要太爽!因為專案需要自從全面轉Qt開發已經6年有餘,在工業控制領域,有一些應用場景需要自定義繪製一些控制元件滿足特定的需求,比如儀器儀表、組態等,而且需要直接使用者通過屬性設計的形式生成匯出控制

定義控制元件顏色由綠色過渡到紅色的控制元件

先寫一個顏色的過度(由綠色過度到紅色) **自定義控制元件的程式碼部分** public class OneView extends View { private Paint paint; private Canvas mConvas;

Android 開發定義控制元件開發-02

1.畫筆的基本設定 : 1.setColor() 該函式的作用是設定畫筆顏色,完整的函式宣告如下: void setColor(int color) 我們知道,一種顏色是由紅、綠、藍三色合成出來的,所以引數 color 只能取8位的0xAARRGGBB樣式顏色值。 其中:

定義控制元件14---ViewGroup繪製的Padding、margin注意

ViewGroup測量子元素有關,其中measureChildWithMargins和measureChildren類似只是加入了對Margins外邊距的處理,ViewGroup提供對子元素測量的方法從measureChildren開始: measureChildren的邏

Android軟體開發 定義控制元件

Android軟體開發之 自定義控制元件 雖然Android系統提供了各種各樣的控制元件供我們開發使用,但在實際的開發中,系統提供的控制元件有時候不能滿足我們的需求,這時我們就需要自定義一個控制元件。 下面的例子就來自定義一個簡單的Button: 首先是佈局,image_btn.xml: <?xml