Qt之QSpinBox和QDoubleSpinBox

weixin_34384681發表於2016-08-23

簡述

QSpinBox和QDoubleSpinBox均派生自QAbstractSpinBox。

QSpinBox旨在處理整數和離散值(例如:月份名稱),QDoubleSpinBox則用於處理浮點值。他們之間的區別就是處理資料的型別不同,其他功能都基本相同。

QDoubleSpinBox的預設的精度是2位小數,但可以通過setDecimals()來改變。

下面主要以QSpinBox為例,來講解常用的功能。最後部分,會單獨分享QDoubleSpinBox的精度設定。

詳細描述

QSpinBox類提供了一個微調框部件。

QSpinBox允許使用者選擇一個值,通過單擊向上/向下按鈕或按下鍵盤的上/下箭頭來增加/減少當前顯示的值,使用者也可以輸入值。微調框支援整數值,但可以被擴充套件為不同的字串,使用validate()、textFromValue()和valueFromText()。

當QSpinBox的值發生改變時,會發射兩個valueChanged()訊號,其中一個提供int型別,另一個則是QString型別,該QString提供了prefix()和suffix()。當前值可以用value()來讀取,setValue()來設定。

單擊向上/向下按鈕或按下鍵盤的上/下箭頭時,將以singleStep()為步長增加/減少當前值。如果想改變這種行為,可以過載虛擬函式stepBy()。最小值、最大值和步長可以使用其中的一個建構函式來設定,以後可以用setMinimum()、setMaximum()和setSingleStep()來修改。

大多數微調框是定向的,但也可以設定為迴圈的。例如:如果取值範圍是0 - 99,當前值是99,如果wrapping()被設定為true,點選“向上”按鈕值會變為0。如果你想要一個迴圈微調框,可以使用setWrapping()函式。

顯示的值可以和任意的字串進行附加,適用setPrefix()和setSuffix()分別可以設定字首和字尾,例如:貨幣或計量單位。微調框中的文字可以用text()(包括任何字首和字尾)或者通過cleanText()(沒有字首()、沒有字尾()、無前導或結尾空白)來獲取。

除了數值的範圍,通常需要使用setSpecialValueText()給使用者一個特殊(預設)的選擇。

基本使用

構建一個QSpinBox,範圍:20 - 200,步長:10,開啟迴圈。

效果

這裡寫圖片描述

原始碼

設定步長為10以後,當值發生改變時,就會在當前值的基礎上±10(相當於一個等差數列,公差為10)。當我們開啟迴圈後,當前值達到最大或者最小時,就會迴圈(類似於聽歌的列表迴圈)。

#include <QSpinBox>

class MainWindow : public CustomWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0)
        : CustomWindow(parent)
    {
        // ...
        QSpinBox *pSpinBox = new QSpinBox(this);
        pSpinBox->setRange(20, 200);  // 範圍
        pSpinBox->setSingleStep(10); // 步長
        pSpinBox->setValue(150);  // 當前值
        pSpinBox->setPrefix("$ ");  // 字首
        pSpinBox->setSuffix(" %");  // 字尾
        pSpinBox->setWrapping(true);  // 開啟迴圈

        connect(pSpinBox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            [=](int value)
        {
            qDebug() << "Value : "  << value;
            qDebug() << "Text : "  << pSpinBox->text();
        });

        connect(pSpinBox, static_cast<void(QSpinBox::*)(const QString &)>(&QSpinBox::valueChanged),
            [=](const QString &text)
        {
            qDebug() << "Text Value : "  << text;
            qDebug() << "Clean Text : " << pSpinBox->cleanText();
        });
    }
};

這裡使用了Qt5的訊號與槽的語法(後面詳細講解),由於valueChanged()是一個過載訊號,所以需要進行引數類別區分。

輸出如下:

Text Value : "$ 160 %"
Clean Text : "160"
Value : 160
Text : "$ 160 %"

特殊文字值

如果設定了specialValueText,只要當前值等於微調框的最小值時,將顯示該文字,而不是一個數值。典型的用途是表明此選擇具有特殊(預設)的意思。

例如,如果你的微調框允許使用者可以選擇一個比例係數(或縮放級別),用於顯示影像,並且應用程式能夠自動選擇一個,將使影像完全符合顯示視窗,可以像這樣設定微調框:

效果

這裡寫圖片描述

原始碼

QSpinBox *zoomSpinBox = new QSpinBox(this);
zoomSpinBox->setRange(0, 1000);  // 範圍
zoomSpinBox->setSingleStep(10);  // 步長
zoomSpinBox->setSuffix("%");  // 字首
zoomSpinBox->setSpecialValueText(tr("Automatic"));  // 特殊文字值
zoomSpinBox->setValue(100);  // 當前值

一旦當前值變為最小值時,顯示的就是Automatic。

自定義

如果使用prefix()、suffix()和specialValueText()沒有提供足夠的控制,可以子類化QSpinBox,重寫valueFromText()和textFromValue()。

例如,自定義一個微調框,允許使用者輸入圖示大小(例如:”32 x 32”):

效果

這裡寫圖片描述

原始碼

#include <QSpinBox>

class IconSizeSpinBox : public QSpinBox
{
    Q_OBJECT

public:
    explicit IconSizeSpinBox(QWidget *parent = 0){}

protected:
    // 將輸入的文字解讀為適當的值
    virtual int valueFromText(const QString &text) const Q_DECL_OVERRIDE
    {
        QRegExp regExp(tr("(\\d+)(\\s*[xx]\\s*\\d+)?"));

        if (regExp.exactMatch(text)) {
            return regExp.cap(1).toInt();
        } else {
            return 0;
        }
    }
    // 根據輸入的值返回文字
    virtual QString textFromValue(int value) const Q_DECL_OVERRIDE
    {
        return tr("%1 x %1").arg(value);
    }
};

QDoubleSpinBox

上面的所有功能對於QDoubleSpinBox同樣適用。

下面,我們看下精度的用法,其實比較簡單,一般主要使用setDecimals()設定精度,然後利用setSingleStep()來設定步長即可。

效果

這裡寫圖片描述

原始碼

QDoubleSpinBox *pSpinBox = new QDoubleSpinBox(this);
pSpinBox->setRange(0, 20);  // 範圍
pSpinBox->setDecimals(3);  // 精度
pSpinBox->setSingleStep(0.005); // 步長

connect(pSpinBox, static_cast<void(QDoubleSpinBox::*)(const QString &)>(&QDoubleSpinBox::valueChanged),[=](const QString &text)
{
    qDebug() << text;
});

常用的基本就這些,如果需要更多其他的特性,請參考QAbstractSpinBox。

相關文章