Qt: QObject::connect: No such slot
Asked Answered
E

1

1

I am building a small interface where I subclassed RViz which is a visualizer from ROS. According to the official documentation it is possible to re-use and re-implement some of the functions present in this tool. What I am trying to do is creating two different QPushButton that will chnage the view of the renderer implemented. I have some problems with the SIGNAL ans SLOT for my two buttons, in fact as I click them, the view doesn't change. Now RViz has a specific function called getNumViews() that allows the user to set the number of views. In my case I have two views only related to the two QPushButton I am implementing.

sig-slot

As I run the application program I receive the following error QObject::connect: No such slot MyViz::switchToView() and thought that all the passages to correctly set the SIGNALS and SLOT were correctly according to the official documentation. Also for completeness I am using C++11 and from researching more I found that the old version of the SIGNAL and SLOT, which is the one I am using is supposed to be still valid.

Below the code related to the SIGNAL and SLOT that I am running:

myviz.h

public Q_SLOTS:
    void switchToView(QString view);

private:
    rviz::ViewManager *view_man;

myviz.cpp

MyViz::MyViz(QWidget *parent) : QWidget(parent)
{

// operation in the constructor

    QPushButton *topViewBtn = new QPushButton("Top View");
    QPushButton *sideViewBtn = new QPushButton("Side View");


    connect(topViewBtn, SIGNAL(clicked()), this, SLOT(switchToView(QString("Top View"))));
    connect(sideViewBtn, SIGNAL(clicked()), this, SLOT(switchToView(QString("Side View"))));

}

here is where I set the 2 views possibilities related to the two QPushButtons

void MyViz::switchToView(QString view)
{
    view_man = manager->getViewManager();
    for(int i = 0; i<view_man->getNumViews(); i++)
    {
        if(view_man->getViewAt(i)->getName() == view)
            view_man->setCurrentFrom(view_man->getViewAt(i));
                    return;
        std::cout<<"Did not find view named %s"<<std::endl;
    }
}

Thank you for pointing in the right direction for solving this issue.

Elamitic answered 15/6, 2019 at 16:8 Comment(0)
S
2

You cannot pass arguments in the connect function using the old syntax. Also the number and type of arguments need to match, so you can only connect clicked to functions without arguments. If you want to use the old syntax, you need to define 2 slots

public Q_SLOTS:
    void switchToTopView();
    void switchToSideView();

which you can then connect via:

connect(topViewBtn, SIGNAL(clicked()), this, SLOT(switchToTopView()));
connect(sideViewBtn, SIGNAL(clicked()), this, SLOT(switchToSideView()));

edit:

The correct syntax for new connect method is:

connect( topViewBtn, &QPushButton::clicked, this, &MyViz::switchToTopView);

The advantage of this method is that you can also bind to lambdas, which indirectly lets you set parameters during connect, so you could write

connect( topViewBtn, &QPushButton::clicked, [this](){
    switchToView( QString("Top View") );
});
Skirret answered 15/6, 2019 at 16:18 Comment(1)
Thanks for the explanation Thomas. Could you update your answer also in case I will need to use the new notation please?Elamitic

© 2022 - 2024 — McMap. All rights reserved.