Qt signals and slots. Slider and progress bar - c++

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

Related

Pass multiples arguments to a slot Qt

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

Slot doesnt exist in connect function in C++/Qt project? (already reran make)

I am adding a slider bar to easyPaint, which will enable a zoom function.
I have the slider appearing where I want it on the screen, and the function I built for it shouldn't have any issues, but when I run it, I get a runtime error that the slot doesn't exist, when it clearly does.
I have already tried cleaning the solution, rerunning CMake, and rebuilding, and still get the "slot does not exist" error every time.
Can anyone else think of any other reason why I would get this issue?
Here is the setup of the dock with slider, within the mainwindow class:
dock = new QDockWidget(tr("Zoom"));
slider = new QSlider(dock);
addDockWidget(Qt::BottomDockWidgetArea, dock);
dock->setWidget(slider);
dock->setFeatures(QDockWidget::NoDockWidgetFeatures);
slider->setOrientation(Qt::Horizontal);
slider->setMinimum(0);
slider->setMaximum(16);
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(zoomBarAct(slider->value())));
Here is the zoom function, which I have declared within the private slots section in the header file:
void MainWindow::zoomBarAct(int zoom)
{
float factor = static_cast<float>(zoom) / 4;
getCurrentImageArea()->zoomImage(factor);
getCurrentImageArea()->setZoomFactor(factor);
}
edit for function declaration (other functions after private slots omitted):
private slots:
void zoomBarAct(int zoom);
This:
SLOT(zoomBarAct(slider->value()))
doesn't make sense. You need to specify the name of the slot:
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(zoomBarAct(int));
However, you are using Qt4-style signal/slot connections. If you switch to modern, Qt5-style syntax, these errors will be caught at compile time. Use this instead, which is much safer and guaranteed to never produce these types of runtime errors, since everything is checked during compilation:
connect(slider, &QSlider::valueChanged, this, &MainWindow::zoomBarAct);

How to tell when a QPushButton is clicked in a QButtonGroup

In my project, I have 40 QPushButtons all put into a QButtonGroup like this:
QButtonGroup* group = new QButtonGroup(this);
group->addButton(ui->slot_0);
group->addButton(ui->slot_1);
//...
group->addButton(ui->slot_38);
group->addButton(ui->slot_39);
Each button is a QPushButton that I made checkable. That way only one button can be checked at a time. All works great, but how can I "make a slot" when one of the buttons becomes checked? I don't want to have 40 different slots, one for each button all to end up doing essentially the same thing. Is there any way I can just use the QButtonGroup I put them in?
As Jamin and Nikos stated: you should create your own slot to handle the signal emitted by QButtonGroup. It could be something like this:
In the header file:
public slots:
void buttonWasClicked(int);
In the *.cpp file:
void MainWindow::buttonWasClicked(int buttonID)
{
cout << "You have clicked button: " << buttonID << endl;
}
And in the code responsible for creation of the MainWindow (i.e. in constructor but not necessairly) there should be this line:
connect(group, SIGNAL(buttonClicked(int)), this, SLOT(buttonWasClicked(int)));
Be aware that since Qt5 the connect syntax has changed. The syntax I used here is from Qt4. It still works but is deprecated now (for more information please refer to New Signal Slot Syntax in Qt 5). Moreover I would suggest going through QButtonGroup class reference as there are other available signals which could suit your needs better than the one I've chosen.
BR
The documentation for QButtonGroup shows a QButtonGroup::buttonClicked() signal - have you already tried that one?
The signal comes in two variants - one that gives the QPushButton as a parameter (as a QAbstractButton), and one that gives the ID of the button in the group.
You can use connect() to setup signal and slot connections in your C++ code.
Sometime during the initialization of your window's class (perhaps in the constructor), call this:
connect(myButtonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(theSlotThatYouWrite(QAbstractButton*));
Where myButtonGroup is probably this->ui->nameOfTheButtonGroup, and theSlotThatYouWrite is a function that you write in your own code, that belongs to your window's class, that returns void and takes a signal QAbstractButton* as a parameter (since that's what this specific signal gives as an argument).
Make sure theSlotThatYouWrite is under the label "private slots:" or "public slots:" in your class's interface.
Here's a screenshot of actual usage of some signals and slots in my own code.
Signals and Slots is something very important to learn, but can be bit of a hill to climb when first trying to understand it!

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.