Sliders

A Slider is an adjustable control with a wide range that you can use to change settings or to show a preview of a change.

Screen showing a Slider control.

The input range for a Slider is set using the fromValue and toValue properties, with the default values being 0.0 and 1.0 respectively. You can get the current value of the slider by using the value and immediateValue properties. The value property is updated only after the slider stops moving, but the immediateValue property is updated constantly.

A Slider doesn't have any modifiable visual properties other than its width.

The value of a slider is always a floating point value.

Sizing

Responding to value changes

A Slider has two signals that you can capture to listen for changes to the slider value, each of which has a different use case. The valueChanged() signal is emitted when the user releases the slider after moving it. The immediateValueChanged() signal is emitted in real time, while the value is changing. You define the way your app responds to these signals by connecting them to slots.

The valueChanged() signal is useful when you care only about the final value, or if it's too resource-intensive to handle updates for every intermediate value. For example, in an app that plays video, you'd probably want to update the screen only after the user releases the slider, and not for every value in between. The immediateValueChanged() signal is useful when you want to make changes continually. For example, on a settings screen, you might want to see how the slider changes volume or brightness as the value changes.

In QML, you capture these signal using the onValueChanged or onImmediateValueChanged signal handlers. This example shows how to use onImmediateValueChanged and output the value to the console.

Slider {
    fromValue: 10.0
    toValue: 20.0
    onImmediateValueChanged: {
        // Output the immediateValue to the console
        console.debug("The slider value is " + immediateValue)
    }
}

In C++, you can create a slot to capture the change. In this example, the slot is called onImmediateValueChanged().

#include <bb/cacades/Slider>
//...

// Create a Slider
Slider *mySlider = Slider::create()
        .fromValue(10.0)
        .toValue(20.0);        

// If any Q_ASSERT statement(s) indicate that the slot failed to connect to 
// the signal, make sure you know exactly why this has happened. This is not
// normal, and will cause your app to stop working
bool connectResult;

// Since the variable is not used in the app, this is added to avoid a 
// compiler warning
Q_UNUSED(connectResult);

// Connect the immediateValueChanged() signal to 
// the onImmediateValueChanged() slot
connectResult = QObject::connect(mySlider, 
                                 SIGNAL(immediateValueChanged(float)),
                                 this,
                                 SLOT(onImmediateValueChanged(float)));
                                 
// This is only available in Debug builds
Q_ASSERT(connectResult);

//...
 
// Create the onImmediateValueChanged() slot to capture
// the immediateValueChanged() signal emitted by the Slider
void Slider::onImmediateValueChanged(float immediateValue)
{
    // Output the immediateValue to the console
    qDebug() << "The slider value is " << immediateValue;
}

For more information on responding to signals, see Signals and slots.

Slider examples

The following example demonstrates how to capture slider movements and update a Label with the value. The slider value is rounded to one digit of precision after the decimal point.

Animation showing a Label that displays the value of a moving Slider control.

main.qml

import bb.cascades 1.0
 
Page {
    titleBar: TitleBar {
        title: "Slider"
    }
    Container {
        layout: DockLayout {}
        Container {
            leftPadding: 20
            rightPadding: leftPadding
            horizontalAlignment: HorizontalAlignment.Center
            verticalAlignment: VerticalAlignment.Center
             
            // A label that presents the current Slider 
            // values (with one-digit precision)
            Label {
                id: labeltext
                text: "Value: 0"
                textStyle.base: SystemDefaults.TextStyles.TitleText
            }
            // A simple Slider with changing values from 
            // 0 to 1 (one-digit precision)
            Slider {
                fromValue: 0
                toValue: 1
                onImmediateValueChanged: {
                    // Update the Label with current 
                    // value (with one-digit precision)
                    labeltext.text = 
                        "Value: " + immediateValue.toFixed(1);
                }
            }
        }
    }
}

sliderrecipe.h

#ifndef _SLIDERRECIPE_H_
#define _SLIDERRECIPE_H_

#include <QObject>
#include <bb/cascades/Label>

namespace bb { namespace cascades { class Application; }}

class SliderRecipe: public QObject
{
    Q_OBJECT

public:
    SliderRecipe(bb::cascades::Application *app);

private slots:
    void onSliderValueChanging(float value);

private:
    bb::cascades::Label *mValueLabel;
};

#endif // ifndef _SLIDERRECIPE_H_

sliderrecipe.cpp

#include "sliderrecipe.h"

#include <bb/cascades/Application>
#include <bb/cascades/Container>
#include <bb/cascades/DockLayout>
#include <bb/cascades/Label>
#include <bb/cascades/Page>
#include <bb/cascades/Slider>
#include <bb/cascades/SystemDefaults>
#include <bb/cascades/TextStyle>
#include <bb/cascades/TitleBar>

using namespace bb::cascades;

SliderRecipe::SliderRecipe(bb::cascades::Application *app)
: QObject(app)
{
    Page *page = new Page();
    TitleBar *tbar = TitleBar::create().title("Slider");
    page->setTitleBar(tbar);

    Container *root = Container::create().layout(new DockLayout());

    // The recipe Container
    Container *recipeContainer = Container::create()
            .left(20.0).right(20.0)
            .horizontal(HorizontalAlignment::Center)
            .vertical(VerticalAlignment::Center);

    // A Label is used to present the current
    // value (with one digit precision)
    mValueLabel = Label::create()
    		.text((const QString) "Value: 0")
    		.textStyle(SystemDefaults::TextStyles::titleText());

    // Create a Slider and connect a slot function to the signal for
    // Slider's immediate value
    Slider *slider = new Slider();

    // If any Q_ASSERT statement(s) indicate that the slot failed to connect to
    // the signal, make sure you know exactly why this has happened. This is not
    // normal, and will cause your app to stop working
    bool connectResult;

    // Since the variable is not used in the app, this is added to avoid a
    // compiler warning
    Q_UNUSED(connectResult);

    // Connect the immediateValueChanged() signal to
    // the onSliderValueChanging() slot
    connectResult = connect(slider,
                            SIGNAL(immediateValueChanged(float)),
                            this,
                            SLOT(onSliderValueChanging(float)));

    // This is only available in Debug builds
    Q_ASSERT(connectResult);

    // Add the controls to the recipe Container and set it as
    // the root component
    recipeContainer->add(mValueLabel);
    recipeContainer->add(slider);
    root->add(recipeContainer);
    page->setContent(root);
    app->setScene(page);
}

// Create the onSliderValueChanging() slot to capture
// the valueChanging() signal emitted by the Slider
void SliderRecipe::onSliderValueChanging(float value)
{
    // Convert the value to only have one decimal number
    float valueOneDec = (float) (((int) (value * 10)) / 10.0f);

    // Create a QString from the number
    QString newValue = NULL;
    newValue.setNum(valueOneDec, 'g', 1);

    // Present the new value in the Label
    mValueLabel->setText((const QString) "Value: " + newValue);
}

main.cpp

#include "SliderRecipe.h"

#include <bb/cascades/Application>
#include <Qt/qdeclarativedebug.h>

using namespace bb::cascades;

Q_DECL_EXPORT int main(int argc, char **argv)
{
    Application app(argc, argv);

    new SliderRecipe(&app);

    return Application::exec();
}

Last modified: 2013-12-21

comments powered by Disqus