2012-04-15 6 views
0

私のアプリケーションでは、私はmouseReleaseEvent()を確認してから、マウスがイベントを処理する位置にアイテムを伝えています。QGraphicsViewを再実装しました。Qtアプリケーションに奇妙なバグがあります

私の見解ではQGraphicsItemsの2つのうちどれがクリックされているか(またはボタンがリリースされているか)を確認し、それぞれのイベントを処理します。

私のウィジェットのコンストラクタでは、項目がリリースを検出したときと同じ方法を使用して、デフォルトで選択された項目の1つを設定します。

私がデバッグしたとき、LabelItemの場合、selectはコンストラクタで問題なく呼び出されました(そして、アプリケーションを最初に起動したときの結果は明らかです)。しかし、アイテムをクリックすると、アプリケーションは終了します。私はselect関数に入っているのを見ましたが、それを残していませんでした。だから問題はここにある。

これは非常に奇妙です。なぜなら、select関数は単なる1行のセッターであるからです。

void LabelItem::select() 
{ 
    selected = true; 
} 

これはです。

void LayerView::mouseReleaseEvent(QMouseEvent *event) 
{ 
    LayerItem *l; 

    if(event->button() == Qt::LeftButton) 
    {   
     l = (LayerItem *) itemAt(event->pos()); 

     if(l->inLabel(event->pos()))  
     {         //No problem upto this point, if label is clicked on 
      l->setSelection(true);  //in setSelection, I call select() or unselect() of LabelItem, 
              //which is a child of LayerItem, and the problem is there. 
              //In the constructor for my main widget, I use setSelection 
              //for the bottom most LayerItem, and have no issues. 
      emit selected(l->getId()); 
     } 
      else if(l->inCheckBox(event->pos())) 
     { 
      bool t = l->toggleCheckState(); 
      emit toggled(l->getId(), t); 
     } 
    } 
} 

私が関数内でラインをコメントアウトしたとき、私はエラーを起こさなかった。他のQGraphicsItem、CheckBoxItemのデバッグはしていませんが、アプリケーションはそのイベントに対しても終了します。問題は関連していると思われるので、今はselectに集中しています。

私はこれを引き起こした可能性があり、なぜこれが起こっているのかについては何の手がかりもありません。私の過去の経験から、私はそれが私が馬鹿げた考えをしていない単純なものだとはかなり確信していますが、私は何が分かりません。

ヘルプは本当に感謝します。

+0

'mouseReleaseEvent()'関数のコードを表示できますか? – alexisdm

+0

nullまたは無効な 'this'ポインタを逆参照しようとすると、この動作は起こります。つまり、ヌルまたは無効なオブジェクトに対して 'select'を呼び出すことができ、代入で' this'を逆参照することができます。 – Lol4t0

答えて

1

LabelItemLayerItemの上にある場合は、マウスの下に最上位のアイテムですので、itemAtは、最も可能性の高いLabelItemを返します。 LabelIteml->setAcceptedMouseButtons(0)でマウスボタンを受け入れないように設定されていない限り、

qgraphicsitem_castを使用してアイテムの種類をテストしてみてください。各派生クラスは、タイプを識別できるようにキャスト関数に別個の値を返すように、QGraphicsItem::type()を再定義する必要があります。あなたはまた、彼らのQGraphicsItem::mouseReleaseEvent()方法を再定義することにより、アイテムそのものでクリックを扱うことができる

、それは邪悪なキャストの必要性を除去するであろうが、あなたは機能LayerView::mouseReleaseEvent()を削除するか、または少なくとも基本クラスの実装をリコールする必要があり、QGraphicsView::mouseReleaseEvent()へアイテムがイベントを受信できるようにします。

+0

それは働いた! 'QGraphicsView'が' QGraphicsItem'とどのようにやりとりをしているのか理解できず、単に私が追加したアイテム、 'LayerItem'を取得すると仮定しました。しかし、私が得ていたアイテムは実際には 'LabelItem'でした。私はドキュメントをもっと徹底的に読むべきだということを示しています。あなたの助けをありがとう! – Rikonator

0

私はこれらの奇妙な振る舞いを見てきました。それは主にバイナリの非互換性でした.C++側は正しく見え、クラッシュは意味をなさないものです。あなたの言うとおり:あなたのコードでは、 "選択された"変数は原因ではありません。宣言を変更して、リンクされたすべてのオブジェクトを再コンパイルするのを忘れた可能性があります。すべてのオブジェクトファイルをきれいにして再コンパイルするだけです。ケースの99%で私のために働いた。

+0

私はソースから完全に再構築しましたが、同じ問題が発生します。コメントに要求されたコードを自分の質問に投稿し、誰かがそのバグを理解できるかどうかを確認します。 – Rikonator

関連する問題