简体   繁体   English

Qt应用程序中的奇怪错误

[英]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. 在我的应用程序中,我重新实现了QGraphicsView检查mouseReleaseEvent() ,然后在鼠标所处的位置告诉该项目以处理事件。

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. 我的视图的QGraphicsItem由其他两个QGraphicsItems ,我检查是否正在单击两个(或释放按钮)这两个之一,并处理相应的事件。

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). 当我调试时,我发现对于LabelItem ,select不会从构造函数中被调用(并且当我第一次启动该应用程序时,结果是清楚的)。 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 ; 这是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. 我尚未调试其他QGraphicsItem CheckBoxItem,但该应用程序也因其事件而终止。 I think the problem might be related, so I'm concentrating on select , for now. 我认为问题可能是相关的,因此我现在专注于select

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. 如果LabelItem是在顶部LayerItemitemAt将最有可能返回LabelItem ,因为它是鼠标下的最上面的项目。 Unless the LabelItem is set to not accept any mouse button with l->setAcceptedMouseButtons(0) . 除非使用l->setAcceptedMouseButtons(0)LabelItem设置为不接受任何鼠标按钮。

Try to use qgraphicsitem_cast to test the type of the item. 尝试使用qgraphicsitem_cast测试项目的类型。 Each derived class must redefine QGraphicsItem::type() to return a distinct value for the cast function to be able to identify the type. 每个派生类都必须重新定义QGraphicsItem::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. 您还可以通过重新定义它们的QGraphicsItem::mouseReleaseEvent()方法来处理项目本身中的点击,这将消除对恶意对象的需要,但是您必须删除函数LayerView::mouseReleaseEvent()或至少调用基本函数类实现QGraphicsView::mouseReleaseEvent() ,以允许项目接收事件。

I have seen these odd behaviours: It was mostly binary incompatibility - the c++ side looks correct, and the crash just does not make sense. 我已经看到了这些奇怪的行为:主要是二进制不兼容-c ++方面看起来是正确的,并且崩溃根本没有意义。 As you stated: In your code the "selected" variable cannot be the cause. 如您所述:在您的代码中,“ selected”变量不能成为原因。 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. 在99%的案件中为我工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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