2016-04-14 27 views
0

我有2个qml文件。 Toolbarbutton.qml创建一个按钮,DockWidget.qml创建一个ListView。我正在尝试将Toolbarbutton中的按钮广播到DockWidget,该按钮已被点击。然后我想添加项目到我的listView。无法获取2个使用信号进行通信的QML文件

我一直在尝试使用信号来建立通信。在Toolbarbutton.qml中,我有一个ID为saveButton的Rectangle项目。在这个矩形项下,我添加了一个名为addSaveHistory()的信号。我缩短了代码,所以更容易看到我在做什么。

Rectangle { 
id: saveButton 
width: 50 
height: 30 
border.color: "white" 
color: buttonMouseArea.containsMouse ? "grey" : "black" 

//Button text 
Text{ 
    id: buttonLabel 
    anchors.centerIn: parent 
    text: "Save +" 
    color: "white" 
} 
signal addSaveHistory(string url) 

MouseArea{ 
    id: buttonMouseArea 
    anchors.fill: parent //anchor the mousearea to the rect area 

    //onClicked handles valid mouse button clicks 
    onClicked: { 
     addSaveHistory("Hello?") //dispatch the event 

    } 
} 
} 

在DockWidget.qml文件中,我有一个使用Connections组件的项目。我缩短了代码,因此更容易看到我在做什么。

Item{ 
    width: 100 
    height: 100 
    objectName: "Save + History" 

Rectangle { 
    id: rect 
    anchors.fill: parent 
    color: "#323232" 

Connections { 
    target: saveButton //id of rectangle in ToolbarButton.qml 

    onAddSaveHistory: { 

     // this is never called 
    } 
} 
} 

我似乎无法弄清楚为什么onAddSaveHistory永远不会被调用。我也曾尝试使用Loader组件将Dockwidget.qml文件加载到Toolbarbutton.qml中,然后专门在Dockwidget中调用一个函数,但那不起作用。

我对信号的工作原理有错误的想法吗?我会非常感谢任何指导。

这是我的main.qml文件。

所有的
import QtQuick 2.2 
import Painter 1.0 

import "save.js" as Save 

Plugin { 

//executed at startup 
Component.onCompleted:{ 

    //add toolbar 
    alg.ui.addToolBarWidget("ToolbarButton.qml")//add a button to toolbar 
    alg.ui.addDockWidget("DockWidget.qml")//add dock widget 

    Save.log("Incremental Save Plugin has been created") 

    } 
} 

回答

1

首先,认识到,信号在ToolbarButton.qml文件的根,即矩形声明的QML元件上。只有根项目形成了QML元素的接口。所有的孩子元素都被外界隐藏起来。所以通常在文件顶部附近声明信号。一个常见的排序是:

Item { 
    id: root 
    property real foo: 0.0 
    property alias bar: innerItem.bar 
    signal baz(url location) 

    Rectangle { 
     id: innerItem 
     property color bar: "red" 
    } 
} 

因此,在这种情况下,一个简单的ToolbarButton.qml声明的信号,当你在一个包含鼠标区域单击看起来像这样发出的:

import QtQuick 2.3 

Rectangle { 
    id: root 
    width: buttonLabel.width + 20 
    height: buttonLabel.height + 20 
    color: "steelBlue" 

    // Declare signal on the button object 
    signal addSaveHistory(string url) 

    Text { 
     id: buttonLabel 
     anchors.centerIn: parent 
     text: "Save +" 
    } 

    MouseArea { 
     id: buttonMouseArea 
     anchors.fill: parent 
     onClicked: { 
      // emit the signal 
      root.addSaveHistory("Hello?") 
     } 
    } 
} 

那么简单这个信号的消费者,这里只是一个文本元素,但可以是任何东西,可能是这样的:

import QtQuick 2.3 

Text { 
    id: dockWidget 
    text: "Waiting for a click..." 
} 

别急,你说,这是如何的帮助。到目前为止,没有任何联系。当我们实例化我们的接收器项目时,我们做到这一点。因此,在这里,main.qml文件如下所示:

import QtQuick 2.3 
import QtQuick.Window 2.2 

Window { 
    visible: true 

    // Instantiate the ToolbarButton that emits the signal when clicked 
    ToolbarButton { 
     id: toolbarButton 
     anchors.top: parent.top 
     anchors.left: parent.left 
     anchors.topMargin: 10 
     anchors.leftMargin: 10 
    } 

    // Instantiate the DockWidget (just a Text element in this example) 
    DockWidget { 
     id: dockWidget 
     anchors.bottom: parent.bottom 
     anchors.bottomMargin: 10 
     anchors.left: parent.left 
     anchors.leftMargin: 10 

     // Complete the plumbing that connects the signal from item above 
     // with id: toolbarButton. 
     Connections { 
      target: toolbarButton 
      // When signal addSaveHistory is emitted, 
      // replace binding above with a new one 
      onAddSaveHistory: dockWidget.text = "Button was clicked" 
     } 
    } 
} 

实际上,没有必要将Connections元素作为DockWidget的子元素。将ToolbarButton和Dock小部件想象成乐高积木,我们在一个对这些项目有更高层次知识以及他们应该如何交互的位置上进行沟通。如果你想要,你可以把它包装到自己更复杂的定制QML组件中。

此外,如果你只对信号有一点爱心,你甚至都不需要连接元素都:

import QtQuick 2.3 
import QtQuick.Window 2.2 

Window { 
    visible: true 

    ToolbarButton { 
     id: toolbarButton 
     anchors.top: parent.top 
     anchors.left: parent.left 
     anchors.topMargin: 10 
     anchors.leftMargin: 10 

     // Add signal handler directly to emitter 
     onAddSaveHistory: dockWidget.text = "Button was clicked" 
    } 

    DockWidget { 
     id: dockWidget 
     anchors.bottom: parent.bottom 
     anchors.bottomMargin: 10 
     anchors.left: parent.left 
     anchors.leftMargin: 10 
    } 
} 

希望这有助于。

+0

嗨肖恩, 非常感谢您的帮助。我有一个独特的问题,因为我正在使用qml为另一个使用qml创建接口的应用程序创建一个插件。如你所建议的,我无法设置我的main.qml。这是我的main.qml需要格式化的方式。我编辑了我的原始帖子以显示main.qml。 – WesM

+0

我编辑了ToolbarButton.qml,按照您的建议工作,以便将其放置在矩形项目下,然后使用id.signalFucntion()语法调用信号。 但是,它似乎是我试图建立的连接并不知道ToolbarButton.qml中的信号 – WesM

+0

没有看到alg.ui.addToolBarWidget()和alg.ui.addDockWidget()是否难以说出解决方案是什么。我猜测他们实例化了作为参数传入的QML文件。不知何故,您需要能够引用那些能够使用插件{}范围内的Connections {}元素。您可能需要查看这些功能的文档(我还找不到任何公开的内容),或询问编写这些功能的开发人员是否有典型示例。 –