How to know which radiobutton is clicked if they are created at runtime?



  • Hi all,

    Title says everything. I create about 40 radiobuttons at runtime and user clicks on OK button after selecting one of them. The code is below:

    @foreach(QString str_cap, cap)
    {
    QRadioButton *button1 = new QRadioButton();
    button1->setText(QString("%1").arg(str_cap));
    connect(button1, SIGNAL(clicked()), insCategorie, SLOT(mpOnRadiBoxClickked()));
    layout->addWidget(button1, count, int(count/10));
    count ++;
    }@

    After handling the OK button, I need to know which radiobutton user has selected. I tried connecting clicked signal of the button to a slot. The slot if fired nicely but how can I know which radiobutton it is?



  • Hi,

    2 options:

    ##########################################

    1. Inside your slot you can call: QObject::sender()
      Which returns a pointer to the Object emitting the signal.

    By casting this object, you can access it's properties

    @
    void MainWindow::buttonClicked()
    {
    QPushButton button = qobject_cast<QPushButton>( QObject::sender() );

    qDebug() << "Button clicked: " << button->text();
    

    }
    @

    ##########################################

    1. QSignalMapper
      While options 1 works perfect, there is also another option where you don't need to access the sender object.

    buttonwidget.h
    @
    #ifndef BUTTONWIDGET_H
    #define BUTTONWIDGET_H

    #include <QWidget>

    class QSignalMapper;

    class ButtonWidget : public QWidget
    {
    Q_OBJECT
    public:
    explicit ButtonWidget(const QStringList &texts, QWidget *parent = 0);

    signals:
    void clicked(const QString &text);

    private:
    QSignalMapper *signalMapper;

    };

    #endif // BUTTONWIDGET_H
    @

    buttonwidget.cpp
    @
    #include "buttonwidget.h"

    #include <QSignalMapper>
    #include <QPushButton>
    #include <QGridLayout>

    ButtonWidget::ButtonWidget(const QStringList &texts, QWidget *parent) :
    QWidget(parent)
    {
    signalMapper = new QSignalMapper(this);

    QGridLayout *gridLayout = new QGridLayout;
    
    for (int i = 0; i < texts.size(); ++i) {
    
        QPushButton *button = new QPushButton(texts[i]);
        connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
    
        signalMapper->setMapping(button, texts[i]);
    
        gridLayout->addWidget(button, i / 3, i % 3);
    }
    
    connect(signalMapper, SIGNAL(mapped(QString)), this, SIGNAL(clicked(QString)));
    
    setLayout(gridLayout);
    

    }
    @

    mainwindow.h
    @
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private slots:
    void buttonClicked(const QString &text);
    };

    #endif // MAINWINDOW_H
    @

    mainwindow.cpp
    @
    #include "mainwindow.h"
    #include "buttonwidget.h"

    #include <QDebug>

    MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    {
    QStringList textList = QStringList() << "item1" << "item2" << "item3" << "item4" << "item5" << "item6";

    ButtonWidget *buttonWidget = new ButtonWidget(textList);
    
    connect(buttonWidget, SIGNAL(clicked(QString)), this, SLOT(buttonClicked(QString)));
    
    setCentralWidget(buttonWidget);
    

    }

    MainWindow::~MainWindow()
    {

    }

    void MainWindow::buttonClicked(const QString &text)
    {
    qDebug() << "Button clicked: " << text;
    }
    @



  • bq. The slot if fired nicely but how can I know which radiobutton it is?

    Looking at the sender() object inside the slot would be one solution. But it's ugly, because you'll have to compare the pointer against all your RadioButtons! Instead, I would recommend to simply add your RadioButtons to a QButtonGroup. When adding a button to the group via addButton(), you can assign a meaningful id to each button. That id will then be passed to the buttonClicked() signal of your QButtonGroup, when clicking a Button.

    EDIT: Or just call QButtonGroup::checkedButton() to get the RadioButton that is currently selected, whenever you need to know.


    Try like this:
    @QButtonGroup *group = new QButtonGroup();

    foreach(QString str_cap, cap)
    {
    QRadioButton *button = new QRadioButton();
    button->setText(QString("%1").arg(str_cap));
    layout->addWidget(button, count, int(count/10));
    group->addButton(button, count++);
    }

    connect(group, SIGNAL(buttonClicked(int)), this, SLOT(RadiBoxClickked(int)));@



  • Excellent answers!!!
    I will go for the method from Lord Mulder. Thanks a lot.



  • @Mulder

    I completely forgot about QButtonGroup!!

    Thanks for mentioning it!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.