如何在 TabView 的选项卡之间发送信号(Qt5) [英] How to send signals between tabs of 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.
是的,但它有点棘手.首先,请记住 Tab 是Loader,所以你的 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:
- 在每个
Tab
中将active
设置为true
,或 - 添加一个解决此问题的中间项目
- Set
active
totrue
in eachTab
, or - 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屋!