Extremely stuck with passing two arguments to slot



  • Hello, so I know that I cant pass an argument directly through the slot() parameter, but I cant figure out how.

    I have one button that i wish to pass different parameters to on different checks

    so if listwidgetitem = 0 is selected then pass ("fileprocess", "c:\google.com") to the slot function

    I looked at signalmapper but that only takes 1 argument per button, i looked at emitting the signal in a different function, but that meant that i cant change the parameters.

    Whats a good way of doing this.



  • @davethedave

    Hi and welcome to devnet forum

    How many arguments has your signal?

    If a signal has only one argument, Qt cannot imagine what the second argument shall be. Therefore it has to be static, which means that you can rewrite your slot for only one argument and set the static value internally.

    Those are some simple thoughts to go through before using some of the more sophisticated methods for signal-slot connections with default arguments



  • @koahnig said in Extremely stuck with passing two arguments to slot:

    @davethedave

    Hi and welcome to devnet forum

    How many arguments has your signal?

    If a signal has only one argument, Qt cannot imagine what the second argument shall be. Therefore it has to be static, which means that you can rewrite your slot for only one argument and set the static value internally.

    Those are some simple thoughts to go through before using some of the more sophisticated methods for signal-slot connections with default arguments

    void Loader::onInject(const wchar_t * proc, const char * path)
    {
    load(proc, path);
    }

    I need to feed onInject a process and a path depending on the users choice
    my signal has 0 arguments
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(onInject(const wchar_t*,const char*)));

    And to even further explain
    if (listwidgetitem = 0)
    {
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(onInject("test.exe", "test.dll")));
    }

    if (listwidgetitem = 2)
    {
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(onInject("test2.exe", "test2.dll")));
    }



  • @davethedave

    One simple way is using an additional slot in Loader to collect the required information.

    Respectively change you slot to

    void Loader::onInject()
    {
    // some additional code is required to collect the information.
    load(proc, path);
    }
    

    Is it fixed where the required information may be found?
    You can somehow combine this with QSignalMapper for instance. This may allow to make it more dynamic, but also more complicated.



  • @koahnig

    Hmm not quite sure how you're thinking, how could i collect the information. Perhaps if i could check the current list item and connect the same function to a pushbutton click then i may have an idea, but not sure how to go about that.



  • Hi @davethedave

    This is a situation, where I would suggest the use of lambdas. As long as the number of different arguments is reasonable small, and you're not bound to Qt4 or lower.

     if (listwidgetitem = 0) {
        connect(ui->pushButton, &QPushButton::clicked, this, [=]{onInject("test.exe", "test.dll");});
    } else if (listwidgetitem = 2) {
        connect(ui->pushButton, &QPushButton::clicked, this, [=]{onInject("test2.exe", "test2.dll");});
    }
    

    I hope this is code is somewhere in a setup function of some kind, otherwise you'll end up with multiple calls of onInject

    the this as 2nd object is technically (here) not needed, but it doesn't hurt either.



  • @J.Hilk said in Extremely stuck with passing two arguments to slot:

    connect(ui->pushButton, &QPushButton::clicked, this, [=]{onInject("test.exe", "test.dll");});

    Hmm i seem to be experiencing the multiple calls thing you were talking about

    it works perfectly however i tried incorporating things like
    connect(ui->pushButton, &QPushButton::clicked, this, [=]{QMessageBox::information(this, "Test", "unavailable!");});

    on some other list items, and multiple messages are showing even though the call doesnt below to the list item, what do you mean exactly and how can i fix this



  • @davethedave
    well,
    QObject:connects will presist as long as your program runs, one of the objects (sender or receiver) is destroyed you manually call disconnect or, Qt::UniqueConnection is passed as 5th parameter.

    One usally places all connect statements therefore in the constructor of the class or by the construction of the QObject (when manually creating objects via new).

    The `listwidgetitem´ dependency of your code example let me to believe that the code is actually inside a normal function and may be called multiple times .

    You'll have to manage that better. Qt::UniqueConnection could be a solution here, but I don't have much experience with that one.

    Can you show more of your actually code, that meight help.


    Edit:
    you could do something like this (untested):

    //member variable, part of the header file.
    QMetaObject::Connection oldConnction;
    
    //...
    if (listwidgetitem = 0) {
       if(oldConnection)
             disconnect(oldConnection);
         oldConnction = connect(ui->pushButton, &QPushButton::clicked, this, [=]{onInject("test.exe", "test.dll");});
    } else if (listwidgetitem = 2) {
        if(oldConnection)
            disconnect(oldConnection);
        oldConnction = connect(ui->pushButton, &QPushButton::clicked, this, [=]{onInject("test2.exe", "test2.dll");});
    }
    

    if this works, than it's a bandaid and I would seriously suggest a redesign!!



  • @J.Hilk

    Thank you so much! your solution works perfectly!

    What an amazing helpdesk


Log in to reply
 

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