継承

2016-06-22 10 views
3

このコード:継承

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を実行しますが、今回は動作しませんでした。ここで

は、クラスの宣言です:public slots:に宣言を変更

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

は、任意の違いはありませんでした。

+0

ヒント:Qt Creatorのオートコンプリートを使用して、SIGNALおよびSLOTマクロを記入してください。それが拒否すれば、どこかに問題があります。オートコンプリートを行うと、誤植の可能性を避けることができます。 – hyde

答えて

1

私はあなたがやろうとしているもので、ここで問題があると思う:

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

QCPAxisなくMyAxisクラスを返します。

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

私はそれが動作することができますどのように表示されていない:QCPAxizはメモリの100のバイトを取り、MyAxisが、あなたはこれをやろうとしている110バイトを取ると言うことができます。呼んでいる関数はQCPAxisを返すので、同じ基本クラスを共有しているという理由だけでMyAxisに変換することはできません...そのフォード・フィエスタを持っているようなものです。「今はフェラーリです"彼らは同じ基本型の"車 "を持っているからです。私はあなたが非定義された行動にあると思いますので、現時点では

...

それはあなたがやろうとしていることは何ですか? QCPAxisの値をMyAxisにコピーすることができます(コピーコンストラクタを使用してください)。

+0

いいえ、それは問題ではありません(それは、Qt5でも依然としてconnect-by-nameが有効な理由の一部です)。 'connect()'はランタイムメタオブジェクトを使って 'ax'のスロットを検索します。実際の問題は 'SLOT'マクロが' SLOT(MyAxis :: rescale(QCPRange)) 'の代わりに 'SLOT(rescale(QCPRange))'のような*修飾されていない*メソッド名を必要とすることです。 –

+1

いいえ、私は間違っています。それが問題だ!単純にキャスト( 'static_cast <>()'、ugh!)は、あるオブジェクトを別のオブジェクトにしません。 Krzysztofが 'qobject_cast <>()'を使用していた場合、彼の間違いはもっと明らかになりました。私は間違って書かれた 'SLOT()'マクロが、問題に対する試行錯誤の修正の一部であったと推測しています... –

+0

@TobySpeight ...私はあなた自身と議論するために+1を与えなければなりません: ))、はい私は最初の質問が "赤いニシン"だったと思います。 –

1

既存の軸をMyAxis*にキャストすることはできません。将来のために

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

ヒント:チェック代替(ここでは、qobject_cast<>()、そうでない場合dynamic_cast<>())がありますどこstatic_cast<>()を避ける新しいMyAxisをインスタンス化し、グラフにそれを割り当てる必要があります。それは無効な仮定を特定するのに役立ちます。

1

Qtには、QObjectから継承するクラスに関するいくつかのメタ情報が保存されています。これらの情報の1つは、クラスのスロットです。オブジェクトを静的にキャストすると、これらのメタ情報はキャストで更新されないため、キャストされたオブジェクトのメタ情報には、MyAxisクラスで実装したスロットは含まれません。そのため、ランタイムにシグナルをキャストされたオブジェクトに接続することができません。 MyAxisクラスの仮想スロットを再実装しても、オブジェクトを静的にキャストすることによって、新しいキャストオブジェクトのスロットが古いスロットにポイントし、再実装されたオブジェクトを指すようにアップグレードしません。

更新: qobject_cast(Qtオブジェクトの安全なキャスト方法)を使用すると、キャストされたオブジェクトがNULLであることがわかります。

+1

'static_cast'を' qobject_cast'に置き換えることは良い考えですが、コードを動作させることはありません。それは問題を診断可能にし、ヌルポインタを与えることで間違いなく推奨されますが、問題は参照対象が「MyAxis」ではないことです。 –

-1
  1. はQtののMOC-発電機は、非常に制限的である:H-FILESの文が欠落しているの一つで

    connect(..., SLOT(...(const QCPRange &))); 
    
  2. Q_DECLARE_METATYPE(QCPRange) 
    
  3. ので、同じ 署名を書きます
+2

Qt 4接続構文を使用するときは、正規化スロットシグネチャを使用してください。したがって、 'connect(...、SLOT(...(QCPRange)));'。 'const'と'& 'は冗長です:' connect'から呼び出される署名正規化子は、それをとにかく削除します。 –