无法使用信号

时间:2016-04-14 14:46:15

标签: qt qml signals-slots

我有2个qml文件。 Toolbarbutton.qml创建一个按钮,DockWidget.qml创建一个ListView。我试图让Toolbarbutton中的按钮向DockWidget广播,单击该按钮。然后我想在listView中添加项目。

我一直在尝试使用信号来建立通信。在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。我缩短了代码,因此更容易看到我在做什么。

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 个答案:

答案 0 :(得分:1)

首先,要意识到信号是在ToolbarButton.qml文件根目录的QML元素上声明的,即Rectangle。只有根项构成QML元素的接口。所有子元素都隐藏在外面的世界中。因此习惯上将信号声明在文件顶部附近。常见的顺序是:

position:absolute

因此,在这种情况下,一个简单的ToolbarButton.qml声明一个信号并在你单击一个包含的MouseArea时发出它将如下所示:

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

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

然后是这个信号的简单消费者,这里只是一个Text元素但可以是任何东西看起来像这样:

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?")
        }
    }
}

但是,等等,你说,这有什么帮助。那么到目前为止没有联系。当我们实例化我们的接收器项目时,我们会这样做。所以这里main.qml文件如下所示:

import QtQuick 2.3

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

实际上,Connections元素不需要是DockWidget的子元素。将ToolbarButton和Dock小部件视为乐高积木,我们在一个对这些项目有更高级别知识以及它们应如何交互的位置进行管道连接。但是,如果您愿意,可以将其包装到自己更复杂的自定义QML组件中。

此外,如果您只关心信号,则根本不需要Connections元素:

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"
        }
    }
}

希望这有帮助。