[英]Change children property when parent property changes in QML
我有3個檔案。 main.qml,Guide.qml和ChannelViewer.qml我的主類包含2個組件和一個加載器,這里是代碼
main.qml
import QtQuick 2.0
Rectangle {
id:loader
color: "black"
property string channelName
property string channelURL
Component{
id:tv
ChannelViewer{}
}
Component{
id:guide
Guide{}
}
Loader
{
id: pageLoader
anchors.fill:parent
focus:true
sourceComponent: tv
}
Connections{
target:pageLoader.item
onChangeChannel:{
channelName=name
channelURL=url
}
}
Keys.onPressed: {
event.accepted = true;
if (event.key === Qt.Key_I) {
pageLoader.sourceComponent = tv;
}
else if(event.key === Qt.Key_G) {
pageLoader.sourceComponent = guide;
}
}
}
現在,如果我按“ G”,我將被無任何問題地移動到指南文件中。在我的指南頁面中,我能夠向main.qml發送信號並更新main中的name屬性。
Guide.qml
Item {
signal changeChannel(string url, string name)
Loader {
id: pageLoader
anchors.fill:parent
sourceComponent: guide
focus:true
}
Keys.onPressed: {
if(event.key === Qt.Key_Escape) {
pageLoader.source = "main.qml";
}
event.accepted = true;
}
Component {
id:guide
Rectangle {
color:"lightblue"
Keys.onPressed: {
if(event.key === Qt.Key_Return) {
changeChannel(menuContent.currentItem.ch_url, menuContent.currentItem.ch_name)
pageLoader.source = "main.qml";
}
event.accepted = true;
}
}
}
}
但是現在當我在Guide.qml中按“ Return”時,我將被帶回到main.qml(Channelname和ChannelURL將被成功更新),而我的main.qml現在將帶我到ChannelViewer.qml,這就是問題所在我的ChannelViewer.qml將不會收到更新的channelName和channelURL。 而且我不確定我在做什么錯。
ChannelViewer.qml
import QtQuick 2.0
import VLCQt 1.0
Rectangle {
id:root
width: 640
height: 480
color: "black"
focus:true
Loader
{
id: pageLoader
anchors.fill:parent
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log(channelURL)
}
}
Keys.onPressed: {
if (event.key === Qt.Key_I) {
event.accepted = true;
if(channelInfo.visible === true) {
channelInfo.visible=false;
}
else {
channelInfo.visible=true;
}
}
}
VlcVideoPlayer {
id: vidwidget
anchors.fill: parent
url:channelURL
ChannelInfo{
id:channelInfo
anchors.bottom: parent.bottom
anchors.bottomMargin: ((parent.height*5)/100)
anchors.horizontalCenter: parent.horizontalCenter
width:parent.width - ((parent.width*10)/100)
height: (parent.height*20)/100
backgroundOpacity: 0.7
radius:10
channelNameProp: channelName
channelNumberProp: "1"
headerIcon: "imgs/television_32x32.png"
}
}
}
編輯:我的ChannelInfo.qml的代碼
import QtQuick 2.0
Item {
id:channelinfo
property color backgroundColor: "blue"
property color headerBackgroundColor: "lightblue"
property color headerNameColor: "black"
property color borderColor: "black"
property color channelNameColor: "white"
property color channelNumberColor: "white"
property real borderWidth:0
property real radius:0
property real backgroundOpacity: 0.5
property string menuTitle : "TV Channels"
property string channelNameProp
property string channelNumberProp
property url headerIcon: "imgs/television.png"
visible:false
Rectangle{
id:root
width:channelinfo.width
height:channelinfo.height
color:channelinfo.backgroundColor
border.color:channelinfo.borderColor
border.width: channelinfo.borderWidth
radius:channelinfo.radius
opacity:channelinfo.backgroundOpacity
visible: parent.visible
Rectangle{
id:header
anchors.top:parent.top
// width:(parent.width*40)/100
width: parent.width
height: (parent.height*30)/100
radius: channelinfo.radius
color:channelinfo.headerBackgroundColor
Image{
source:channelinfo.headerIcon
anchors.left: parent.left
anchors.leftMargin: 10
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: -4
}
Text{
id:headerTitle
anchors.left: parent.left
anchors.leftMargin: 50
anchors.verticalCenter: parent.verticalCenter
width:parent.width
wrapMode: Text.WordWrap
color:channelinfo.headerNameColor
text:menuTitle
font.pixelSize: Math.round(parent.height/2)
font.bold: true
}
}
Rectangle{
id:content
anchors.bottom: parent.bottom
width:parent.width
height:parent.height-header.height
color:"transparent"
Text{
id:channelName
anchors.left: parent.left
anchors.leftMargin: 50
anchors.verticalCenter: parent.verticalCenter
color:channelinfo.channelNameColor
text:channelNameProp
font.pixelSize: Math.round(parent.height/4)
font.bold: true
}
Text{
id:channelNumber
anchors.right: parent.right
anchors.rightMargin: 20
anchors.verticalCenter: parent.verticalCenter
color:channelinfo.channelNumberColor
text:channelNumberProp
font.pixelSize: Math.round(parent.height/4)
font.bold: true
}
}
}
}
VLCPlayer的Github頁面https://github.com/vlc-qt/
如果您將要具有這樣的固定結構,為什么還要打擾信號,您也可以簡單地:
Keys.onPressed: {
if(event.key === Qt.Key_Return) {
channelName = menuContent.currentItem.ch_name
channelURL = menuContent.currentItem.ch_url
pageLoader.source = "main.qml";
}
event.accepted = true;
}
然后刪除不必要的部分:
Connections{
target:pageLoader.item
onChangeChannel:{
channelName=name
channelURL=url
}
}
由於channelName
和channelURL
是在channelURL
文件的根對象中聲明的,因此由於動態作用域,應該可以從嵌套在樹上的對象中訪問它們。
因此,發布相關代碼后,您將擁有:
Text{
id:channelName
在您的ChannelInfo
對象中,該對象遮蓋了main.qml
聲明的channelName
屬性。 養成一致的命名約定的習慣是一個好主意。 例如,由於這是一個ID,因此我個人會使用id: _cName
,這樣可以最大程度地減少發生此類沖突的幾率。
更新:
我能想到為什么它不起作用的唯一另一個原因是,您正在通過執行諸如channelNameProp = something
類的方法來破壞channelNameProp: channelName
綁定。
這是一個簡單的示例,說明即使在涉及動態更改Loader項的情況下,動態范圍也適用 (只要您不遮擋任何東西):
// main.qml
ApplicationWindow {
id: _cName
visible: true
width: 640
height: 480
property int value: 0
Loader {
id: loader
source: "Obj.qml"
}
}
// Rect.qml
Rectangle {
id: rectangle
width: 50; height: 100
color: "red"
Text {
anchors.centerIn: parent
text: value
}
MouseArea {
anchors.fill: parent
onClicked: {
loader.source = "Obj.qml"
}
}
}
// Obj.qml
Rectangle {
id: rectangle
width: 50; height: 100
color: "blue"
MouseArea {
anchors.fill: parent
onClicked: {
value++
loader.source = "Rect.qml"
}
}
}
作為屬性
property string channelName
property string channelURL
具有更改信號並因此支持屬性綁定,我認為最簡單的方法是將第9-17行更改為
Component{
id:tv
ChannelViewer {
id: channelViewer
channelName: loader.channelName
channelURL: loader.channelURL
}
}
Component{
id:guide
Guide {
id: guide
channelName: loader.channelName
channelURL: loader.channelURL
}
}
如果Guide更改了channelName,則需要確保在loader
對其進行更改。 您可以使用Binding
-objects使綁定在分配( =
)中保留。
所以這個工作,你需要創建的屬性channelName
和channelURL
在你的根節點Guide.qml
ABD你ChannelViewer.qml
。 然后,在這些文件里每一個地方,你可以使用完全合格的標識符: id.propertyName
,這將是如channelinfo.channelName
在ChannelInfo.qml
, root.channelName
在ChannelViewer.qml
和一個id,你將需要設置(如再次root)在Guid.qml
> root.channelName
。
- 對綁定使用完全合格的標識符(該標識符始終包括
idOfTheObject.propertyName
有助於避免出現問題。 在某些情況下(定位,定位,調整大小),parent
還可以,但是您可能不知道父級到底是什么。- 如果您確切知道代碼的使用方式和位置(例如,它本質上是較大對象的部分定義,並且永遠不會在其他上下文中使用),則動態范圍是一種幸運。 但是在這里您需要知道,如果父文件更改了內部api,則需要相應地修改子文件。 如果您認為該文件可能要重用,請避免動態作用域,而僅引用文件中定義的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.