【问题标题】:Qt Drag&Drop with own widgets?Qt Drag Drop带有自己的小部件?
【发布时间】:2011-04-14 12:57:33
【问题描述】:

我自己创建了一个小部件,包括 QProgressBar 和 QVBoxLayout 中的 QLabel。它还有一个返回标签文本的功能(自创)。 现在在我的 MainWindow 中,我有另外两个 QHBoxLayouts,我想将我的小部件从一个拖放到另一个。当我单击 QLabel 和 QProgressBar 之间的小空闲空间时,它也可以工作。但是当我直接点击其中一个时,应用程序崩溃并痛苦地烧毁。
我也知道它失败的地方。我的mousePressEvent 看起来像这样:

void DragDrop::mousePressEvent(QMouseEvent *event) {

// !!!!---- make sure ONLY MyWidgets are here, else: CRASH ----!!!!
    MyWidget *child = static_cast<MyWidget*>(childAt(event->pos()));
    if (!child)
    return;

qDebug() << child->returnLabelText();
...

}

所以当我点击 ProgressBar 时,它会投射 ProgressBar,而不是我自己的小部件。而且因为 QProgressBar 没有像 returnLabelText() 这样的功能(但我的小部件有)它失败了。
获取我的小部件的更好方法是什么?

【问题讨论】:

    标签: c++ qt qt4 drag-and-drop casting


    【解决方案1】:

    QWidget::childAt(int,int) 返回 child 小部件,而不是父小部件。在您的情况下,它返回 QProgressBar。然后,您尝试强制转换为 MyWidget,但事实并非如此。您正在寻找的是 QProgressBar(或 QLabel)的父级。

    static_cast 不会验证您尝试转换的对象的类型,并且即使转换无效也会始终产生非空指针。您在此处查找的是dynamic_cast,如果对象不是您要查找的类型,它将返回 NULL。由于您正在寻找被点击的小部件的父级(或祖先),您可以使用循环遍历被点击的小部件的祖先以找到您正在寻找的 MyWidget 实例。

    void DragDrop::mousePressEvent(QMouseEvent *event) {
      QWidget *widget = childAt(event->pos());
      do {
        MyWidget *myWidget = dynamic_cast<MyWidget*>(widget);
        widget = widget->parentWidget();
      } while (myWidget == NULL && widget != NULL)
      if (myWidget == NULL)
        return;
    
      qDebug() << myWidget->returnLabelText();
      // ...
    }
    

    【讨论】:

    • ianmac45 是对的……在 QObjects 的上下文中,强烈首选 qobject_cast,因为它不依赖于 RTTI。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    相关资源
    最近更新 更多