如何在TabView的选项卡之间发送信号(Qt5)



我有带两个选项卡的TabView。每个选项卡都有Item元素(包含其他内容)。我需要从一个标签发送信号,并在另一个标签中捕捉(处理)它

如果我试图将信号从一个选项卡(项)发送到另一个选项卡,它不会工作,也不会显示任何错误。

我找到了一种方法,使用这里写的连接将信号从选项卡发送到TabView范围(http://qt-project.org/doc/qt-5/qml-qtquick-loader.html)。

在第一个选项卡信号中声明:

signal message()

在此选项卡中进行调用(例如在onClicked处理程序中):

onClicked: {
    nameOfItemInFirstTab.message()
}

在TabView范围中,我声明了Connections:

Connections {
    target: nameOfTheFirstTab.item
    onMessage:
    {
        doSomething()
    }
}

使用这种方式,可以捕获第一个选项卡中的信号。但是,现在如何将信号发送到第二个选项卡?还有别的办法吗?

你可以这样做:

import QtQuick 2.3
import QtQuick.Controls 1.2
Rectangle {
    id: myRect
    width: 100
    height: 100
    TabView {
        anchors.fill: parent
        Component.onCompleted: {
            tab1.tab1Signal.connect(tab2.onTab1Signal)
            tab2.tab2Signal.connect(tab1.onTab2Signal)
        }
        Tab {
            id: tab1
            title: "Tab 1"
            signal tab1Signal
            function onTab2Signal() {
                print("Tab 1 received Tab 2's signal")
            }
            Item {
                Button {
                    text: "Send signal"
                    anchors.centerIn: parent
                    onClicked: tab1Signal()
                }
            }
        }
        Tab {
            id: tab2
            title: "Tab 2"
            signal tab2Signal
            function onTab1Signal() {
                print("Tab 2 received Tab 1's signal")
            }
            Item {
                Button {
                    text: "Send signal"
                    anchors.centerIn: parent
                    onClicked: tab2Signal()
                }
            }
        }
    }
}

这些函数当然可以命名为任何名称;我只在它们前面加了"on",因为这是信号处理程序名称的约定。

有关QML中连接信号的更多信息,请参阅将信号连接到方法和信号。


是否可以在Item中生成onTab1Signal()?我需要向tab2的Item的元素发送一些信息(String/int)。

是的,但这有点棘手。首先,请记住,Tab是一个Loader,因此在其中声明的Item可能并不总是有效的。事实上,如果您查看Tab的实现,您会发现它将其active属性设置为false,这实际上意味着只有在该选项卡成为最新选项卡之后才加载选项卡内容(这种设计称为延迟加载)。一个天真的实现(即我的第一次尝试:p)会遇到奇怪的错误,所以你必须:

  1. 在每个Tab中设置activetrue,或者
  2. 添加一个对此进行说明的中间项目

第一种解决方案是最简单的:

import QtQuick 2.3
import QtQuick.Controls 1.2
Rectangle {
    id: myRect
    width: 100
    height: 100
    TabView {
        id: tabView
        anchors.fill: parent
        Component.onCompleted: {
            tab1.tab1Signal.connect(tab2Item.onTab1Signal)
            tab2.tab2Signal.connect(tab1Item.onTab2Signal)
        }
        // You can also use connections if you prefer:
//        Connections {
//            target: tab1
//            onTab1Signal: tabView.tab2Item.onTab1Signal()
//        }
//        Connections {
//            target: tab2
//            onTab2Signal: tabView.tab1Item.onTab2Signal()
//        }
        property alias tab1Item: tab1.item
        property alias tab2Item: tab2.item
        Tab {
            id: tab1
            title: "Tab 1"
            active: true
            signal tab1Signal
            Item {
                id: tab1Item
                function onTab2Signal() {
                    print("Tab 1 received Tab 2's signal")
                }
                Button {
                    text: "Send signal"
                    anchors.centerIn: parent
                    onClicked: tab1Signal()
                }
            }
        }
        Tab {
            id: tab2
            title: "Tab 2"
            active: true
            signal tab2Signal
            Item {
                function onTab1Signal() {
                    print("Tab 2 received Tab 1's signal")
                }
                Button {
                    text: "Send signal"
                    anchors.centerIn: parent
                    onClicked: tab2Signal()
                }
            }
        }
    }
}

第二种解决方案稍微困难一些,并附带一个警告:

import QtQuick 2.3
import QtQuick.Controls 1.2
Rectangle {
    id: myRect
    width: 100
    height: 100
    TabView {
        id: tabView
        anchors.fill: parent
        QtObject {
            id: signalManager
            signal tab1Signal
            signal tab2Signal
        }
        property alias tab1Item: tab1.item
        property alias tab2Item: tab2.item
        Tab {
            id: tab1
            title: "Tab 1"
            signal tab1Signal
            onLoaded: {
                tab1Signal.connect(signalManager.tab1Signal)
                signalManager.tab2Signal.connect(tab1.item.onTab2Signal)
            }
            Item {
                id: tab1Item
                function onTab2Signal() {
                    print("Tab 1 received Tab 2's signal")
                }
                Button {
                    text: "Send signal"
                    anchors.centerIn: parent
                    onClicked: tab1Signal()
                }
            }
        }
        Tab {
            id: tab2
            title: "Tab 2"
            signal tab2Signal
            onLoaded: {
                tab2Signal.connect(signalManager.tab2Signal)
                signalManager.tab1Signal.connect(tab2.item.onTab1Signal)
            }
            Item {
                function onTab1Signal() {
                    print("Tab 2 received Tab 1's signal")
                }
                Button {
                    text: "Send signal"
                    anchors.centerIn: parent
                    onClicked: tab2Signal()
                }
            }
        }
    }
}

因为active没有设置为true,所以第二个选项卡在启动时不会加载,所以它不会接收第一个选项卡的信号,直到它成为当前选项卡(即单击它)。也许这对您来说是可以接受的,所以我也记录了这个解决方案。

相关内容

  • 没有找到相关文章

最新更新