首页 文章

QML在匿名孙子之间发送信号

提问于
浏览
1

我正在尝试在树结构中的qml组件之间进行通信 . 我有一个main.qml组件,其id和root . 它有两个孩子,每个孩子都有一个从转发器和模型动态创建的任意数量的孩子 .

当点击其中一个孙子时,我希望其他人知道,并能够采取行动 . 所以,如果我可以在孙子孙女之间发送信号,那就没事了 .

问题是它们都没有设置它们的id属性,因为它们是动态制作的,而且它们中的一些属于不同的范围 . 为了在它们之间进行通信,我已经完成了以下操作:在root中创建了一个函数,每个孙都可以看到它,并且可以使用消息作为参数来调用它 . 然后,根函数以消息作为参数发出信号 . 所有的孙子都可以连接到信号,因为他们知道root的id .

人们怎么看?我感觉我已经错过了qml中的信号点,感觉就像我已经实现了一个粗略的系统并且错过了整点或者什么 .

此外,我想要远离C世界,但人们认为最好使用C类,以便我可以使用信号和插槽 .

我的目标是具有非常松散耦合的MVC结构和集中式控制器 . 人们对MVC中QML组件之间的通信有何看法 .

我在这里找到的唯一类似的问题是关于C或在组件上使用硬编码的id .

我认为id不能动态设置,甚至不能在创建时设置;我错了吗?

此外,组件在不同的范围内,因此无法解析id;我错了吗?

我写了一些代码:

//qml.main
import QtQuick 2.4
import QtQuick.Controls 1.3

ApplicationWindow {
    id: root
    visible: true
    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("&Open")
                onTriggered: console.log("Open action triggered");
            }
            MenuItem {
                text: qsTr("Exit")
                onTriggered: Qt.quit();
            }
        }
    }

    property string thisName: "root"

    signal rootSays(string broadcastMessage)

    function callRoot(message) {
        var response = message
        print("Root received: " + message)
        print("Root broadcasting: " + response)
        rootSays(response)
    }

    MajorComponent{//this is root's child A
        property string thisName: "A"
        thisModel: [{name:"First Grandchild of A", color:"red", y:0},
                    {name:"Second Grandchild of A", color:"green", y:80}]
    }

    MajorComponent{//this is root's child B
        property string thisName: "B"
        thisModel: [{name:"First Grandchild of B", color:"blue", y:210},
                    {name:"Second Grandchild of B", color:"yellow", y:290}]
    }


}


//qml.MinorComponent
import QtQuick 2.0

Rectangle {
    property string thisName: ""
    property string thisColor: ""

    color: thisColor
    height: 50; width: 200
    Text {
        anchors.centerIn: parent
        text: thisName
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            print(thisName + " clicked")
            print("Root called with: " + thisName)
            root.callRoot("Hello from " + thisName)
            print("---")
        }
    }
}


//qml.MajorComponent
import QtQuick 2.0

Rectangle {
    property var thisModel: []

    Repeater {
        model:thisModel
        MinorComponent {
            y: modelData.y
            thisName: modelData.name
            thisColor: modelData.color
            function handleResponse(response) {
                print(thisName + " received: " + response);
            }
            Connections {
                target: root
                onRootSays: handleResponse(broadcastMessage)
            }

        }
    }

}

1 回答

  • 1

    我认为id不能动态设置,甚至不能在创建时设置;我错了吗?

    id s纯粹是"compile"时间构造 . 话虽如此,没有什么可以阻止您实现和管理自己的对象注册表系统 . 一个简单的空JS对象可以做,它可以有效地用作 QMap 来查找基于键(属性名称)的对象 . 如果将 Map 对象设置为根对象的属性,则应该可以从树中的每个对象解析因为动态范围 .

    信号的方法是一个合理的IMO . 我使用了类似的东西,结合了仿函数和通过引用捕获,允许访问任意树结构中的任意和可选现有对象,按照它们必须满足的各种标准过滤候选 . 你可以用这种技术做一些非常棘手的事情 .

    话虽这么说,一个说明你实际想要实现的实际例子将有助于提供更具体的答案 .

相关问题