【问题标题】:casting value emitted from qml on drag drop拖放时从 qml 发出的投射值
【发布时间】:2013-12-26 00:19:51
【问题描述】:

在我的 QML 中:

DropArea {
  onDropped: {
    root.dropSignal(drop);
  }
}

信号定义为:

signal dropSignal(var data)

我的槽函数:

void MainSlot::dropSlot(const QVariant &data)
{
  qDebug() << "Called the C++ slot with data:" << data;
}

这会输出以下内容:

Called the C++ slot with data: QVariant(QObject*, QQuickDropEvent(0x7fff5fbfd828) ) 

我需要帮助将此对象转换为我期望的某种 Drop 事件。我希望 C++ 代码处理接受/拒绝 drop 和从 drop 访问数据的逻辑。

我在类参考中找不到 QQuickDropEvent。我确实找到了 QDropEvent。从有关 DragArea 的文档中,尚不清楚与 QML DragEvent 等效的 C++ 是什么或在哪个头文件中定义了 DragEvent。

尝试这样的演员阵容没有奏效:

QDropEvent *item = qobject_cast<QDropEvent*>(v.value<QObject*>());

【问题讨论】:

    标签: qt5 qt-quick qtquick2


    【解决方案1】:

    QML 的 DragEvent = QQuickDropEvent

    这在QML DragEvent documentation 的更新版本中有所说明,来自sources

    /*!
        \qmltype DragEvent
        \instantiates QQuickDropEvent
        \inqmlmodule QtQuick
        \ingroup qtquick-input-events
        \brief Provides information about a drag event
    
        The position of the drag event can be obtained from the \l x and \l y
        properties, and the \l keys property identifies the drag keys of the event
        \l source.
    
        The existence of specific drag types can be determined using the \l hasColor,
        \l hasHtml, \l hasText, and \l hasUrls properties.
    
        The list of all supplied formats can be determined using the \l formats property.
    
        Specific drag types can be obtained using the \l colorData, \l html, \l text,
        and \l urls properties.
    
        A string version of any available mimeType can be obtained using \l getDataAsString.
    */
    

    QQuickDropEvent 的标头在src/quick/items/qquickdroparea_p.h 中可用。我猜这又是一个私有头文件,这意味着您不应该在 C++ 中处理这些事件,而是在 Javascript 中。

    QQuickDropEvent 实例包含您无法直接访问的 QDropEvent 类型的私有实例变量。

    编辑:您可能希望在 Javascript 中复制 drop 的属性并将数组传递给 C++(未经测试):

    DropArea {
        var actionIdToString = function(id) {
            if (id ===   Qt.CopyAction) return 'Qt.CopyAction';
            if (id ===   Qt.MoveAction) return 'Qt.MoveAction';
            if (id ===   Qt.LinkAction) return 'Qt.LinkAction';
            if (id === Qt.IgnoreAction) return 'Qt.IgnoreAction';
            return 'Unexpected action';
        }
    
        onDropped: {
            var dropProperties = [
                drop.accepted,
                actionIdToString(drop.action),
                drop.drag.source,
                drop.keys,
                drop.supportedActions,
                drop.x,
                drop.y
            ]
            root.dropSignal(dropProperties);
        }
    }
    

    有一篇关于passing more complex datastructures between C++ and QML 的博文。据我所知,在将 Javascript 数组传递到您的插槽时,您会得到一个 QVariantList

    您可能需要考虑使用 Javascript 对象 (JSON style),以便通过名称而不是 C++ 中的索引来访问 drop 的属性,但我不确定对象在从 QML 到 C++ 的步骤中存活的情况。

    【讨论】:

    • 那么这是否意味着我应该在上下文中嵌入一个 C++ 对象来为事件处理程序提供逻辑? [qt-project.org/doc/qt-5.0/qtqml/…
    • 我添加了一个关于如何将 drop 而不是其属性复制到 C++ 的部分。这有帮助吗?
    • 你写这个例子真是太好了。但是,它有一个问题:它使我无法将调用 drop.accept() 的责任委托给 C++ 类。在您的示例中,我传递了 drop.accepted,该值将取决于我是否决定在 qml 中调用 drop.accept(),这似乎并不理想。老实说,我的 C++ 无法将 SLOT 直接附加到 onDropped 事件似乎很奇怪......似乎对于在 qml 中调度的每个事件都应该已经存在一个 SIGNAL。
    • 当我们谈论它时,DragEvent 上的方法在哪里访问给定提供的键的数据...例如在 html5 中:e.dataTransfer.getData('text/html') ;
    • 远非理想,没错。但是由于Qt的界面暂时是这样,所以只有两种可能:在Javascript中处理掉线或处理私有标头。您已经证明您的插槽可以正常工作并且您可以在 C++ 中接收数据。现在您可以将 QVariant 转换为 QQuickDropEvent 并使用它。您必须在 Qt 源代码中找到标头、包含它们、找到函数名称等,因为没有文档。
    猜你喜欢
    • 1970-01-01
    • 2017-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    相关资源
    最近更新 更多