1

can someone tell me how exactly signals with parameters work? I mean... if i have declared signal f.e.:

void sign1(int)

how should i specify what integer i want to send with that signal? Also, can i declare signal with multiple arguments? Like:

void sign2(int, int)

And again... i want to send with sign2 two out of four variables that i have. Is that possible, and how it should be done? To specify my question below is a little more detailed example:

class Board
{
  signals: 
    void clicked(int, int);
  private:
    int x1{4}; int x2{4}; int x3{5}; int x4{8};
}

and there is board.ui file with pushbutton. After pushbutton is clicked i want to send to the slot for example x1 and x3. Example:

connect(ui->button, SIGNAL(clicked(int, int)), obj2, slot2); 

I hope that it's somehow clear. I will really appreciate your help.

Tojmak
  • 99
  • 5
  • The problem is the button clicked signal does not have this signature. [https://doc.qt.io/qt-5/qabstractbutton.html#clicked](https://doc.qt.io/qt-5/qabstractbutton.html#clicked) – drescherjm Oct 15 '20 at 16:51
  • You could could have a slot in Board that calls `emit clicked( val1, val2)` but I am not sure how you want to get the values to emit do you have a 2d array of buttons? – drescherjm Oct 15 '20 at 16:55
  • Yeah, but cannot i declare my own signals? – Tojmak Oct 15 '20 at 16:57
  • Yes you can define your own signals but the values for the parameters have to come from somewhere. It does not make sense to directly connect a clicked (bool) to clicked(int,int) – drescherjm Oct 15 '20 at 16:58
  • You may want [https://doc.qt.io/qt-5/qsignalmapper.html](https://doc.qt.io/qt-5/qsignalmapper.html) – drescherjm Oct 15 '20 at 17:00
  • but why should i use clicked(bool)? So it's not possible to combine signal's parameters with variables defined in my class? – Tojmak Oct 15 '20 at 17:02
  • Because that is the signature of the clicked signal that the button emits. – drescherjm Oct 15 '20 at 17:03
  • QSignalMapper is probably what you need. – drescherjm Oct 15 '20 at 17:03
  • and that has to be emitted? I mean, i thought that i can redefine signal that button may emits, I wanted to use clicked(int, int) which somehow i will provide in place of clicked(bool) – Tojmak Oct 15 '20 at 17:09

2 Answers2

2

QObject::connect() works like this (in the general case, not using lambda):

connect(obj1, obj1_signal, obj2, ob2_slot)

Since there is no signal clicked(int, int) in the class QPushButton (which I assume you are using), it cannot be use for the connection.

If you want to have the signal clicked(int, int) in a button, you can subclass QPushButton, add the signal, and using emit to send the signal where the click event is handled.

However, that is not a good design, since you will have to store a Board object (or at least a reference to it) in the button class, which is irrelevant to the class.
Instead, you can have a slot Board::buttonClicked(), connected to QPushButton::clicked(bool). Then in that slot, you can do emit Board::clicked(int, int).

Ngoc Minh Nguyen
  • 1,113
  • 1
  • 5
  • 13
1

The rule for signal/slot connection may be formulated as the following:

You can ignore signal arguments, and you cannot create slot arguments from nothing

What does it mean? If your signal has an argument, your slot shall have at most an argument also. See tabular below.

enter image description here

  • On first line, you have a signal with two arguments, thus, your slot can have two arguments (using all the signal arguments), or one argument (ignoring one argument of the signal) or no argument (ignoring both signal arguments)

  • On the second line, you have a signal valueChanged(int) with one argument. Your slot may have one or no argument (ignoring the signal argument) but may not have two or more arguments as you cannot create values.

  • On the third line the signal textChanged(QString) cannot be connected with setValue(int) because we cannot create an int value from from QString.

  • The fourth line follow these rules. If the signal has no argument, the connected signal cannot create new arguments, thus update() is correct, setValue(int) isn't.

  • Another point that shall be looked at is overloading of signal/slots. It is the case where many signals/slots with the same name but with different numers or different types of arguments. You may have the class QLCDNumber, where the slot display has many overload. In this cas, you have to explicitly defined which pair of signals slots, you would like to use as explained here

You can try out the following example:

Example :



#include <QtWidgets>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget *window = new QWidget();
    window->setAttribute(Qt::WA_DeleteOnClose);
    QVBoxLayout *topLayout = new QVBoxLayout(window);

    //Set up of GUI
    QSlider *slider = new QSlider(Qt::Horizontal);
    slider->setRange(0, 100);

    QSpinBox *spin = new QSpinBox;
    spin->setReadOnly( true );

    QHBoxLayout *horizontalLayout = new QHBoxLayout;
    horizontalLayout->addWidget(slider);
    horizontalLayout->addWidget(spin);
    topLayout->addLayout(horizontalLayout);

    // using pointer to member function
    QObject::connect(slider, &QSlider::valueChanged,
                     spin, &QSpinBox::setValue);
    // set the slider position and hence the QSpinBox value too
    slider->setValue(40);

    // Uncommenting the following connect will result in a compile time error.
    // The signal passes no arguments whereas the slot is expecting a single
    // argument.
    // By using function pointers we get compile time parameter list checking.
    // Using the old-style SIGNAL/SLOT macros this would have been detected
    // as a run time warning only.
    //QObject::connect(slider, &QSlider::sliderPressed,
    //                 spin, &QSpinBox::setValue);

    QTextEdit *textEdit = new QTextEdit();
    textEdit->setAttribute(Qt::WA_DeleteOnClose);

    // Uncommenting the following connect will result in a compile time error.
    // The signal is passing an incompatible parameter to the slot.
    // By using function pointers we get compile time parameter type conversion.
    // Using the old-style SIGNAL/SLOT macros this would have been detected
    // as a run time warning only.
    //QObject::connect(slider, &QSlider::sliderMoved,
    //                 textEdit, &QTextEdit::setFontFamily);

    window->show();
    return app.exec();
}
Pat. ANDRIA
  • 1,858
  • 1
  • 9
  • 20