How to send signals between tabs of TabView (Qt5)

回眸只為那壹抹淺笑 提交于 2020-01-11 04:05:15

问题


I have TabView with two tabs. Each tab has Item element (which contains other stuff). I need to send signal from one tab and to catch (to handle) it in other tab.

If I try to send signal from one Tab (Item) to other - it doesn't work, without showing of any errors.

I found a way to send signal out from tab to TabView scope using Connections as written here (http://qt-project.org/doc/qt-5/qml-qtquick-loader.html).

declare in the first tab signal:

signal message()

Make a call in this tab (in onClicked handler? for example):

onClicked: {
    nameOfItemInFirstTab.message()
}

In TabView scope I declared Connections:

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

Using this way, it's possible to catch the signal out of the first tab. But how, now, to send signal to the second tab? Is there another way to do it?


回答1:


You can do it like this:

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()
                }
            }
        }
    }
}

The functions can of course be named anything; I only prefixed them with "on" because that's the convention for signal handler names.

For more information on connecting signals in QML, see Connecting Signals to Methods and Signals.


Is it possible to make a onTab1Signal() in Item? I need to send some information (String/int) to elements of Item of tab2.

Yes, but it's a bit trickier. First of all, remember that Tab is a Loader, so your Item declared inside it may not always be valid. In fact, if you look at the implementation of Tab, you'll see that it sets its active property to false, effectively meaning that tab content is loaded only after that tab has been made current (a design called lazy loading). A naive implementation (i.e my first attempt :p) will encounter strange errors, so you must either:

  1. Set active to true in each Tab, or
  2. Add an intermediate item that accounts for this

The first solution is the easiest:

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()
                }
            }
        }
    }
}

The second solution is slightly more difficult, and comes with a caveat:

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()
                }
            }
        }
    }
}

Because active isn't set to true, the second tab isn't loaded at start up, so it won't receive the first tab's signals until it's made current (i.e by clicking on it). Perhaps that's acceptable for you, so I documented this solution as well.



来源:https://stackoverflow.com/questions/26014363/how-to-send-signals-between-tabs-of-tabview-qt5

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!