库组件的Qt.createComponent URL

时间:2018-08-12 14:55:54

标签: qt qml qt5

下面是TimelinePresenter.qml中的一个函数,它是我创建的自定义组件。

function createMenu() {
    var menuComp = Qt.createComponent("Menu.qml");
    if( menuComp.status != Component.Ready )
    {
        if( menuComp.status == Component.Error )
            console.debug("Error: " + menuComp.errorString());
        return;
    }
}

出现错误:

Error: qrc:/qml/timeline/Menu.qml:-1 No such file or directory

TimelinePresenter.qml是在.qrc文件中指定的资源文件,其路径为qml / timeline,如错误消息中所示,因此qml引擎正试图在该目录中找到Menu.qml。如何指定创建qt菜单组件的路径?

编辑:

我的resources.qrc文件

<RCC>
    <qresource prefix="/">
        <file>qml/main_window.qml</file>
        <file>qml/timeline/TimelineViewItem.qml</file>
        <file>qml/timeline/HorizontalLine.qml</file>
        <file>qml/timeline/TimelineView.qml</file>
        <file>qml/timeline/VerticalLine.qml</file>
        <file>qml/timeline/timeline-item/timeline_item.h</file>
        <file>qml/timeline/TimelinePresenter.qml</file>
        <file>qml/timeline/timeline-item/analog_timeline_item.h</file>
        <file>qml/timeline/timeline-item/digital_timeline_item.h</file>
        <file>qml/timeline/timeline_presenter_backend.h</file>
        <file>qml/ControllableListPresenter.qml</file>
        <file>qml/controllable_list_backend.h</file>
        <file>qml/controllable-popup/AddControlUnitPopup.qml</file>
        <file>qml/styled/CenteredPopup.qml</file>
        <file>qml/styled/StyledTextField.qml</file>
    </qresource>
</RCC>

2 个答案:

答案 0 :(得分:0)

您将组件的创建与属于该组件的对象的创建混淆了。

Menu component已经存在并且由Qt提供,您所要做的就是使用Qt.createQmlObject()方法创建对象。

示例:

var menuObj = Qt.createQmlObject('import QtQuick.Controls 2.0 ; Menu {
MenuItem { text: "Cut" }
MenuItem { text: "Copy" }
MenuItem { text: "Paste" } }', parentItem, "dynamicSnippet1");

完整示例:

import QtQuick 2.7
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    id: parentItem

    Component.onCompleted: {
        var menu = Qt.createQmlObject('import QtQuick.Controls 2.0 ; Menu {
        MenuItem { text: "Cut" }
        MenuItem { text: "Copy" }
        MenuItem { text: "Paste" }
    }', parentItem,"dynamicSnippet1");
        // test: open menu
        menu.open()
    }
}

答案 1 :(得分:0)

就您在评论中所描述的情况而言,我建议仅在您单击的位置创建一个Menu,仅创建popup(),并将其设置为特定的上下文。

我准备了一个小例子来说明如何使用Menu

import QtQuick 2.7
import QtQuick.Window 2.0
import QtQuick.Controls 2.3 // Necessary for the "Action" I used. Create the Menu otherwise if you are bound to older versions.
import QtQml 2.0

ApplicationWindow {
    id: window
    visible: true
    width: 600
    height: 600

    Repeater {
        model: ListModel {
            ListElement { color: 'black'; x: 400; y: 50  }
            ListElement { color: 'black'; x: 100; y: 190 }
            ListElement { color: 'black'; x: 70;  y: 80 }
            ListElement { color: 'black'; x: 30;  y: 0 }
            ListElement { color: 'black'; x: 340; y: 500 }
            ListElement { color: 'black'; x: 210; y: 10 }
        }
        delegate: MouseArea {
            x: model.x
            y: model.y
            width: 50
            height: 50
            property QtObject modelItem: model

            onClicked: menu.openMenu(x + mouse.x, y + mouse.y, modelItem)

            Rectangle {
                color: model.color
                anchors.fill: parent
            }
        }
    }

    Menu {
        id: menu
        Action { text: "green"    ; onTriggered: { menu.currentContext.color = text } }
        Action { text: "blue"     ; onTriggered: { menu.currentContext.color = text } }
        Action { text: "pink"     ; onTriggered: { menu.currentContext.color = text } }
        Action { text: "yellow"   ; onTriggered: { menu.currentContext.color = text } }
        Action { text: "orchid"   ; onTriggered: { menu.currentContext.color = text } }
        Action { text: "orange"   ; onTriggered: { menu.currentContext.color = text } }
        Action { text: "teal"     ; onTriggered: { menu.currentContext.color = text } }
        Action { text: "steelblue"; onTriggered: { menu.currentContext.color = text } }

        property QtObject currentContext
        function openMenu(x, y, context) {
            currentContext = context
            popup(x, y)
        }
    }
}
  

尽管我认为此答案可能会解决您的问题,但我知道这并不是您最初提出的问题的答案。


对于组件部分:我认为您误解了Component是什么-它不是Item。这是创建QtObjects准备阶段,还包括 prototype 或配置的 factory 等。

因此,您的功能(如果可行)将在创建不可见的事物时结束,您可以通过调用createObject()从中创建事物。

创建Component是正确的做法,如果您想在以后创建对象,并且可能想通过JavaScript或期望的其他QML类型多次创建相似的对象Component作为输入(例如代表)。

要创建组件,您有多种可能,例如:

  1. Qt.createComponent(url)
  2. Component { SomeItem {} }

第一个希望您知道该URL,而对于您而言,您则不知道。为了避免这种情况,最简单的解决方案是创建一个新文件,例如 MyMenu.qml 其中仅包含Menu {}-那么您可以由此创建一个Component

第二个不希望您知道该URL,但是它不是动态创建的。

Component {
    id: myCmp
    Menu {
    }
}
onSomeSignal: myCmp.createObject({ prop1: val1 }, this)

在实例化文件中的对象时,将自动创建Component。这样一来,(一次)速度会变慢,因为必须处理更多的代码,但是您以后不必这样做。

如果顶层元素是Qt.createQmlObject("Write a new QML-File here"),则创建带有Component eyllanesc 这样的对象也可以用来创建Component。如果没有Component作为顶层,它还将首先创建一个曾经用于创建QtObject的组件,然后将其丢弃。这是最慢但最灵活的动态创建对象的方法。