如何在 TabView 的选项卡之间发送信号(Qt5) [英] How to send signals between tabs of TabView (Qt5)

查看:10
本文介绍了如何在 TabView 的选项卡之间发送信号(Qt5)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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).

在第一个 tab 信号中声明:

declare in the first tab signal:

signal message()

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

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

onClicked: {
    nameOfItemInFirstTab.message()
}

在 TabView 范围内我声明了 Connections:

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?

推荐答案

你可以这样做:

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",因为这是信号处理程序名称的约定.

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

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

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

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

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

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

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. 在每个 Tab 中将 active 设置为 true,或
  2. 添加一个解决此问题的中间项目
  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()
                }
            }
        }
    }
}

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

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.

这篇关于如何在 TabView 的选项卡之间发送信号(Qt5)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆