Pass multiples arguments to a slot Qt - c++

I'm using a Qt horizontal slider and I want to connect it's valueChanged signal to a slot I defined. However I need to access a specific member inside this slot to modify a variable thanks to the int I set with the slider. Until now, my connect line looks like this :
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(setVariable(int)));
Is it possible to pass more than one argument to my slot ?What i'd like to do is something like :
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(setVariable(int, pointerToMember*)));
If not how can I proceed ?
Thanks

Yes, you can, but you need to use new connect style, so you can pass lambda function
connect(slider, &QAbstractSlider::valueChanged, this, [=](int &new_value) { this->setVariable(new_value, ... );});
Edit:
This works only in Qt5 and above

Related

Qt signals and slots. Slider and progress bar

connect(ui->horizontalSlider, SIGNAL(valueChanged(int)),
ui->progressBar, SLOT(setValue(ui->horizontalSlider->value()-100)));
I tried to connect signals and slots when the value of slider for example is 30, the value of the progress bar should be 70 but nothing is changed, I can't find mistake.
Welcome aboard.
I am surprised that you want to do a calculation inside the connect. This is not how it works.
Please add a slot (method) like
void slotSetValue(int input)
{
ui-progressBar->setValue(100 - input);
}
and connect like
connect(ui->horizontalSlider,SIGNAL(valueChanged(int)), this,slotSetValue(int)));
Fine-tuning for your code may be needed.
ps. I recommend to use the Qt5-connects, which are compile-time-checked.
You normally do :
connect(ui->horizontalSlider, &QSlider::valueChanged,
ui->horizontalSlider, &QSlider::setValue);
but your logic is not correct because you are connecting a valueChanged with a setValue , that will crash your app since an overflow will happen...
on the other hand, connect used to only pipe signals and slots, you can not do math in the signals/functions involved in that, at least not like that... you will need a lambda or something similiar in the middle

Qt custom QPushButton clicked signal

I want to send two integers, string and fret, to a SLOT that will process the location of the button that was pressed. The SIGNAL and SLOT argument have to match so I am thinking I need to reimplement the QPushButton::clicked event method. Problem is I am new to Qt and could use some direction.
connect(&fretBoardButton[string][fret], SIGNAL(clicked()), this, SLOT (testSlot()));
If you use the C++11 connection syntax you can use a lambda with calls testSlot with your string and fret arguments:
connect(&fretBoard[string][fret], &QPushButton::clicked, [this, string, fret]() {
testSlot(string, fret);
});
This code creates a lambda using the [captures, ...](arguments, ...) { code } syntax. When you make the connection it captures the string and fret variable values, and will then pass them on to testSlot when the button is clicked.
There are Two approaches you could use to add the string and fret information. one is to use the sender() function to get the button which emitted the signal. you can the access fret and string if they are members of your button class so in the SLOT you would have.
MyPushButton *button = (MyPushButton *)sender();
button.getFret();
button.getString();
However since you are already subClassing QPushButton you could use a private SLOT to catch the buttonClicked signal and re-emit a signal with the right values.
In the constructor
connect(this, SIGNAL(clicked()), this, SLOT(reemitClicked()));
and then the reemit SLOT
void MyPushButton::reemitClicked()
{
emit clicked(m_fret, m_string);
}
be sure to add the appropriate private slot and public signal to you class
https://doc.qt.io/archives/qq/qq10-signalmapper.html see this artical for a good discussion on various ways to add an argument to signal.

Qt: Connecting multiple input widgets with valueChanged(int) signals to single slot?

With Qt 4.8 I create a number of input widgets (QSpinBox, QSlider) programmatically.
In the end, I would like to have a single method to handle changes of any of these input widgets, ideally by index.
However, these widgets only have a Signal with parameter, e.g. valueChanged(int).
This is not compatible with QSignalMapper()'s Slot map().
As it was pointed out in the comments, the connection does work!
connect( spinbox, SIGNAL( valueChanged(int) ),
signalMapper, SLOT( map() )
);
Now I just need to get the value, but this cannot be done via the sender() method anymore, because this now is the SignalMapper.
Original question:
Is there another way besides (re)implementing QSignalMapper with additional parameters or a parameter-less valueChanged() for the widget or using objectName and QObject::sender() in order for the Slot to see which element changed (and get the new value)?
You can use QAbstractSpinBox::editingFinished() and QAbstractSlider::sliderReleased() as your signals, they are parameterless.
Unfortunately there is no parameterless version of QAbstractSlider::valueChanged() so if you want a signal emitted continuously as the slider moves, you may need to subclass QSlider and create it. E.g.
class MySlider : public QSlider
{
...
private slots:
void HandleValueChanged(int) { emit valueChanged(); }
signals:
void valueChanged();
};
MySlider::MySlider(...)
{
connect(this, SIGNAL(valueChanged(int)), this, SLOT(HandleValueChanged(int)));
}
Though I admit, this may not be the most elegant solution.
If I understand your question and what you have until now correctly, you are missing two parts.
mapper->setMapping(<spinbox>, <id or name or pointer to the spinbox);
connect(mapper, SIGNAL(mapped(<datatype you used in setMapping()>),
this, SLOT(HandleValueChanged(<datatype you used in setMapping()>)));
So the HandleValueChanged() slot will receive an identifier of your sender, then you can directly access the value of the sender with the appropriate getter.
The method setMapping() takes either and integer, QString or a pointer to the widget itself as second argument. This is then forwarded via the mapped() signal of the mapper, so you can later identify which widget emitted the signal.

Qt: connecting signal to slot having more arguments

I want to connect a signal clicked() from the button to a slot of different object.
Currently I connect signal to helper method and call desired slot from there:
connect(button, SIGNAL(clicked()), this, SLOT(buttonClicked()));
void buttonClicked() { // Helper method. I'd like to avoid it.
someObject.desiredSlot(localFunc1(), localFunc2());
}
But maybe there is a more simple and obvious way to do this?
is this what you want to do:
the signal clicked should be connected to the "desiredSlot" which takes two arguments that are returned by localFunc1 & 2 ??
this is not possible, as you can read in the QT docs. A slot can take less arguments than provided by the signal - but not the opposite way! (The documentation says "This connection will report a runtime error")
This ought to work with the new signal/slot mechanism in qt 5:
connect( button, &QPushButton::clicked, [&](){ someObject.desiredSlot( localFunc1(), localFunc2() ); } );
You will need to adjust the lambda capture to your needs.
In some cases, default arguments may help, e.g. declare desiredSlot as:
desiredSlot(int a=0, int b=0)
You cannot access members in default argument though.
That is not the way to connect signals and slots in QT. You should use:
connect(button, SIGNAL(clicked()), receiver, SLOT(slotToBeCalled());
Have a look at the QT documentation.

why append Slot doesn't work?

I have got a problem when I try to make following simple connections
QSpinBox *spinBox = new QSpinBox;
QSlider *slider = new QSlider(Qt::Horizontal);
QTextEdit *text = new QTextEdit("Hello QT!");
QObject::connect(spinBox, SIGNAL(valueChanged(int)),slider, SLOT(setValue(int)));
QObject::connect(slider, SIGNAL(valueChanged(int)),spinBox, SLOT(setValue(int)));
QObject::connect(slider,SIGNAL(valueChanged(int)),text, SLOT(append("slider changed!")));
QObject::connect(spinBox,SIGNAL(valueChanged(int)),text, SLOT(append("spinbox changed!")));
QObject::connect(text,SIGNAL(textChanged()),spinBox,SLOT(clear()));
It can be successfully compiled and excuted.But the two append slots seem not work.I've checked the help manual about QTextEdit and there's a public slot append there.Have I missed something?Help would be appreciated!
Unfortunately, you cannot pass custom values to your slots via QObject::connect (only type information for the arguments is allowed/interpreted correctly). Instead, create your own slot, something like
void MyWidget::mySliderChangedSlot(int newValue)
{
text->append("slider changed!");
}
and use
QObject::connect(slider, SIGNAL(valueChanged(int)), pMyWidget, SLOT(mySliderChangedSlot(int)));
to achieve your desired behaviour.
I hope that helps.
What exactly are you trying to do? That has now way of working because you connect a signal which has an int param to a slot with a string parameter for one, the other thing is that the signal slots where not meant for this kind of usage you just say wich function are conected and they pass parameters betwen them you dont pass the values yourself, you are not using them correctly read the documentation at http://doc.trolltech.com/4.6/signalsandslots.html for correct usage examples.