Results 1 to 4 of 4

Thread: QRadioButton and QDataWidgetMapper

  1. #1
    Join Date
    Jun 2009
    Posts
    9
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QRadioButton and QDataWidgetMapper

    Hi,

    i have a model, were each item has among others a boolean option. The logical approach of using QDataWidgetMapper works quite well for all the other fields (mapped to LineEdits, ComboBoxes, etc.). But I have no success mapping this boolean option to two QRadioButtons.

    Here is what I do:
    - Groupbox with two RadioButtons and autoExcluse == true
    - QDataWidgetMapper maps the Variable to the QRadioButton for "true"

    Here is what I expect:
    - model->setData ( "true" ) when this QRadioButton is selected
    - model->setData ( "false") when the other QRadioButton is selected

    Here is what I get:
    - model->setData ("true") when the unmapped QRadioButton is checked (which should be false)
    - nothing happens, when the mapped QRadioButton is checked

    I used connect(radioButton, SIGNAL(toggled(bool)), mapper, SLOT(submit())), but that works only sometimes and looks like a hack.

    Any Ideas? Should I subclass QItemDelegate and look at the events? if so, which? and then do what? Or rather QRadioButton, so that it behaves?

    Thanks a lot for your help
    Simon

  2. #2
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QRadioButton and QDataWidgetMapper

    for a bool property where only one option is checked, you can
    * use a QCheckBox
    * use 2 exclusive radiobuttons and just ignore the second for the QDataWidgetMapper;
    the first one for a relevant purposes will behave like a checkbox and contain the correct bool state all by itself, too.

    If you want to map the possible values of an enum, things are different though. then you need to consider all the radiobuttons. in this case i'd suggest to create a wrapper parent widget with a (custom) property value() that contains the desired enum value and map the parent with that property in the QDataWidgetMapper.

    HTH

  3. #3
    Join Date
    Jun 2009
    Posts
    9
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QRadioButton and QDataWidgetMapper

    Hi Caduel,

    thanks for your help and sorry for replying so late ...

    So here are my observations, as a reference for myself and anyone searching an answer:

    *QCheckBox:
    Might work, but I didn't try. Generally speaking QDataWidgetMapper needs a Focus event or something similiar to notice the changed data.

    *QRadioButton:
    The problem with your Idea is that one cannot "uncheck" an exclusive QRadionButton, because Qt apparently doesn't know which RadioButton to check in exchange (doesn't really make sense for just two Buttons ...).

    So here is what I did:

    1. Create a Class ButtonGroup: public QWidget
    Qt Code:
    1. class ButtonGroup : public QWidget {
    2. Q_OBJECT
    3. public:
    4. ButtonGroup(QWidget *parent = 0);
    5. virtual ~ButtonGroup();
    6.  
    7. Q_PROPERTY(int checkedId READ getCheckedId WRITE checkId USER true)
    8. int getCheckedId();
    9. void checkId(int id);
    10.  
    11. void addButton(QAbstractButton *button, int id);
    12.  
    13. signals:
    14. void buttonClicked();
    15.  
    16. private:
    17. QButtonGroup *m_buttonGroup;
    18. QVBoxLayout *m_layout;
    19. };
    To copy to clipboard, switch view to plain text mode 
    - contains a QButtonGroup and some layouting
    - give it a user property and return QButtonGroup::checkedId there
    - use QButtonGroup::button(int id) to get an Button and then check it with button->setChecked(true);

    2. Map this with the QDataWidgetMapper

    3. in your delegate add a slot like this:
    Qt Code:
    1. void Delegate::commitMyData() {
    2. QWidget *obj = qobject_cast<QWidget*>(sender());
    3. emit commitData(obj);
    4. emit closeEditor(obj);
    5.  
    6. qDebug() << "commitMyData";
    7. }
    To copy to clipboard, switch view to plain text mode 

    4. connect QButtonGroup::buttonClicked signal to your delegate::commitMyData

    5. thats it

    future improvements:

    would be cool to have ButtonGroup use SendEvent or something, so that I can just map it using QDataWidgetMapper and be done.

    Hope that helps someone.

    Bye

  4. #4
    Join Date
    May 2011
    Posts
    4
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QRadioButton and QDataWidgetMapper

    I had trouble understanding this so I posted about it on stackoverflow.

    The piece I was missing is how the delegate needs to be connected to the mapper.

    I have created a sample project that works at http://scanrobot.fi/wp-content/uploa...tablemodel.zip

    Here is the essence of what I needed to understand in practice:

    Qt Code:
    1. mapper->setModel(model);
    2. mapper->toLast();
    3.  
    4. QRadioButton *b1=new QRadioButton("a",this);
    5. QRadioButton *b2=new QRadioButton("b",this);
    6.  
    7. RadioButtonDelegate *delegate=new RadioButtonDelegate(this);
    8. ButtonGroup *group=new ButtonGroup(this);
    9. mapper->addMapping(group,model->fieldIndex("radio"));
    10.  
    11. // set the delegate as the item delegate of mapper
    12. mapper->setItemDelegate(delegate);
    13. // connect value change in group to delegate so it can send appropriate signals
    14. connect(group,SIGNAL(buttonClicked(int)),delegate,SLOT(commitMyData()));
    15.  
    16. group->addButton(b1,1);
    17. group->addButton(b2,0);
    To copy to clipboard, switch view to plain text mode 

    Source for buttongroup.cpp:

    Qt Code:
    1. #include "buttongroup.h"
    2.  
    3. ButtonGroup::ButtonGroup(QWidget *parent) :
    4. QWidget(parent)
    5. {
    6. m_buttonGroup=new QButtonGroup(this);
    7. connect(m_buttonGroup,SIGNAL(buttonClicked(int)),this,SIGNAL(buttonClicked(int)));
    8.  
    9. }
    10.  
    11. int ButtonGroup::getCheckedId()
    12. {
    13. int id=m_buttonGroup->id(m_buttonGroup->checkedButton());
    14. return id;
    15. }
    16.  
    17. void ButtonGroup::checkId(int id)
    18. {
    19. m_buttonGroup->button(id)->setChecked(true);
    20. }
    21.  
    22. void ButtonGroup::addButton(QAbstractButton *button, int id)
    23. {
    24. m_buttonGroup->addButton(button,id);
    25. }
    To copy to clipboard, switch view to plain text mode 

    buttongroup.h (nothing very new here compared to the original url):

    Qt Code:
    1. #ifndef BUTTONGROUP_H
    2. #define BUTTONGROUP_H
    3.  
    4. #include <QWidget>
    5. #include <QButtonGroup>
    6. #include <QVBoxLayout>
    7. #include <QAbstractButton>
    8. #include <QRadioButton>
    9.  
    10. class ButtonGroup : public QWidget
    11. {
    12. Q_OBJECT
    13. public:
    14. explicit ButtonGroup(QWidget *parent = 0);
    15.  
    16. Q_PROPERTY(int checkedId READ getCheckedId WRITE checkId USER true)
    17. int getCheckedId();
    18. void checkId(int id);
    19.  
    20. void addButton(QAbstractButton *button, int id);
    21.  
    22. signals:
    23. void buttonClicked(int);
    24.  
    25. private:
    26. QButtonGroup *m_buttonGroup;
    27. QVBoxLayout *m_layout;
    28.  
    29.  
    30. };
    31.  
    32. #endif // BUTTONGROUP_H
    To copy to clipboard, switch view to plain text mode 

    radiobuttondelegate.h (nothing very new here either):

    Qt Code:
    1. #ifndef RADIOBUTTONDELEGATE_H
    2. #define RADIOBUTTONDELEGATE_H
    3.  
    4. #include <QItemDelegate>
    5.  
    6. class RadioButtonDelegate : public QItemDelegate
    7. {
    8. Q_OBJECT
    9. public:
    10. explicit RadioButtonDelegate(QObject *parent = 0);
    11.  
    12. signals:
    13.  
    14. public slots:
    15.  
    16. void commitMyData();
    17. };
    18.  
    19. #endif // RADIOBUTTONDELEGATE_H
    To copy to clipboard, switch view to plain text mode 

    radiobuttondelegate.cpp (or here):
    Qt Code:
    1. #include "radiobuttondelegate.h"
    2. #include <QDebug>
    3. RadioButtonDelegate::RadioButtonDelegate(QObject *parent) :
    4. QItemDelegate(parent)
    5. {
    6. }
    7. void RadioButtonDelegate::commitMyData() {
    8. QWidget *obj = qobject_cast<QWidget*>(sender());
    9. emit commitData(obj);
    10. emit closeEditor(obj);
    11.  
    12. qDebug() << "commitMyData";
    13. }
    To copy to clipboard, switch view to plain text mode 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.