Selection controls

Cascades includes a couple of different options for handling selection within your app: CheckBox and RadioGroup.

Check box

A CheckBox is a selection control with two states: checked and unchecked. Check boxes allow the user to make multiple selections simultaneously from a number of options. This behavior differs from a radio button, which supports only one selection at a time.


Screen showing an unchecked CheckBox and a checked CheckBox.

A CheckBox supports optional text that you can use to describe the purpose or function of the control. To toggle the state of a CheckBox, you can tap anywhere inside the control, including the text.

The visual appearance of a CheckBox is fixed and can't be changed. The optional text is always left-aligned in the parent container, and has a predefined font, font size, and font color. The check box itself is always right-aligned in the parent container.

Sizing

  • The height is fixed and can't be changed.
  • If text is used, the width automatically adjusts to fill the parent container. There is also a minimum limit to ensure that some of the text is displayed if space is limited.
  • If text isn't used, the width is fixed and can't be changed.
  • The leftPadding, rightPadding, topPadding, and bottomPadding properties can't be used on this control.

Responding to selection changes

When a user selects or clears a CheckBox, the control emits the checkedChanged() signal that you can capture so that your application can respond to it.

In QML, you use the onCheckedChanged signal handler to listen for the state change. The following example shows how you can use a CheckBox to enable or disable a second CheckBox:

CheckBox {
    text: "Check to enable"
    onCheckedChanged: {
        // Use an if statement to respond to checked changes and
        // enable or disable a second CheckBox control
        if (checked) {
            myCheckBox.enabled = true;
            myCheckBox.text = "Enabled";
        } else {
            myCheckBox.enabled = false;
            myCheckBox.text = "Disabled";
        }
    }
}
CheckBox {
    id: myCheckBox
    text: "Disabled"
    enabled: false
}

Here's how to do the same thing in C++:

#include <bb/cascades/CheckBox>
//...

firstCheckBox = new CheckBox();
firstCheckBox->setText("Check to enable");

secondCheckBox = new CheckBox();
secondCheckBox->setText("Disabled");
secondCheckBox->setEnabled(false);

// 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 checkChanged() signal to the handleCheckedChanged()
// slot
connectResult = QObject::connect(firstCheckBox, 
                                 SIGNAL(checkedChanged(bool)),
                                 this,
                                 SLOT(handleCheckedChanged(bool)));

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

//...

// Create the handleCheckedChanged() slot to capture the
// checkedChanged() signal emitted by the CheckBox
void CheckBox::handleCheckedChanged(bool checked)
{
    // Use an if statement to enable or disable
    // the second CheckBox based on the checked state
    // of the first CheckBox
	if (checked) {
		secondCheckBox->setEnabled(true);
		secondCheckBox->setText("Enabled");
	} else {
		secondCheckBox->setEnabled(false);
		secondCheckBox->setText("Disabled");
	}
}

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

Radio group

A RadioGroup is used for grouping a set of Option controls. Options in a RadioGroup are displayed as radio buttons, and they support optional text to describe the purpose or function of the option.

An active radio button. An inactive radio button.

In a RadioGroup, only one option can be selected at a time, and these options are typically used to give users a choice between a set of predefined options (such as "Easy" or "Hard").

The appearance of a RadioGroup is fixed and can't be changed. The optional text is always left-aligned in the parent container, and has a predefined font, font size, and font color. The radio button itself is always right-aligned in the parent container.

Sizing

Responding to option selection

When a user selects an option in a RadioGroup, the RadioGroup emits the selectedOptionChanged() signal that you can use to affect the behavior of your app.

In QML, you can use the onSelectedOptionChanged signal handler to respond to option changes. The following example uses two options in a RadioGroup to control the enabled state of a third option.

// Create a RadioGroup with three options
RadioGroup {
    Option {
        id: option1
        text: "Enable option"
    }
    Option {
        id: option2
        text: "Disable option"
        selected: true
    }
    Option {
        id: option3
        text: "Option"
        enabled: false
    }
    onSelectedOptionChanged: {
        // Use an if statement to enable or disable the third
        // option in the RadioGroup based on the selected option
        if (option1.selected == true) {
            option3.enabled = true;
        } else if (option2.selected == true) {
            option3.enabled = false;
        }
    }
}

Here's how to do the same thing in C++:

#include <bb/cascades/RadioGroup>
#include <bb/cascades/Option>
//...

// Create a RadioGroup with three options
RadioGroup *myRadioGroup = RadioGroup::create()
                .add(Option::create()
                    .text("Enable option")
                    .objectName("option1"))
                .add(Option::create()
                    .text("Disable option")
                    .selected(true)
                    .objectName("option2"))
                .add(Option::create()
                    .text("Option")
                    .enabled(false)
                    .objectName("option3"));
                    
// 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 selectedOptionChanged() signal to the handleOptionChanged()
// slot
connectResult = connect(myRadioGroup, SIGNAL(selectedOptionChanged
                    (bb::cascades::Option*)), this, 
                    SLOT(handleOptionChanged(bb::cascades::Option*)));
                    
// This is only available in Debug builds
Q_ASSERT(connectResult);

//...

// Create the handleOptionChanged() slot to capture the
// selectedOptionChanged() signal emitted by the RadioGroup
void RadioGroup::handleOptionChanged(bb::cascades::Option *selectedOption)
{
    // Use an if statement to enable or disable the third option
    // in the RadioGroup based on the selected option
	if (option1->isSelected() == true) {
		option3->setEnabled(true);
	} else if (option2->isSelected() == true){
		option3->setEnabled(false);
	}
}

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

Selection example

The following example creates a series of selection controls that are used to change the background color of a container.

Four CheckBox controls are used to control the RGBA values of the background color. When you select a CheckBox, a value of 1 is applied for that color. Clearing a CheckBox sets the value back to 0.

When the app starts, only three CheckBox controls and two RadioGroup options are initially visible. When the RGBA radio option is selected, the Alpha CheckBox becomes visible. Selecting the Alpha check box halves the opacity of the background color.

Animation showing a RadioGroup and a series of CheckBox controls used to change the background color of a Container.

main.qml

import bb.cascades 1.0

Page {
    // Create four values that are used
    // to define the RGBA color values for
    // the background color of the main container
    property variant cb1value: cb1.checked
    property variant cb2value: cb2.checked
    property variant cb3value: cb3.checked
    property real cb4value: 1.0

    titleBar: TitleBar {
        title: "Selection"
    }

    Container {
        Container {
            RadioGroup {
                Option {
                    text: "RGB"
                    selected: true
                }
                Option {
                    text: "RGBA"
                }
                onSelectedOptionChanged: {
                    // Use an if statement to control the
                    // visibility of the "Alpha" CheckBox
                    if (selectedOption.text == "RGBA") {
                        cb4.visible = true;
                    } else {
                        cb4.visible = false;
                        cb4.checked = false;
                        cb4value = 1.0;
                    }
                }
            }
        }
        Container {
            topPadding: 30
            bottomPadding: 30
            preferredWidth: 500
            horizontalAlignment:HorizontalAlignment.Center

            CheckBox {
                id: cb1
                text: "Red"
            }
            CheckBox {
                id: cb2
                text: "Green"
            }
            CheckBox {
                id: cb3
                text: "Blue"
            }
            CheckBox {
                id: cb4
                text: "Alpha"
                visible: false
                onCheckedChanged: {
                    // If the "Alpha" check box is selected
                    // the opacity of the background color
                    // is halved.
                    if (checked) {
                        cb4value = 0.5
                    } else {
                        cb4value = 1.0
                    }
                }
            }
        }
        Container {
            // Set the background color of the container
            // using the value of each check box
            background: Color.create
                (cb1value, cb2value, cb3value, cb4value)
            horizontalAlignment: HorizontalAlignment.Fill
            verticalAlignment: VerticalAlignment.Fill
            layoutProperties: StackLayoutProperties {
                spaceQuota: 1.0
            }              
        }
    }
}

SelectionRecipe.h

#ifndef SELECTIONRECIPE_H_
#define SELECTIONRECIPE_H_


#include <bb/cascades/Page>
#include <bb/cascades/Container>
#include <QObject>
#include <bb/cascades/CheckBox>
#include <bb/cascades/RadioGroup>
#include <bb/cascades/Option>

namespace bb { namespace cascades { class Application; }}

using namespace bb::cascades;

class SelectionRecipe : public QObject
{
    Q_OBJECT

public:

    SelectionRecipe(bb::cascades::Application *app);
        virtual ~SelectionRecipe() {}

public slots:
	void handleSelectedOptionChanged(bb::cascades::Option *selectedOption);
	void handleCheckedChanged(bool checked);

private:

	float cb1value;
	float cb2value;
	float cb3value;
	float cb4value;

	CheckBox *mCheckBox1;
	CheckBox *mCheckBox2;
	CheckBox *mCheckBox3;
	CheckBox *mCheckBox4;

	Container *colorContainer;
    Container *root;
    Container *radioContainer;
    Container *checkContainer;

};

#endif /* SELECTIONRECIPE_H_ */

SelectionRecipe.cpp

#include "SelectionRecipe.h"

#include <bb/cascades/Application>
#include <bb/cascades/Container>
#include <bb/cascades/DockLayout>
#include <bb/cascades/CheckBox>
#include <bb/cascades/RadioGroup>
#include <bb/cascades/Option>
#include <bb/cascades/StackLayout>
#include <bb/cascades/StackLayoutProperties>
#include <bb/cascades/Page>
#include <bb/cascades/Color>
#include <bb/cascades/TitleBar>


using namespace bb::cascades;

SelectionRecipe::SelectionRecipe(bb::cascades::Application *app)
: QObject(app)
{
    // Create a Container and set the layout
    Page *page = new Page();
    Container *root = Container::create()
    			.layout(new StackLayout());

    TitleBar *tbar = TitleBar::create().title("Selection");
    page->setTitleBar(tbar);


    Container *radioContainer = Container::create();

    // Create a RadioGroup and add options for "RGB" and "RGBA"
    RadioGroup *myRadioGroup = RadioGroup::create()
    			.add(Option::create().text("RGB").selected(true))
    			.add(Option::create().text("RGBA"));

    radioContainer->add(myRadioGroup);


    // 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 selectedOptionChanged() signal to the
    //handleSelectedOptionChanged() slot
    connectResult = connect(myRadioGroup,
                      SIGNAL(selectedOptionChanged(bb::cascades::Option*)),
                      this,
                      SLOT(handleSelectedOptionChanged(bb::cascades::Option*)));

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

    Container *checkContainer = Container::create()
    			.horizontal(HorizontalAlignment::Center)
    			.preferredWidth(500)
    			.top(30)
    			.bottom(30);

    // Create the "Red" check box
    mCheckBox1 = CheckBox::create()
            .text("Red");

    // Connect the checkedChanged() signal to the
    // handleCheckedChanged() slot
    connectResult = connect(mCheckBox1, SIGNAL
           (checkedChanged(bool)), this, SLOT(handleCheckedChanged(bool)));

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

    // Create the "Green" check box
    mCheckBox2 = CheckBox::create()
            .text("Green");

    // Connect the checkedChanged() signal to the
    // handleCheckedChanged() slot
    connectResult = connect(mCheckBox2, SIGNAL
           (checkedChanged(bool)), this, SLOT(handleCheckedChanged(bool)));

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

    // Create the "Blue" check box
    mCheckBox3 = CheckBox::create()
            .text("Blue");

    // Connect the checkedChanged() signal to the
    // handleCheckedChanged() slot
    connectResult = connect(mCheckBox3, SIGNAL
           (checkedChanged(bool)), this, SLOT(handleCheckedChanged(bool)));

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

    // Create the "Alpha" check box
    mCheckBox4 = CheckBox::create()
    		.text("Alpha")
    		.visible(false);

    // Connect the checkedChanged() signal to the
    // handleCheckedChanged() slot
    connectResult = connect(mCheckBox4, SIGNAL
           (checkedChanged(bool)), this, SLOT(handleCheckedChanged(bool)));

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

    checkContainer->add(mCheckBox1);
    checkContainer->add(mCheckBox2);
    checkContainer->add(mCheckBox3);
    checkContainer->add(mCheckBox4);

    StackLayoutProperties* myStackProperties = StackLayoutProperties::create()
    			.spaceQuota(1.0);

    colorContainer = Container::create()
    			.background(Color::Black)
    			.horizontal(HorizontalAlignment::Fill)
    			.vertical(VerticalAlignment::Fill)
    			.layoutProperties(myStackProperties);

    root->add(radioContainer);
    root->add(checkContainer);
    root->add(colorContainer);
    page->setContent(root);
    app->setScene(page);

}

// Create the handleSelectedOptionChanged() slot to capture
// the selectedOptionChanged() signal emitted by the RadioGroup
void SelectionRecipe::handleSelectedOptionChanged(Option *selectedOption)
{
    // Use an if statement to control the visibility of the
    // "Alpha" check box
	if (selectedOption->text() == "RGBA") {
		mCheckBox4->setVisible(true);
	} else {
		mCheckBox4->setVisible(false);
		mCheckBox4->setChecked(false);
		cb4value = 1.0;
	}
	colorContainer->setBackground(Color::fromRGBA
			(cb1value, cb2value, cb3value, cb4value));
}

// Create the handleCheckedChanged() slot to capture the
// checkedChanged() signals emitted from each of the
// check boxes
void SelectionRecipe::handleCheckedChanged(bool checked)
{
    // Set the value based on the checked state
	cb1value = mCheckBox1->isChecked();
	cb2value = mCheckBox2->isChecked();
	cb3value = mCheckBox3->isChecked();

    // If the "Alpha" check box is checked, the value
    // is set to 0.5 to halve the opacity
	if (mCheckBox4->isChecked()) {
		cb4value = 0.5;
	} else {
		cb4value = 1.0;
	}
	colorContainer->setBackground(Color::fromRGBA
				(cb1value, cb2value, cb3value, cb4value));
}

main.cpp

#include "SelectionRecipe.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 SelectionRecipe(&app);
 
    return Application::exec();
}

Last modified: 2013-12-21



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus