Question

I have written a simple widget, which has a list of QCheckBoxes. Also, my class has a member called isMultiselectable, which is initialized in the constructor. When this option is TRUE, I want the widget to be multi-selectable (i.e. the user can set more than one QCheckBox). Otherwise, it has to prevent the multiple selection of the QCheckBoxes.

What is the recommended way of implementing this? Thank you.

Was it helpful?

Solution 2

There are at least three ways to solve this issue, but I would suggest you to do the third if the second is not possible in your use case:

  • You could implement the mediator pattern yourself

The idea would that you get the "selected" signal for each button, and then you deselect all the other.

  • Switching between QRadioButtons and QCheckBoxes.

You could just simply switching between radio buttons and regular check boxes based on the value of the boolean variable isMultiselectable

  • Use the mediator pattern, but with the help of the QSignalMapper class

You could use the following signals below to achieve this based on your preference. I would personally suggest to use whichever you find more understandable, let it either integer, string, or the widget.

int

void QSignalMapper::mapped(int i) [signal]

This signal is emitted when map() is signalled from an object that has an integer mapping set. The object's mapped integer is passed in i.

QString

void QSignalMapper::mapped(const QString & text) [signal]

This signal is emitted when map() is signalled from an object that has a string mapping set. The object's mapped string is passed in text.

QWidget

void QSignalMapper::mapped(QWidget * widget) [signal]

This signal is emitted when map() is signalled from an object that has a widget mapping set. The object's mapped widget is passed in widget.

QObject

void QSignalMapper::mapped(QObject * object) [signal]

This signal is emitted when map() is signalled from an object that has an object mapping set. The object provided by the map is passed in object.

You would then go through the QCheckBoxes to connect their signals to your handler with a somewhat similar code to this:

#include <QCheckBox>
#include <QStringList>

...

QStringList checkBoxStringList = QStringList() << "foo" << "bar" << "baz";

for (int i = 0; i < checkBoxStringList.size(); ++i) {
    QCheckBox *checkBox = new QCheckBox(checkBoxStringList.at(i));
    connect(checkBox, SIGNAL(clicked()), signalMapper, SLOT(map()));
    signalMapper->setMapping(checkBox, texts.at(i));
    gridLayout->addWidget(checkBox, i / 3, i % 3);
}

connect(signalMapper, SIGNAL(mapped(QString)),
        this, SIGNAL(myHandler(QString)));

...

void MyClass::myHandler(QString checkBoxString)
{
    if (isMultiSelectable)
        return;

    // Go through the rest and call setChecked(false)

    ...
}

You can find the documentation here for the class and its use:

http://qt-project.org/doc/qt-5.1/qtcore/qsignalmapper.html

OTHER TIPS

Non-multiselectable checkboxes will confuse users. You should not do this. When you need multi-selection, use checkboxes. When you need single-selection, use radio buttons instead. QRadioButtons are single-selectable by default.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top