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.
Moc-генератор Qt очень ограничен: пишите с той же сигнатурой:
connect(..., SLOT(...(const QCPRange &)));
В одном из h-файлов отсутствует утверждение:
Q_DECLARE_METATYPE(QCPRange)