简体   繁体   中英

c++/ qt - no such slot - Inheritance

This code:

MyAxis *ax;
ax = static_cast<MyAxis*>(ui->customPlot->axisRect()->addAxis(QCPAxis::atLeft));
connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)),
        ax, SLOT(MyAxis::rescale(QCPRange)));

gives me this run-time error:

QObject::connect: No such slot QCPAxis::MyAxis::rescale(QCPRange) in plotwindow.cpp:267

Usually when I get errors like this, I add Q_OBJECT macro to class and run qmake to fix it, but that didn't work this time.

Here is the declaration of the class:

class MyAxis : public QCPAxis
{
    Q_OBJECT
public:
    void setRefAxis(QCPAxis *refAxis);
    void setScale(double newScale);


public Q_SLOTS:
    virtual void rescale(const QCPRange &range);

private:
    double scale;
    QCPAxis *ref;
};

Changing the declaration to public slots: didn't make any difference.

I think you have a problem here in what you are trying to do:

ui->customPlot->axisRect()->addAxis(QCPAxis::atLeft)

returns a QCPAxis and not a MyAxis class. Lets say QCPAxiz takes 100 bytes of memory and MyAxis takes 110 bytes then you are trying to do this:

A_110_Byte_Type* p110Bytes = static_cast<110-bytes *> (<100-bytes>); // not real code!

I don't see how that can work. The function you are calling returns a QCPAxis and you can't just convert it into a MyAxis just because they share the same base class... its a bit like have a having a Ford-Fiesta and saying, "now it is a Ferrari" just because they have the same base type of "car".

So at the moment I think you are into un-defined behavior...

What is it that you are trying to do? - you can copy the values of the QCPAxis into your MyAxis (with a copy constructor - I think you need one of those to do this)

You can't just cast the existing axis to a MyAxis* . You need to instantiate a new MyAxis and assign that to the graph:

QCPGraph *graph = new QCPGraph(this);
MyAxis *ax = new MyAxis(graph);
graph->setValueAxis(ax);
connect(...);

Tip for future: avoid static_cast<>() where there's a checking alternative (here, qobject_cast<>() , otherwise dynamic_cast<>() ). That will help identify invalid assumptions.

Qt stores some meta information about classes that inherit from QObject . One of these information is the slots of the class. By static casting an object these meta information doesn't update in cast, so your casted object's meta information doesn't contain the slot you implemented in your MyAxis class. that's why it can't connect the signal to the casted object at runtime. Even if you reimplement a virtual slot in your MyAxis class, by static casting your object new casted object's slot points to the old slot and doesn't upgrade to point to the reimplemented one.

UPDATE: By using qobject_cast (which is the safe cast way for Qt objects) you can see that it the casted object is NULL.

  1. The moc-generator of Qt is very restrictive: so write with the same signature:

     connect(..., SLOT(...(const QCPRange &))); 
  2. In one of the h-files a statement is missing:

      Q_DECLARE_METATYPE(QCPRange) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM