Passing another variable to a SLOT in QObject::connect



  • Suppose there are two widgets, a QPushButton and a QLabel
    How can I write the connecting code, so that when the button is pressed down, a specific string is displayed in the Label?
    @QObject::connect(....,SIGNAL(pressed(),......,SLOT(setText("My String"))); @
    shows an error...
    If I put:
    @QObject::connect(....,SIGNAL(pressed(),......,SLOT(setText(QString)));@
    where would the value for the string come from?
    ...I am just starting to learn using Qt...



  • Both statements are invalid.

    In short:

    • connect() wants only the SIGNATURE of the signal/slot (without the return type), not the argument names, nor anything else;
    • a slot cannot have more arguments than the ones carried by the signal you're connecting to it (where should they come from?);
    • passing values inside connect() is an error, although it's pretty clear what you'd like to do;
    • simply use a "proxy" slot that calls the target slot with the arguments, or read the docs about QSignalMapper.


  • bq. simply use a “proxy” slot that calls the target slot with the arguments....

    How do I do that?



  • @
    //...
    connect(button, SIGNAL(pressed)), SLOT(handleButtonPress()));
    //...

    void MyClass::handleButtonPress()
    {
    someLabel->setText("My String");
    }@



  • In your (very simple) case, if it's applicable, you can just provide a default argument for the slot. Otherwise, simply create another slot that calls the setText one with the string you want.



  • [quote author="peppe" date="1297240228"]In your (very simple) case, if it's applicable, you can just provide a default argument for the slot. Otherwise, simply create another slot that calls the setText one with the string you want.[/quote]Indeed. With a slot called setText(), providing a default argument can be misleading:

    @myLabel->setText();@

    What does that do?

    Oh well. It's a style issue.



  • bq. Otherwise, simply create another slot that calls the setText one with the string you want.

    Any way without creating whole new classes?


  • Moderators

    "QSignalMapper":http://doc.qt.nokia.com/4.7/qsignalmapper.html might also be an option.



  • to solve simple problem like yours I use this solution:
    @
    connect(button1, SIGNAL(clicked()), SLOT(buttonClicked());
    connect(button2, SIGNAL(clicked()), SLOT(buttonClicked());
    button1->setProperty("name", "button1");
    button2->setProperty("name", "button2");
    ...
    ...
    MyClass::buttonClicked()
    {
    QPushButton *button = sender();
    if(button->property("name").toString() == "button1")
    {
    .....
    .....
    }
    else if(button->property("name").toString() == "button2")
    {
    ....
    ....
    }
    }
    @



  • Luca, that is unsave code.

    You don't know what kind of object sender() refers to, or if it is non-0 at all (direct call to buttonClicked()). So, you should at least check that before assuming this. Using a QSignalMapper is the safe way to go, and it still allows other ways to trigger the slot and still work correctly.



  • Safe or not safe, it's arguably not even simpler than the QSignalMapper approach. Likewise, if a slot is going to make (significant) behavioral changes based on the sender(), then it is probably time to review the design anyway.



  • [quote author="Andre" date="1297288071"]Luca, that is unsave code.

    You don't know what kind of object sender() refers to, or if it is non-0 at all (direct call to buttonClicked()). So, you should at least check that before assuming this. Using a QSignalMapper is the safe way to go, and it still allows other ways to trigger the slot and still work correctly.
    [/quote]
    Yes, I usually check if pointer is a push button with a dynamic_cast:
    @
    QPushButton button = dynamic_cast<QPushButton>(sender());
    if(button==NULL)
    {
    return;
    }
    @

    Mine is only a fast example...



  • qobject_cast might be more thorough.



  • Hi there is a tool which do exactly what you need.
    See "QSignalMapper":http://doc.trolltech.com/latest/qsignalmapper.html
    There is good example how to use it.



  • If you're in the same class (or have access to the possible sender objects pointers) you simply can compare pointers:

    @
    void MyClass::buttonClicked()
    {
    if(sender() == button1) {
    // ....
    } else if(sender() == button2) {
    // ....
    }
    }
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.