2016-06-22 16 views
3

Этого код: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: No such slot QCPAxis::MyAxis::rescale(QCPRange) in 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: не имеет никакого значения.

+0

Подсказка: используйте автозаполнение Qt Creator, чтобы заполнить макросы SIGNAL и SLOT. Если он откажется, есть проблема где-то. Если это автозаполнение, вы избегаете возможных ошибок. – hyde

ответ

1

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

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 (с помощью конструктора копирования - я думаю, вам нужно одно из них)

+0

Нет, это не проблема (и это связано с тем, что соединение по имени по-прежнему полезно даже в Qt5). 'connect()' будет использовать метаобъект времени выполнения для поиска слотов 'ax'. Реальная проблема заключается в том, что для макроса 'SLOT' требуется имя метода * unqualified *, т. Е.' SLOT (rescale (QCPRange)) 'вместо' SLOT (MyAxis :: rescale (QCPRange)) '. –

+1

Нет, я ошибаюсь; это проблема! Простое литье (с 'static_cast <>()', ugh!) Не превращает один объект в другой. Если бы Krzysztof использовал 'qobject_cast <>()', его ошибка была бы более очевидной. Я предполагаю, что неправильно написанный макрос «SLOT()» был частью пробной ошибки «ошибка» для проблемы ... –

+0

@TobySpeight ... Я должен дать вам +1 за то, что вы спорили с самим собой:)), да, согласен Я думаю, что первым вопросом была «красная селедка» –

1

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

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

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

1

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

UPDATE: Используя qobject_cast (который является безопасным способом для объектов Qt), вы можете видеть, что он литой объект NULL.

+1

Замена 'static_cast' на' qobject_cast' - хорошая идея, но это не заставит код работать. Это сделает проблему диагностируемой, указав нулевой указатель, поэтому это определенно целесообразно, но проблема в том, что референт не является «MyAxis» - ему нужно разобраться в этом. –

-1
  1. МПЦ-генератор Qt очень ограничительно: так писать с той же подписью:

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

    Q_DECLARE_METATYPE(QCPRange) 
    
+2

При использовании синтаксиса Qt 4 connect предпочитайте нормализованные сигнатуры слотов. Таким образом, 'connect (..., SLOT (... (QCPRange)));'. 'Const' и' & 'являются избыточными: нормализатор подписи, вызываемый из' connect', все равно удалит их. –

 Смежные вопросы

  • Нет связанных вопросов^_^