简体   繁体   中英

Weird bug in Qt application

In my application, I have my re-implemented QGraphicsView checking for a mouseReleaseEvent() , and then telling the item at the position the mouse is at to handle the event.

The QGraphicsItem for my view is made up of two other QGraphicsItems , and I check which one of the two is being clicked on (or rather having the button released on), and handle the respective events.

In my Widget's constructor, I set one of the items as selected by default, using the same methods I used when the items detect a release.

When I debugged, I found that for the LabelItem , select is called without a problem from the constructor (and the result is clear when I first start the application). But, when I click on the items, the application terminates. I saw that I was getting into the select function, but not leaving it. So the problem is here.

Which is very weird, because the select function is just a single line setter.

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

This is the mouseReleaseEvent ;

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

When I commented the line out in the function, I had no errors. I have not debugged for the other QGraphicsItem , CheckBoxItem, but the application terminates for its events as well. I think the problem might be related, so I'm concentrating on select , for now.

I have absolutely no clue as to what could have caused this and why this is happening. From my past experience, I'm pretty sure it's something simple which I'm stupidly not thinking of, but I can't figure out what.

Help would really be appreciated.

If the LabelItem is on top of the LayerItem , itemAt will most likely return the LabelItem because it is the topmost item under the mouse. Unless the LabelItem is set to not accept any mouse button with l->setAcceptedMouseButtons(0) .

Try to use qgraphicsitem_cast to test the type of the item. Each derived class must redefine QGraphicsItem::type() to return a distinct value for the cast function to be able to identify the type.

You also could handle the clicks in the items themselves by redefining their QGraphicsItem::mouseReleaseEvent() method, it would remove the need for the evil cast, but you have to remove the function LayerView::mouseReleaseEvent() or at least recall the base class implementation, QGraphicsView::mouseReleaseEvent() , to allow the item(s) to receive the event.

I have seen these odd behaviours: It was mostly binary incompatibility - the c++ side looks correct, and the crash just does not make sense. As you stated: In your code the "selected" variable cannot be the cause. Do you might have changed the declaration and forgot the recompile all linked objects. Just clean and recompile all object files. Worked for me in 99% of the cases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM