C++/ qt - нет такого слота - Наследование

Этот код:

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

дает мне эту ошибку во время выполнения:

QObject:: connect: такого слота нет QCPAxis::MyAxis::rescale(QCPRange) в plotwindow.cpp:267

Обычно, когда я получаю такие ошибки, я добавляю Q_OBJECT макрос в класс и запустить qmake чтобы исправить это, но на этот раз это не сработало.

Вот объявление класса:

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;
};

Изменение декларации на public slots: не имеет никакого значения.

4 ответа

Я думаю, что у вас есть проблема в том, что вы пытаетесь сделать:

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

возвращает QCPAxis и не MyAxis учебный класс. Допустим, QCPAxiz занимает 100 байтов памяти, а MyAxis - 110 байтов, тогда вы пытаетесь сделать это:

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

Я не понимаю, как это может работать. Функция, которую вы вызываете, возвращает QCPAxis, и вы не можете просто преобразовать его в MyAxis только потому, что они имеют один и тот же базовый класс... это немного похоже на то, что у вас есть Ford-Fiesta и говорят: "Теперь это Ferrari". "Просто потому, что они имеют один и тот же базовый тип" автомобиля ".

Так что на данный момент я думаю, что вы в неопределенном поведении...

Что вы пытаетесь сделать? - вы можете скопировать значения QCPAxis в свой MyAxis (с помощью конструктора копирования - я думаю, вам нужен один из них, чтобы сделать это)

Вы не можете просто привести существующую ось к MyAxis*, Вам нужно создать новый экземпляр MyAxis и назначьте это на график:

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

Совет на будущее: избегать static_cast<>() где есть альтернатива проверки (здесь, qobject_cast<>(), иначе dynamic_cast<>()). Это поможет определить неверные предположения.

Qt хранит некоторую мета-информацию о классах, которые наследуются от QObject, Одной из этих сведений являются слоты класса. При статическом приведении объекта эти метаинформации не обновляются при приведении, поэтому метаинформация вашего приведенного объекта не содержит слота, который вы реализовали в своем MyAxis учебный класс. Вот почему он не может подключить сигнал к объекту во время выполнения. Даже если вы переопределите виртуальный слот в вашем MyAxis Класс, путем статического приведения вашего объекта новый слот брошенного объекта указывает на старый слот и не обновляется, чтобы указывать на повторно реализованный.

ОБНОВЛЕНИЕ: с помощью qobject_cast (это безопасный способ приведения объектов Qt), вы можете видеть, что приведенный объект имеет значение NULL.

  1. Moc-генератор Qt очень ограничен: пишите с той же сигнатурой:

    connect(..., SLOT(...(const QCPRange &)));
    
  2. В одном из h-файлов отсутствует утверждение:

        Q_DECLARE_METATYPE(QCPRange)
    
Другие вопросы по тегам