No such slot when connecting widget signal with parent widget slot

388 views Asked by At

I have the following classes:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QStringList pluginsToStart, QWidget *parent = 0);
    ~MainWindow();

// some other stuff

public slots:
    void on_timeDataChanged(logging::TimeValueVector<bool>& aData);
    void on_importStarted();
}

and

class DataImporterWidget : public PluginWidget
{
    Q_OBJECT

public:
    explicit DataImporterWidget(QWidget *parent = 0);
    ~DataImporterWidget();

    void initConnections(QMap<QString, PluginWidget*> pluginWidgetMap);

in the method initConnections, I want the widget to init the signal-slot connections like so:

void DataImporterWidget::initConnections(QMap<QString, PluginWidget*> pluginWidgetMap)
{
    for(Importer* importer : this->getImporterMap().values())
    {
        connect(importer, SIGNAL(signal_timeDataChanged(logging::TimeValueVector<bool>&)),
            parentWidget(), SLOT(on_timeDataChanged(logging::TimeValueVector<bool>&)));
    }

    connect(this, SIGNAL(signal_importStarted()), parentWidget(), SLOT(on_importStarted()));
}

Importer is a QGroupBox and a base class for derived sub classes specifying concrete data importer types. It works like so: If I press a button, an DataImporterWidget is created and added to a QMdiArea as a QMdiSubWindow. When creating the DataImporterWidget I call the initConnections() method which sets up the signal-slot connections.

Now, when I run the program, I get the following message:

QObject::connect: No such slot 
QMdiSubWindow::on_timeDataChanged(logging::TimeValueVector<bool>&) in src/dataimporter/DataImporterWidget.cpp:81
QObject::connect: No such slot QMdiSubWindow::on_importStarted() in src/dataimporter/DataImporterWidget.cpp:85
QObject::connect:  (sender name:   'DataImporterWidget')

I do not understand why I get it because the slot is there. Even if I cast the parentWidget to the MainWindow, I get the same error.

PluginWidget is just a base class deriving from QWidget that holds some common functionality for my used plugins. I put Q_OBJECT on each base and derived class but still get this error. However, if I set up the connections in the MainWindow, it works just fine, but I wonder why the above solution won't work.

3

There are 3 answers

0
M F On BEST ANSWER

I've found the problem. The reason is, that the MainWidget class holds a QMdiArea where I add my PluginWidgets. So, when I create the PluginWidget, I set the MainWidget as its parent, but as soon as I add it to the QMdiArea, it also becomes a child of QMdiSubWindow. The parentWidget was never null but it was the wrong one ...

0
sisco_0 On

Don't create the connection from child object, instead create it from parent object code after creating the child object. This way you won't need to cast any type.

0
WindyFields On

You did not shown a huge chunk of important code (like creating DataImporterWidget, setting MainWindow as its parent, the place where you call initConnections...). However, you said

If I use the new signal slot syntax, my program crashes with a segmentation fault...

If it crashes, than you have to find a reason why. Using old signal-slot connect syntax does not cure the disease, it just delay its manifestation. According to this, the reason why you get a segfault can be parentWidget() == nullptr or parent is not initialized yet.

My advice, check your code, and make user the parent of DataImporterWidget is created and specified before your call initConnections().