Qt 获取2个QML文件以使用信号进行通信时出现问题

Qt 获取2个QML文件以使用信号进行通信时出现问题,qt,qml,signals-slots,Qt,Qml,Signals Slots,我有2个qml文件。Toolbarbutton.qml创建按钮,DockWidget.qml创建列表视图。我正在尝试将工具栏中的按钮广播到DockWidget,以确认该按钮已被单击。然后我想将项目添加到我的listView 我一直在试图用一个信号来建立联系。在Toolbarbutton.qml中,我有一个ID为saveButton的矩形项。在这个矩形项下,我添加了一个名为addSaveHistory()的信号。我缩短了代码,以便更容易看到我在做什么 Rectangle { id: saveBu

我有2个qml文件。Toolbarbutton.qml创建按钮,DockWidget.qml创建列表视图。我正在尝试将工具栏中的按钮广播到DockWidget,以确认该按钮已被单击。然后我想将项目添加到我的listView

我一直在试图用一个信号来建立联系。在Toolbarbutton.qml中,我有一个ID为saveButton的矩形项。在这个矩形项下,我添加了一个名为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

    }
}
}
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  
     }
 }
}
在DockWidget.qml文件中,我有一个使用Connections组件的项。我已经缩短了代码,以便更容易看到我在做什么

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

    }
}
}
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  
     }
 }
}
我似乎不明白为什么从未调用过OnadSaveHistory。我还尝试使用加载程序组件将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")

  }
}

首先,要意识到信号是在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声明一个信号,并在您单击包含的鼠标earea时发出该信号,它将如下所示:

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..."
}
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"
        }
    }
}
然后是这个信号的一个简单消费者,这里只有一个文本元素,但可以是如下所示的任何东西:

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..."
}
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"
        }
    }
}
但是等等,你说,这有什么帮助呢。到目前为止还没有联系。我们在实例化Receiver项时会这样做。因此,这里的main.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..."
}
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的子元素。把工具栏按钮和停靠小部件想象成乐高积木,我们一起在一个对这些项目以及它们应该如何交互有更高知识水平的位置进行安装。但是,如果您想这样做,可以将其封装到它自己的更复杂的定制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
    }
}

希望这有帮助。

首先,要意识到信号是在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声明一个信号,并在您单击包含的鼠标earea时发出该信号,它将如下所示:

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..."
}
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"
        }
    }
}
然后是这个信号的一个简单消费者,这里只有一个文本元素,但可以是如下所示的任何东西:

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..."
}
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"
        }
    }
}
但是等等,你说,这有什么帮助呢。到目前为止还没有联系。我们在实例化Receiver项时会这样做。因此,这里的main.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..."
}
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的子元素。把工具栏按钮和停靠小部件想象成乐高积木,我们一起在一个对这些项目以及它们应该如何交互有更高知识水平的位置进行安装。但是,如果您想这样做,可以将其封装到它自己的更复杂的定制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
    }
}

希望这能有所帮助。

嗨,肖恩,非常感谢你的帮助。我有一个独特的问题,因为我正在使用qml为另一个使用qml创建接口的应用程序创建插件。我无法按照您的建议设置main.qml。这就是我的main.qml的格式。我编辑了我的原始帖子以显示main.qml。我编辑了ToolbarButton.qml以按照您的建议工作,因此它被放置在矩形项下,然后使用id.signalfunction()语法调用信号。然而,我试图建立的连接似乎不知道ToolbarButton.qmlw中的信号,因为没有看到alg.ui.addToolBarWidget()和alg.ui.addDockWidget()的作用,所以很难说解决方案是什么。我猜他们实例化了作为参数传入的QML文件。不知何故,您需要能够引用那些能够使用Plugin{}范围中的Connections{}元素。您可能需要查看这些函数的文档(我还没有找到任何公开的文档),或者询问编写它们的开发人员是否有一个典型的示例。如果幸运的话,这些函数将返回对创建的工具栏按钮的引用,然后您可以将其存储在插件上声明的属性中。DockWidget也是如此。所以它可能类似于:Plugin{id:root;property-var-button:null;property-var-dockWidget:null;Component.onCompleted:{root.button=alg.ui.addToolbarWidget(…);root.dockWidget=alg.ui.addDockWidget(…);},但这取决于这些函数是否返回有用的内容(您希望它们会)。如果没有,那么您需要一些其他API才能引用所创建的项。谢谢Sean。我明白您的意思:)嗨Sean,非常感谢您的帮助。我有一个独特的问题,因为我正在使用qml为另一个使用qml创建接口的应用程序创建插件。我无法按照您的建议设置main.qml。这就是我的in.qml需要格式化。我编辑了我的原始帖子以显示main.qml。我编辑了ToolbarButton.qml,以便按照您的建议工作,将其放置在矩形项下,然后使用id.signalfuncntion()语法调用信号。但是,我试图建立的连接似乎不知道