问题
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:
- 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()
}
}
}
}
}
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