Solved Pass two arguments to a slot
-
Hello, can you show me a example?
- Create a slot with same number of parameters of the signal.
- Emit a signal inside this slot passing the index and another thing.
How I can call comboBoxCourseLoadValues(int, int) directly ?
I need pass the current index of combobox when it's change and another parameter.My best regards.
-
@Helson
Hello,
Slots are regular functions, so you can call them as such. For example:class ExampleClass : public QObject { Q_OBJECT signals: void myComboSignal(int, int); public slots: ExampleClass() : additionalParameter(100) { combo = new QComboBox(); QObject::connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(handleComboIndex(int))); } void handleComboIndex(int index) { comboBoxCourseLoadValues(index, additionalParameter); // < Call the slot directly // AND/OR emit myComboSignal(index, additionalParameter); // < Emit your own signal that you can connect to another slot } void comboBoxCourseLoadValues(int, int); private: int additionalParameter; QComboBox * combo; }
Kind regards.
-
Hey there,
Why don't you use a vector instead? -
Hi
If your compiler supported c++11 and Qt5 later, then:
connect(comboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
[&](int index){ comboBoxCourseLoadValues(index, yourDefinedSecondParameter); }); -
@Devopia53
It's give me a compile error;
'QComboBox::currentIndexChanged' : cannot access protected member declared in class 'QComboBox' -
Can you explain me a little bit?
-
Thanks for you elucidation.
But I dont know how I can get "additionalParameter" into handleComboIndex() without use it's in class construct.
This parameter value is obtained in runtime.I'm using QT 4.8 version.
My best regards!
-
Hello,
you can use other way to declare SIGNAL & SLOT combination withconnect(ComboBox, ¤tIndexChanged, this, &comboBoxCourseLoadValues);
and then you can use as many parameters as you want for comboBoxCourseLoadValues.
Kind regards.
-
I try this, but the slot is never called :/
-
@Helson said:
Thanks for you elucidation.
But I dont know how I can get "additionalParameter" into handleComboIndex() without use it's in class construct.
This parameter value is obtained in runtime.I'm using QT 4.8 version.
My best regards!
as explained above by @kshegunov there is no direct way to connect with single argument signal to a double argument slot. The problem could be how the SW shall decide what the second arguments are.
There are more elaborate ways to handle, but I think it is much simpler for you at the time to add another slot routine with only one argument. This may be connected to the combobox. Within this single argument slot you simply call your double argument slot. You can use any slot as a member function, because it simply is.
-
@Helson said:
I try this, but the slot is never called :/
Because you are still using Qt 4.8. To my knowledge it has been added to Qt 5.3 or higher.
[edit: koahnig]
-
How I can pass the parameter inside to the second slot ?
void handleComboIndex(int index) { comboBoxCourseLoadValues(index, additionalParameter); //additionalParameter is unknow here // AND/OR emit myComboSignal(index, additionalParameter); // }
additionalParameter is obtained in another method.
So I want to spend the second parameter in the slot.Please.
-
Basically the first possibility. As described a slot routine is basically an extended member function and you still can use it as member function.
You can handle it also through a signal (your emit there) plus an additional connect to the new slot, but that seems ackward here.
Where should your parameter come from?
Your combobox will not know either. If you know it outside sometwhere you have to pass it to the object beforehand. signal-slots do some "magic", but crystal ball reading is not part of it ;) -
Same .cpp file.
void ClassOne::execute() { QVector<QString> myArray; DialogClass dlg; if(QDialog::Accepted == dlg.exec()) { for(int i = 0; i < 10 ; i++){ other = getInfo(); myArray.push_back(other); } connect(dlg.ComboBox, SIGNAL(currentIndexChanged(int)), &dlg, mySlot(int))); dlg.comboBox(anotherArray); // This fill the combobox } } void DialogClass::mySlot(int index){ //I Need the myArray here. }
-
As I said the easiest way is to use a vector but keep in mind it is not a direct solution.
First you have to send the currentIndexChanged(int) to a slot that accepts (int) as-well, like this:
connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboBoxCourseLoadValues(int)));
But the Slot is capable of remembering the value of emitted signal until it receives another call.
As soon as the slot receives two INTs(what you are looking for) you can do what ever you want with it or emit another signal from there to another slot which accepts (int,int).
Here is the code:void MainWindow::comboBoxCourseLoadValues(int p) { static QVector<int> vec; vec.push_front(p); if(vec.size()>1){ /*Here you have got 2 INTs.*/ /*And you can do what ever you want with them. Eg:Send a new Signal(int,int)*/ /*but make sure to not send the address of them somewhere else AT ALL*/ /*becuase we are going to clear the vector Now*/ qDebug()<<vec.at(0)<<vec.at(1); //for viewing the out put result vec.clear(); }
}
-
I did not find the class definition for DialogClass above. However, it may look similar like:
class Dialog : public QObject { ... public: QComboBox ComboBox; ... public slots: void mySlot(int index); ... };
What hinders you to add the second array?
class Dialog : public QObject { ... QVector<QString> mArray; public: QComboBox ComboBox; ... void setSecondArray ( const QVector<QString> & array ) { mArray = array; } public slots: void mySlot(int index); ... }; void DialogClass::mySlot(int index){ do_something_with = mArray.at(index); //I Need the myArray here. }
-
@Nouriemm
Ohh Thanks for this explanation, but in this case I need a parameter of another type:connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboBoxCourseLoadValues(int, QVector)));
But I like your explanation, I learned too much about signals.
-
The @mrjj give me a solution with pointers in another topic:
https://forum.qt.io/topic/62427/get-a-array-inside-slotBut what you say is very useful.
QVector<QString> mArray; ///is in another class definition
Why the code below is in the class definition? When it's called? How I can do learn more about it?
void setSecondArray ( const QVector<QString> & array ) { mArray = array; }
-
@Helson said:
Why the code below is in the class definition? When it's called? How I can do learn more about it?
void setSecondArray ( const QVector<QString> & array )
{
mArray = array;
}That is basically inline code. As you might have noted is the array in my definition in the private section. Therefore, is somewhat secured, because not diretly accessible. With the inline definition the code section will be introduced directly whereever you use. It spares the overhead of calling a member function.
It has ups and downs and should be used only for short sections of code. Here is a link to an articleI seemed to remember that you noted a deadline. Therefore "kis"="keep it simple".
I looked at @mrjj code you linked. As far as I saw you cannot use it. You seem to use the original signals of QComboBox and that gives you an index for the current line. To make out of int index a complete array with other information would be magic. -
@Helson
Hello,
I'm a bit slow to respond these days, and have little to contribute to @koahnig's excellent points. I would advise against @Nouriemm's suggestion though only because of the unneeded use of static variables. While here it's not such a problem (since GUI objects are not reentrant anyway), in many cases using static variables like this:void MainWindow::comboBoxCourseLoadValues(int p) { static QVector<int> vec; ... }
can get you a lot of headaches ... especially when order of construction/destruction is important.
Kind regards.