PDA

View Full Version : simple way to connect 120 pushbutton signals to one slot



wagmare
21st January 2010, 12:57
hi friends,
i am having 128 QPushButton which checkable() condition is set true(Toggle button) in my window and i want to set color of each button if it is toggled so i will use stylesheet to set color with QPushButton signal toggled(bool) to recv_slot(bool)..
but the problem is how i can connect each 128 buttons to a single slot .. it makes my program lengthier .. how can i minimize in connection .. can i go for QSignalMapper or QList ..?

please suggest me a good solution ..

aamer4yu
21st January 2010, 13:23
Put the buttons in a QList<QPushButton*>. Iterate this list and connect the signal and slot for each button
for eg -
foreach(button,buttonList)
connect(button,SIGNAL(clicked()),this,SLOT(onButto nClicked()));

in the slot u can cast the sender() to know which button was clicked.

^NyAw^
21st January 2010, 13:24
Hi,

Maybe qbuttongroup ("http://doc.trolltech.com/latest/[b)[/b].html"]QButtonGroup can help you. You can get the button list and do a connection for every button on the list.

vishwajeet.dusane
21st January 2010, 13:52
Hi,

One more way could be derive your class from QPushButton and add color change mechanism within derived class only. if that is not feasible for your architecture then add overloaded constructor within derived class to accept that class pointer to which your QPushButton needs to be connected. so within this class only you will have connect call. Later just matter of string replace in your code from QPushButton to MyCustonDerivedPushButton class.

squidge
21st January 2010, 13:57
Why not use QSignalMapper? http://qt.nokia.com/doc/4.6/qsignalmapper.html

It's a simple way of combining multiple signals to a single slot, and can pass id to your slot to state which triggered the signal.

wagmare
21st January 2010, 15:00
[Why not use QSignalMapper? http://qt.nokia.com/doc/4.6/qsignalmapper.html

It's a simple way of combining multiple signals to a single slot, and can pass id to your slot to state which triggered the signal.

but if i am using toggled(bool) signal of QPushButton how can i use QSignalMapper because i need the bool value .. i dont know the procedure ..can u explan it ..

wagmare
21st January 2010, 15:19
thanks for reply to all

wagmare
21st January 2010, 15:22
Put the buttons in a QList<QPushButton*>. Iterate this list and connect the signal and slot for each button
for eg -
foreach(button,buttonList)
connect(button,SIGNAL(clicked()),this,SLOT(onButto nClicked()));

in the slot u can cast the sender() to know which button was clicked.
thanks aamer ji ...
i dont know how to get sender() from the button variable ... is it a QPushButton variable ..?

please can u tell me more about this method ...

i coded like this

button_list = this->findChildren<QPushButton *> ();
for(int i =0; i <button_list.size(); i++)
{
connect(button_list[i], SIGNAL(toggled(bool)), this, SLOT(state_changed(bool)));
}

in state_changed(bool) slot
f
or(i =0; i <button_list.size(); i++)
{
if(sender() == button_list[i])
{
printf("blah blah \n");
}
}

faldzip
21st January 2010, 16:07
thanks aamer ji ...
i dont know how to get sender() from the button variable ... is it a QPushButton variable ..?

please can u tell me more about this method ...

i coded like this

button_list = this->findChildren<QPushButton *> ();
for(int i =0; i <button_list.size(); i++)
{
connect(button_list[i], SIGNAL(toggled(bool)), this, SLOT(state_changed(bool)));
}

in state_changed(bool) slot
f
or(i =0; i <button_list.size(); i++)
{
if(sender() == button_list[i])
{
printf("blah blah \n");
}
}

that is generally how this works: sender() returns QObject * pointer pointing to the object which called this slot. You then have to cast it to QPushButton* (using qobject_cast is the best way to do so), so your code is right :]

graciano
21st January 2010, 16:45
Why not ...


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindowClass)
{
ui->setupUi(this);
...
//QPushButton *buttonx[9];
buttonx[0] = ui->b1;
buttonx[1] = ui->b2;
buttonx[2] = ui->b3;
buttonx[3] = ui->b4;
buttonx[4] = ui->b5;
buttonx[5] = ui->b6;
buttonx[6] = ui->b7;
buttonx[7] = ui->b8;
buttonx[8] = ui->b9;

//http://doc.trolltech.com/qq/qq10-signalmapper.html
//The Signal Mapper Approach
QSignalMapper *signalMapper = new QSignalMapper(this);
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(myButtonPressed(int)));
for(int i = 0; i < 9; i++){
signalMapper->setMapping(buttonx[i], i + 1);
connect(buttonx[i], SIGNAL(clicked()), signalMapper, SLOT(map()));
}
...

}

...

void MainWindow::myButtonPressed(int m){
//use one specific button

//iterate the array to use all

}

...

aamer4yu
21st January 2010, 18:48
I guess I paid more attention to your list question. On reading again I feel what Vishwajeet said is better solution( Subclassing the QPushButton).
In fact I myself had used subclassing for same problem once. You only need to do the following n paintEvent of inherited class-

MyButton::paintEvent(*event)
{ QPushButton::paintevent(event);
QPainter painter(this);
// draw some color over top of the button using painter.
}

wagmare
22nd January 2010, 06:15
Why not ...


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindowClass)
{
ui->setupUi(this);
...
//QPushButton *buttonx[9];
buttonx[0] = ui->b1;
buttonx[1] = ui->b2;
buttonx[2] = ui->b3;
buttonx[3] = ui->b4;
buttonx[4] = ui->b5;
buttonx[5] = ui->b6;
buttonx[6] = ui->b7;
buttonx[7] = ui->b8;
buttonx[8] = ui->b9;

//http://doc.trolltech.com/qq/qq10-signalmapper.html
//The Signal Mapper Approach
QSignalMapper *signalMapper = new QSignalMapper(this);
connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(myButtonPressed(int)));
for(int i = 0; i < 9; i++){
signalMapper->setMapping(buttonx[i], i + 1);
connect(buttonx[i], SIGNAL(clicked()), signalMapper, SLOT(map()));
}
...

}

...

void MainWindow::myButtonPressed(int m){
//use one specific button

//iterate the array to use all

}

...


but if i want to use toggled(bool) signal of QPushButton how can i map it to signal mapper ... i need the bool value ... i dont know how to do it in signal mapper mapping ..

wagmare
22nd January 2010, 06:18
I guess I paid more attention to your list question. On reading again I feel what Vishwajeet said is better solution( Subclassing the QPushButton).
In fact I myself had used subclassing for same problem once. You only need to do the following n paintEvent of inherited class-

MyButton::paintEvent(*event)
{ QPushButton::paintevent(event);
QPainter painter(this);
// draw some color over top of the button using painter.
}

right
i agree but all the push buttons are designed by designer .. i am having 128 button arranged in specific position by designer .. if i am adding it maually to my widget means no problem i will inherit QPushButton as sub class and i will set pseudo state in QPaintEvent ..

vishwajeet.dusane
22nd January 2010, 11:35
Hi

Thats ok if u have added push buttons from designer. There is an option in designer to promote your class. You right click on your push button and then press "promote to ..." promote single QPushButton to yourCustonClass. save your .ui file. in any editor open you .ui file which is nothign but a xml file. do the string replace for rest of you 127 push buttons ;) Now you have used custom class in designer for your push buttons.

second step would be to write implementation for it. that you can manage rite.

numbat
22nd January 2010, 12:43
but if i want to use toggled(bool) signal of QPushButton how can i map it to signal mapper ... i need the bool value ... i dont know how to do it in signal mapper mapping ..
Just call isChecked ().

caduel
22nd January 2010, 14:20
you can try to move the logic inside the stylesheet:

QPushButton:checked {
background-color: rgb(224, 0, 0);
border-style: inset;
}

(See the style sheet docs: stylesheet-examples

wagmare
25th January 2010, 11:28
you can try to move the logic inside the stylesheet:

QPushButton:checked {
background-color: rgb(224, 0, 0);
border-style: inset;
}

(See the style sheet docs: stylesheet-examples

this one works perfect ... in designer i had given this stylesheet option to all 128 push buttons ... but dissolves the border of the push button .. it look flat surface without the trace of the button

aamer4yu
25th January 2010, 12:09
but dissolves the border of the push button .. it look flat surface without the trace of the button
Thats why subclassing is the better way. You wont lose the native drawing.

wagmare
25th January 2010, 12:23
Thats why subclassing is the better way. You wont lose the native drawing.

right sub classing is better option ...