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:로 선언 변경 : 여기

클래스의 선언이다.

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

QCPAxis 아닌 MyAxis 클래스를 반환

+0

힌트 : Qt Creator 자동 완성을 사용하여 SIGNAL 및 SLOT 매크로를 채 웁니다. 그것이 거절하면, 어딘가에 문제가 있습니다. 자동 완성 기능을 사용하면 잠재적 인 오타를 피할 수 있습니다. – hyde

답변

1

나는 당신이 여기 당신이 뭘 하려는지에 문제가있다 생각합니다. QCPAxiz는 100 바이트의 메모리를 소요하고 MyAxis는이 작업을 수행하려고 다음 110 바이트를 취 말할 수 : 나는 그 일을 할 수있는 방법이 표시되지 않습니다

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

. 당신이 호출하고있는 함수는 QCPAxis를 반환하며, 같은 기본 클래스를 공유하기 때문에 그냥 MyAxis로 변환 할 수 없습니다 ... 포드 - 피에스타 (Phord-Fiesta)를 가지고 있고 "이제는 페라리입니다. "그들은 같은 기본 유형의"자동차 "를 가지고 있기 때문에. 내가 생각하는 순간에 따라서

이되지 않은 정의의 행동에 있습니다 ...

은 당신이하려고하는 것이 무엇입니까? - QCPAxis의 값을 MyAxis에 복사 할 수 있습니다 (복사 생성자를 사용하면이 작업 중 하나가 필요합니다)

+0

아니요, 문제가 아닙니다. (그리고 Qt5에서도 여전히 연결 이름이 유용합니다.) 'connect()'는 실행 시간 메타 객체를 사용하여'ax'의 슬롯을 검색합니다. 진짜 문제는'SLOT' 매크로가'SLOT (MyAxis :: rescale (QCPRange)) '대신에'SLOT (rescale (QCPRange))'와 같은 * 수식어가 아닌 * 메소드 이름을 필요로한다는 것입니다. –

+1

아니요, 틀렸어. 그게 문제 야! 간단히 캐스팅 ('static_cast <>()', 우!)은 한 객체를 다른 객체로 만들지 않습니다. Krzysztof가'qobject_cast <>()'를 사용했다면, 그의 실수는 더욱 분명 해졌을 것입니다. 나는 잘못 쓰여진'SLOT()'매크로가 문제에 대한 시행 착오의 '수정'의 일부라고 추측하고있다. –

+0

@TobySpeight ... 너 자신과 논쟁하기 위해 +1해야한다 :)) 그렇습니다. 첫 번째 질문은 "청어 청어"라고 생각합니다. –

1

기존 축을 MyAxis*으로 전송할 수는 없습니다.

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

팁을 미래 : 새 MyAxis를 인스턴스화하고 그래프에 그를 할당해야합니다 (그렇지 않으면 dynamic_cast<>() 여기, qobject_cast<>())를 검사 대안이 어디 static_cast<>()을 피하십시오. 이는 잘못된 가정을 확인하는 데 도움이됩니다.

1

Qt는 QObject에서 상속받은 클래스에 대한 일부 메타 정보를 저장합니다. 이 정보 중 하나는 클래스의 슬롯입니다. 객체를 정적으로 캐스팅하면 이러한 메타 정보가 캐스트로 업데이트되지 않으므로 casted 객체의 메타 정보에는 MyAxis 클래스에 구현 한 슬롯이 포함되지 않습니다. 그래서 런타임에 신호를 캐스트 된 객체에 연결할 수 없습니다. MyAxis 클래스의 가상 슬롯을 다시 구현하더라도 객체를 정적으로 형 변환하여 새 casted 객체의 슬롯이 이전 슬롯을 가리키고 다시 구현되지 않은 슬롯을 가리 키도록 업그레이드하지 않습니다.

업데이트 : qobject_cast (Qt 개체의 안전한 캐스트 방법)을 사용하면 캐스팅 된 개체가 NULL임을 알 수 있습니다.

+1

'static_cast'를'qobject_cast'로 대체하는 것은 좋은 생각이지만 코드가 작동하지는 않습니다. 그것은 문제를 진단 할 수 있도록 null 포인터를줌으로써 가능할 것이므로 확실히 권고 할 만하다. 그러나 문제는 지시 대상이 MyAxis가 아니라는 것이다. –

-1
  1. Qt를의 MOC-발생기는 매우 제한적인 경우 : H-파일 진술이없는 한에서

    connect(..., SLOT(...(const QCPRange &))); 
    
  2. :

    Q_DECLARE_METATYPE(QCPRange) 
    
  3. 그래서 같은 서명 쓰기
+2

Qt 4 연결 구문을 사용할 때는 정규화 된 슬롯 서명을 사용하십시오. 그러므로'connect (..., SLOT (... (QCPRange)));'. 'const'와'&'는 중복되어 있습니다 :'connect'에서 호출 된 서명 정규화 기는 어쨌든 그것을 제거 할 것입니다. –