如何在 QML 中实现对象之间的单一连接?

Posted

技术标签:

【中文标题】如何在 QML 中实现对象之间的单一连接?【英文标题】:How to implement single connection between objects in QML? 【发布时间】:2018-12-06 15:07:21 【问题描述】:

在我的 Qt 应用程序中,我有很多窗口,有时它们需要一个“返回”按钮。此按钮位于ApplicationWindowheader 中的ToolBar 组件上。

我想要实现的是,这个Back 按钮将只有一个与其他对象的连接,即与调用connect 方法的最后一个对象的连接。现在每个connect 我都得到一个新连接,当信号发出时,它会被多次调用。不幸的是,Qt 没有disconnectAll 方法,如果可以,那将解决我的问题,我只需先调用disconnectAll,然后再调用connect,这将实现单连接。

那么,你是如何在 Qt 中用一个简单的方法实现这个功能的呢?

这是一个最小的可重现示例,多次单击选项卡,然后按“返回”按钮,您将看到大量 console.log 消息。我需要的是这条消息对应于连接到Back 按钮的最后一个对象。

import QtQuick 2.11
import QtQuick.Controls 2.4

ApplicationWindow 
    visible: true
    width: 640
    height: 480
    title: qsTr("Tabs")
    signal back_btn_clicked()

    SwipeView 
        id: swipeView
        anchors.fill: parent
        currentIndex: tabBar.currentIndex

        Page1Form 
            id: page1
            function page1_callback() 
                console.log("page 1 back button triggered")
            
            function install_button() 
                enable_back_button(page1_callback)
            
        
        Page2Form 
            id: page2
            function page2_callback() 
                console.log("page 2 back button triggered")
            
            function install_button() 

                enable_back_button(page2_callback)
            
        
        function install_back_button(idx) 
            if (idx===0) 
                page1.install_button()
            
            if (idx===1) 
                page2.install_button()
            
        
    
    Button 
        id: btn_back
        visible: false
        text: "Back Button"
        onClicked: back_btn_clicked()
    

    footer: TabBar 
        id: tabBar
        currentIndex: swipeView.currentIndex

        TabButton 
            text: qsTr("Page 1")
            onClicked: swipeView.install_back_button(0)
        
        TabButton 
            text: qsTr("Page 2")
            onClicked: swipeView.install_back_button(1)
        
    
    function enable_back_button(func_name) 
        btn_back.visible=true
        back_btn_clicked.connect(func_name)

    

PageForm.ui 是这样定义的

import QtQuick 2.11
import QtQuick.Controls 2.4

Page 
    width: 600
    height: 400

    header: Label 
        text: qsTr("Page 1")
        font.pixelSize: Qt.application.font.pixelSize * 2
        padding: 10
    

    Label 
        text: qsTr("You are on Page 1.")
        anchors.centerIn: parent
    

【问题讨论】:

看起来像XY problem。您正在提供您的代码、您自己的错误解决方案并询问如何修复它。提出问题,并询问如何实现特定目标。 @folibis 我已经解释了问题:Qt没有实现对象之间的单一连接,目标是拥有这个功能 【参考方案1】:

我认为最简单的技巧是将回调存储在一个属性中,然后在enable_back_button() 中,在您的disconnect() 函数中引用该属性,并使用作为函数参数传递的新回调相应地更新该属性. (这个参数的基本原理是 disconnect() 函数必须接受一个参数:断开连接的插槽。所以我们需要以某种方式跟踪它。

ApplicationWindow 
    visible: true
    // ... omitted for brevity

    property var prevCallback: null

    // ... ofb


    function enable_back_button(func_name) 
        btn_back.visible=true

        if (prevCallback)
            back_btn_clicked.disconnect(prevCallback)   // disconnect previous callback

        back_btn_clicked.connect(func_name)  // connect new callback

        prevCallback = func_name  // update property with new callback
    

这也适用于多个连接,只需将存储更改为数组,然后遍历它。

【讨论】:

我已经尝试过了,但是不知道函数类型可以保存在var类型中。完美运行。谢谢!

以上是关于如何在 QML 中实现对象之间的单一连接?的主要内容,如果未能解决你的问题,请参考以下文章

如何在两个表之间的组中实现递归连接?

如何在elasticsearch中实现两种类型之间的交叉连接?

如何在 Python 和 Qt Quick QML 应用程序中实现简化的双向数据绑定

如何在tabview中的更改选项卡中实现转换?

如何在Python和Qt Quick QML应用程序中实现简化的双向数据绑定

如何在任何 MQ 平台中实现这个单一并发分布式队列?