1. 程式人生 > >Qt5學習筆記——QRadioButton與QButtonGroup

Qt5學習筆記——QRadioButton與QButtonGroup

【我是小標題:使用QToolButton實現radio button功能。】

QRadioButton是什麼?
  下圖是Windows系統中典型的radio button顯示效果。
  這裡寫圖片描述
  QRadioButton是一個可以switch on或off的按鈕,對應的狀態為checked和unchecked。一組QRadioButton通常用於表示程式中“多選一”的選擇,例如單項選擇題。在一組radio buttons中,同一時刻只能有一個button處於checked狀態,如果使用者選擇了其他button,原先被選中的button將變為unchecked。
  和QpushButton一樣,QRadioButton類提供了一個text label和一個small icon,其中text可以在建構函式中設定,也可以通過setText()方法設定,但是icon只能通過setIcon()方法設定,還可以通過在text中某個字母前加“&”符號來指定快捷鍵,例如:

QRadioButton *button = new QRadioButton("Search from the &cursor", this);

上面例子的快捷鍵為“Alt + c”。

分組
  上面其實已經提到過,“同一個父窗體”或“一個button group”,這就是分組。如果沒有進行分組,則預設擁有相同父窗體的radio buttons都將具有相互排他性,所以如果你想在一個窗體中表達多組radio buttons的效果,需要顯式地對它們進行分組,可以使用QGroupBox或者QButtonGroup。建議使用QButtonGroup,因為它僅僅是一個容器,不會有任何視覺表現,並且對於包含在它裡面的子buttons,QButtonGroup提供比QGroupBox方便的訊號槽操作。

訊號
  QRadioButton的訊號繼承自QAbstractButton,一般我們比較關注的是toggled()和clicked(),
  需要注意的是,radio button無論是被switch on還是off,它都會發送一個toggled(bool)訊號,其中包含一個bool型引數用於記錄此次發生的是被switch on還是off,所以如果你想根據radio button的狀態變化來處理一些事的話,就需要connect它們。
  當然,如果組內有很多個radio buttons,並且你又想跟蹤toggled或clicked的狀態,你不需要一個個來connect,因為一旦使用QButtonGroup來管理,完全可以用buttonToggled()和buttonClicked()來處理組內所有buttons的toggled()和clicked()訊號。

方法
  在QButtonGroup中新增一個button可以使用addButton()方法,刪除一個button可以使用removeButton()方法。如果這個button group是exclusive的,還可以通過checkedButton()方法來找到當前處於checked狀態的button。可以通過button()方法找到該button group中的某一個button,以及通過buttons()方法獲得該button group中的buttons列表。

屬性
  接下來,我們需要關注一個名為autoExclusive的bool型屬性,它是QAbstractButton類的屬性,該屬性用於控制一個button是否具有排他性(auto-exclusivity),可以通過autoExclusive() 方法進行查詢,通過setAutoExclusive(bool)方法進行設定。
  如果autoExclusive為true,屬於同一個父窗體的所有checkable按鈕的行為將表現得與它們被放在一個exclusive的button group中一樣,任何時刻都只能有一個按鈕處於checked狀態。不過別擔心, autoExclusive屬性的預設值為false(除了QRadioButton)。
  還要注意的是,如果buttons已經放在了一個button group,那麼autoExclusive屬性將失效。
  QButtonGroup預設是exclusive的,所以只要它的組內的所有buttons是checkable的,不管是不是QRadioButton,都將表現得與QRadioButton一樣。最後如果你建立了一個exclusive的button group,最好為它設定一個初選項,否則組內將沒有任何一個button被選中,這不太符合“one of many”的設計吧。

示例
  以下示例程式碼,包括普通QRadioButton的用法以及用QToolButton模擬的單選按鈕組,相關程式碼解釋請看註釋。(因為QRadioButton只提供了一個small icon,但是我們希望可以更加個性化,所以嘗試用QToolButton來實現)
  
【mainwidget.h】檔案

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include <QRadioButton>
#include <QButtonGroup>
#include <QToolButton>
#include <QLabel>

class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = 0);
    ~MainWidget();

    // 裝置操作模式型別(用於表示普通QButtonGroup)
    typedef enum {
        OM_Auto,
        OM_Manual,
        OM_ManualFullSpeed
    }operatingModeTypes;

    // 動物選項型別(用於表示QToolButton模擬的單選按鈕)
    typedef enum {
        AN_PIG,
        AN_MONKEY,
        AN_CAT
    }animalTypes;

private slots:
    void operatingModeButtonsToggled(int, bool);
    void operatingModeButtonsClicked(int);

    void customButtonsToggled(int, bool);
    void customButtonsClicked(int);

private:
    // 裝置操作模式組
    QButtonGroup *operatingModeGroup;
    QRadioButton *autoBtn;
    QRadioButton *manualBtn;
    QRadioButton *manualFullSpeedBtn;

    // 電源開關組
    QButtonGroup *powerGroup;
    QRadioButton *powerOnBtn;
    QRadioButton *powerOffBtn;

    // 動物選項組
    QButtonGroup *customGroup;
    QStringList animalStrList;  // 記錄動物名稱
    QLabel *curAnimalLabel;     // 顯式當前選中的動物名稱
};

#endif // MAINWIDGET_H

【mainwidget.cpp】檔案

#include "mainwidget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>

// 儲存customGroup中checked和unchecked按鈕的樣式
QString toolBtnCheckedStyleSheet("border-style: solid; background-color: LightGray;");
QString toolBtnUncheckedStyleSheet("border-style: solid; background-color: transparent;");

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle(tr("QRadioButtonTest"));
    setFixedSize(400, 300);

    /* ******* 普通RadioButton ******* */
    autoBtn = new QRadioButton(tr("Auto"));
    manualBtn = new QRadioButton(tr("Manual"));
    manualFullSpeedBtn = new QRadioButton(tr("Manual Full Speed"));

    operatingModeGroup = new QButtonGroup(this);
    operatingModeGroup->addButton(autoBtn, OM_Auto);
    operatingModeGroup->addButton(manualBtn, OM_Manual);
    operatingModeGroup->addButton(manualFullSpeedBtn, OM_ManualFullSpeed);
    autoBtn->setChecked(true);  // 為operatingModeGroup組設定初選項

    /* ******* 新增Icon的RadioButton ******* */
    powerOnBtn = new QRadioButton(tr("Power ON"));
    powerOnBtn->setIcon(QIcon(":/images/power_on.png"));
    powerOffBtn = new QRadioButton(tr("Power OFF"));
    powerOffBtn->setIcon(QIcon(":/images/power_off.png"));

    powerGroup = new QButtonGroup(this);
    powerGroup->addButton(powerOnBtn);
    powerGroup->addButton(powerOffBtn);
    powerOffBtn->setChecked(true);  // 為powerGroup組設定初選項

    /* ******* 自定義RadioButton ******* */
    QSize size(100, 100);
    animalStrList<<"pig"<<"monkey"<<"cat";

    customGroup = new QButtonGroup(this);
    customGroup->setExclusive(true);
    curAnimalLabel = new QLabel;
    QHBoxLayout *customBtnBarLayout = new QHBoxLayout;

    for(int i=0; i<3; i++)
    {
        QToolButton *customBtn = new QToolButton;
        customGroup->addButton(customBtn, AN_PIG+i);    // 將自定義的button加入customGroup中,併為其設定id

        customBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); //文字處於圖片下方
        QPixmap pixmap(QString(":/images/%1.jpg").arg(animalStrList.at(i)));
        customBtn->setIcon(pixmap);   // 為按鈕設定圖示
        customBtn->setIconSize(size);   // 設定圖片大小
        customBtn->setFixedSize(size.width()+30, size.height()+30); // 設定按鈕大小
        customBtn->setText(animalStrList.at(i)); // 設定提示文字
        customBtn->setCheckable(true);
        customBtn->setChecked(false);
        customBtn->setStyleSheet(toolBtnUncheckedStyleSheet); // 所有按鈕初始狀態為unchecked

        customBtnBarLayout->addWidget(customBtn);   // 新增到佈局
    }
    customGroup->button(AN_PIG)->setChecked(true);  // 為customGroup組設定初選項
    customGroup->button(AN_PIG)->setStyleSheet(toolBtnCheckedStyleSheet);   // 修改被checked按鈕的樣式
    curAnimalLabel->setText(QString(tr("當前選擇:"))+animalStrList.at(customGroup->checkedId()));

    // 建立佈局
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(autoBtn);
    mainLayout->addWidget(manualBtn);
    mainLayout->addWidget(manualFullSpeedBtn);
    mainLayout->addStretch();
    mainLayout->addWidget(powerOnBtn);
    mainLayout->addWidget(powerOffBtn);
    mainLayout->addStretch();
    mainLayout->addWidget(curAnimalLabel);
    mainLayout->addLayout(customBtnBarLayout);
    setLayout(mainLayout);

    // 連線訊號
    connect(operatingModeGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(operatingModeButtonsToggled(int,bool)));
    connect(operatingModeGroup, SIGNAL(buttonClicked(int)), this, SLOT(operatingModeButtonsClicked(int)));
    connect(customGroup, SIGNAL(buttonClicked(int)), this, SLOT(customButtonsClicked(int)));
    connect(customGroup, SIGNAL(buttonToggled(int,bool)), this, SLOT(customButtonsToggled(int,bool)));
}

MainWidget::~MainWidget()
{

}

void MainWidget::operatingModeButtonsToggled(int id, bool status)
{
    int tmp = operatingModeGroup->checkedId();
    QString str = operatingModeGroup->checkedButton()->text();
    QByteArray byteArray = str.toLocal8Bit();
    qDebug("flag = %d, status = %d, tmp = %d, checked = %s", id, status, tmp, byteArray.data());
}

void MainWidget::operatingModeButtonsClicked(int id)
{
    qDebug("Clicked: %d", id);
}

void MainWidget::customButtonsToggled(int id, bool state)
{
    if(state == false)
    {   // 修改被unchecked按鈕的樣式
        customGroup->button(id)->setStyleSheet(toolBtnUncheckedStyleSheet);
    }else
    {   // 修改被checked按鈕的樣式
        customGroup->checkedButton()->setStyleSheet(toolBtnCheckedStyleSheet);
    }
}

void MainWidget::customButtonsClicked(int id)
{
    curAnimalLabel->setText(QString(tr("當前選擇:"))+animalStrList.at(id));
}

示例圖片
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

相關推薦

Qt5學習筆記——QRadioButtonQButtonGroup

【我是小標題:使用QToolButton實現radio button功能。】 QRadioButton是什麼?   下圖是Windows系統中典型的radio button顯示效果。      QRadioButton是一個可以switch on或off

linux學習筆記--程序進程管理

ref monitor vim 子進程 free task 排序 image ctrl 、工作管理 1、前臺程序放後臺程序 命令後 加 & 2、任務執行時將前臺任務任務放到後臺中並【暫停】 ctr + z 3、jobs 觀察後臺工作狀態 及多少任務

學習筆記--概率期望

推廣 可能 試驗 同時 導致 取出 集合 .com strong 相關概念 基本事件ω(也稱樣本點): 一次試驗可能出現的每一個直接的 結果。也就是隨機試驗不能夠再分解的結果。 如:E1有兩個基本事件:E1 ={出現正面}, E2={出現反面}   E2有六個基本事件

shell腳本編程學習筆記-分支循環結構

linux shell 1.1 if語句 (1)if條件語句語法:單分支結構 if [ 條件 ] then 指令 fi 或 if [ 條件 ];then 指令 fi if 單分支條件中文編程形象語法 如果 [ 你有房 ] 那麽 我就嫁給你 果如 前面的文件條件表達式[ -f “$file1” ]&

Qt5學習筆記 | 信號槽

object net https qt 5 span BE main.c style CA 在 Qt 5 中,QObject::connect()有五個重載: QMetaObject::Connection connect(const QObject *, const c

Qt5學習筆記(1)-環境配置(win+64bit+VS2013)

Qt5學習筆記(1)-環境配置 工欲善其事必先…不裝…所以裝軟體 久不露面,趕緊打下醬油。 下載 地址:http://download.qt.io/ 這個小網頁就可以下載到跟Qt有關的幾乎所有大部分東西 地址:http:

學習筆記- GC記憶體管理

深入GC與記憶體管理 託管堆中存放引用型別物件,因此GC的記憶體管理的目標主要都是引用型別物件,本文中涉及的物件如無明確說明都指的是引用型別物件。  物件建立及生命週期 一個物件的生命週期簡單概括就是:建立>使用>釋放,在.NET中一個物件的生命週期: n

nodejs學習筆記-組織管理模組

1.將模組定義成類:對於公有變數可以直接獲取或者修改。私有變數需要呼叫函式進行修改。 var _name; var name = ''; var foo = function(name){ _name = name; } foo.prototype.GetName = function(

學習筆記: jstack執行緒狀態

jstatck可以列印JVM內部所有執行緒 1、檢視有哪些java程序   2、檢視所有執行緒的資訊 重定向到5579.txt檔案中 jstack 5579 > 5579.txt   3、執行緒的狀態 New: 執行緒還沒有啟動 RUNNABLE:已經在JVM中

Docker學習筆記 ---儲存管理

儲存管理 為了適應不同平臺不同場景的儲存需求,Docker提供了各種基於不同檔案系統實現的儲存驅動來管理實際的映象檔案   元資料管理 映象在設計上將元資料和檔案儲存完全隔離。Docker管理元資料採用的也正是從上至下repository、image、layer是3個層次。 所以reposi

Spring Boot學習筆記(一)JSP整合

專案結構展示 在webapp目錄下面手動建立JSP的目錄和web.xml 建立web.xml只是為了不報錯,在SpringBoot的專案中實際上用不到web.xml 開啟pom.xml把框住的地方改成war,也就是maven的打包方式,預設的jar,如果要在專案中使用jsp的話就要改成war

C++學習筆記——繼承派生

繼承與派生是同一過程從不同角度的描述: 保持已有類的特性而構造新類的過程稱為繼承。 在已有類的基礎上新增自己的特性而產生新類的過程稱為派生。 被繼承的已有類稱為基類(或父類)。 派生出的新類稱為派生類(或子類)。 直接參與派生出某類的基類稱為直接基類。 基類的基類

Linux學習筆記——VimShell

這兩天在實訓Linux,特此做一下筆記防止遺忘,參考劉老師的《Linux就該這麼學》 一、Vim文字編輯器 1.引入 “在Linux中一切都是檔案,配置一個服務就是在修改其配置檔案的引數。” 而我們在日常的Linux運維過程中,就需要編輯各種各樣的檔案,所以,這

Objective-C學習筆記-NSSetNSDictionary

1.NSSet與NSArray的區別就是NSSet裡面的值是不可重複且無序的,在查詢速度上NSSet比NSArray更快,而NSDictionary則可以儲存鍵值對,這個鍵值對也是無序的,鍵通常是一個字串(唯一的),而值可以是任意型別的物件 2.和NSArray一樣,N

AC620FPGA學習筆記——PLLNCO

AC620FPGA學習筆記——PLL與NCO PLL&NCO 整體框架 PLL配置 NCO配置 程式碼部分 頂層程式碼 PLL&NCO 工程地址:http

Kafka學習筆記 --- Topic offset

我們知道流處理平臺有以下三種特性: * 可以讓你釋出和訂閱流式的記錄。這一方面與訊息佇列或者企業訊息系統類似。 * 可以儲存流式的記錄,並且有較好的容錯性。 * 可以在流式記錄產生時就進行處理。 Kafka適合什麼樣的場景? 它可以用於兩大類別的應用

node.js學習筆記——模組

1.模組 1.1 模組概述 在node中,一個檔案就是一個模組,每個模組都有自己的作用域。 Node中模組分為兩類:一類是Node提供的模組,稱為核心模組;另一類是使用者編寫的模組,稱為檔案模組。 核心模組在node原始碼的編譯過程中就編譯進了二進位制執行檔案

Java學習筆記——介面抽象類的區別

在某種意義上,介面是比抽象類更抽象的類,介面的作用更多是起到標準化、規範化的作用。 它們之間的區別:   1.抽象類可以有非抽象方法,而介面中只能有抽象方法(但在JDK1.8之後的版本中,介面可以擁有方法體,也就是說,介面也可以擁有非抽象方法了)    2.

go語言學習筆記--陣列切片

一、陣列 基本概念 1、一組相同型別已編號且長度固定的資料項序列 宣告格式:var identifier [len]type 2、Go語言中陣列是一種值型別,不是c中指向首元素地址,函式中使用 陣列作為引數,是值傳遞,會產生一次陣列拷貝。不會修改原資料 3、將陣列傳

ARM學習筆記——異常中斷——指令ldr及.word偽指令用法

在ARM彙編指令中,ldr是一條常用的記憶體訪問指令,如: ldr r1, [r2] //將地址為r2的記憶體單元位資料讀取到r1中 它也可以作為大範圍的地址讀取偽指令,如: ldr r1, =label //r1=label的地址 label: