Quantcast
Channel: Jobs
Viewing all articles
Browse latest Browse all 18427

QRadioButton group and QDataWidgetMapper

$
0
0
I wanted to be able to represent an exclusive set of options as several radio buttons. I also wanted to be able to store an integer Id corresponding to which option was selected in my database, and ideally, use QDataWidgetMapper to do it. Yes, a combo box could serve here, but for this particular UI, I would prefer option buttons (in part because there are other widgets that become enabled/disabled as a result of the selected option, and they are laid out in a way that helps make the relationship apparent.) I came across QButtonGroup and thought that might solve my problem, but QButtonGroup is not a QWidget, which is needed by QDataWidgetMapper. I also came acroos QGroupBox which is a QWidget, but it doesn’t have a property to get at the currently selected option (and why should it – a group box could have all sorts of different sets of child items.) I thought this would be a fairly common problem, so I wanted to present my solution so that: Those of you who have tackled this problem before can chime in on the solution Those of you who are looking for a solution have a starting place I wanted to use a widget as a starting place, and then add to the interface: A method for assigning an integer Id to each option button A property for getting/setting the current Id / selected option button The currently selected propery needs to be a property in order to work with QDataWidgetMapper. The best widget to use as a starting place seemed to be…well…QWidget! Here is my OptionGroup class: optiongroup.h #ifndef OPTIONGROUP_H #define OPTIONGROUP_H   #include <QWidget> #include <QMap>   class QRadioButton;   class OptionGroup : public QWidget {     Q_OBJECT     Q_PROPERTY(int currentSelection READ currentSelection WRITE setCurrentSelection USER true)   public:     explicit OptionGroup(QWidget *parent = 0);         int currentSelection() const;     void setCurrentSelection(int selection);       void setSelectionId(QRadioButton *button, int id);   signals:     void selectionChanged(int selection);   public slots:     void buttonToggled(bool checked);   private:     int currentSelection_;     QMap<int, QRadioButton*> buttonMap_;     QMap<QRadioButton*, int> revButtonMap_; };   #endif // OPTIONGROUP_H optiongroup.cpp: #include <QRadioButton> #include "optiongroup.h"   OptionGroup::OptionGroup(QWidget *parent) :     QWidget(parent), currentSelection_(-1) { }   int OptionGroup::currentSelection() const {    return currentSelection_; }   void OptionGroup::setCurrentSelection(int selection) {     // If the specified selection id is not in our button map,     // then it is invalid, set selection to -1.  Otherwise,     // update the selection to user specified value       auto iter = buttonMap_.find(selection);     if (iter == buttonMap_.end() || selection < 0) {         currentSelection_ = -1;         for (iter = buttonMap_.begin(); iter != buttonMap_.end(); ++iter)             iter.value()->setChecked(false);     } else {         iter.value()->setChecked(true);         currentSelection_ = selection;     } }   void OptionGroup::setSelectionId(QRadioButton* button, int id) {     // Make sure we got a valid Id (non-negative)     // Also then listen for signals from this button     if (id >= 0) {         buttonMap_[id] = button;         revButtonMap_[button] = id;         connect(button, SIGNAL(toggled(bool)), this, SLOT(buttonToggled(bool)));     } }   void OptionGroup::buttonToggled(bool checked) {     if (checked == true) {         QRadioButton* btn = qobject_cast<QRadioButton*>(sender());         Q_ASSERT(btn);         currentSelection_ = revButtonMap_[btn];         emit selectionChanged(currentSelection_);     } } Note that you’ll need to call setSelectionId() to assign an Id to each QRadioButton. -1 is used to represent an invalid or unset Id, so be sure to pass something that is greater than or equal to 0. If you had: ui->optBtnA which corresponds with Id 0 ui->optBtnB which corresponds with Id 1 ui->optBtnC which corresponds with Id 2 And they were all children of an OptionGroup ui->optionGroup, you would do this: ui->optionGroup.setSelectionId(ui->optBtnA, 0); ui->optionGroup.setSelectionId(ui->optBtnB, 1); ui->optionGroup.setSelectionId(ui->optBtnC, 2);   ... // QDataWidgetMapper mapper; // int optionField; This is which field in your data model you are storing the option value in mapper.addMapping(ui->optionGroup, optionField); This seems to be working well enough. Having the two maps for looking up Ids/QRadioButton* is redundant. Since the list of options is always likely to be pretty small, so I might use a QList of QPair’s and just sequentially search them. Hit me with your critiques, and hope this helps somebody else out.

Viewing all articles
Browse latest Browse all 18427

Trending Articles