2017-08-03 21 views
0

私は3つのファイルを持っています。 main.qml、Guide.qmlとChannelViewer.qml 私のメインクラスは、2つのコンポーネントが含まれており、ここでのローダは今、私は希望 "G" を押すと、コードQMLで親プロパティが変更されたときに子プロパティを変更します

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; 
     } 
    } 
} 

です私のガイドページでは、main.qmlに信号を送り、mainのnameプロパティを更新することができます。

Guide.qml私はGuide.qmlで「戻る」を押したときに、今私はmain.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; 
      } 
     } 
    } 
} 

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

EDIT:私の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 
      } 
     } 
    } 
} 

GithubのページのプロパティとしてVLCPlayer ためhttps://github.com/vlc-qt/

答えて

1

、なぜさえ、信号を気にしますが、単純にすることができ

Connections{ 
    target:pageLoader.item 
    onChangeChannel:{ 
     channelName=name 
     channelURL=url 
    } 
} 

channelNamechannelURLはqmlファイルのルートオブジェクトで宣言されているため、ツリーベクタの上にネストされたオブジェクト内からアクセス可能である必要があります動的スコープの使用。あなたは、関連するコードを掲載した後

だから、あなたが持っている:main.qmlで宣言さchannelNameプロパティをシャドウイングされたあなたのChannelInfoオブジェクト、中

 Text{ 
      id:channelName 

。一貫した命名規則の習慣を開発することをお勧めします。たとえば、これはIDなので、私は個人的にid: _cNameを使用していました。このようにして、そのような衝突を得る確率を最小限に抑えます。

更新:それは動作しませんなぜ私が考えることができます

唯一の他の理由は、あなたがどこかにchannelNameProp = somethingような何かをすることによって結合channelNameProp: channelNameを壊しているということです。残念ながら、私が持っている

// 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" 
    } 
    } 
} 
+0

ダイナミックスコープに頼らないように努力する必要があるので、私は信号を好むでしょう。双方向バインディングはより良いかもしれませんが、信号はIMHOの良いスタートです。 – derM

+0

"動的スコープに頼らないように努力する必要があります" - なぜですか?バインドする前に – dtech

+0

私はこれを試してもうまくいきませんでした。私はもう一度試してみましたが、それでも同じです。 main.qmlはGuide.qmlから更新された値を取得しますが、ChannelViewerは更新された値を取得しません。 –

0

property string channelName 
property string channelURL 

は変更信号を持っているので、結合性をサポートし、私は最も簡単な方法は、ガイドがCHANNELNAMEを変更した場合、あなたはそれを変更することを確認する必要があり

Component{ 
    id:tv 
    ChannelViewer { 
     id: channelViewer 
     channelName: loader.channelName 
     channelURL: loader.channelURL 
    } 
} 

Component{ 
    id:guide 
    Guide { 
     id: guide 
     channelName: loader.channelName 
     channelURL: loader.channelURL 
    } 
} 

に行9-17を変更することだと思いますloader。バインディングを割り当てのままにするにはBinding -objectsを使用します(=)。

だから、この作品は、あなたのGuide.qml ABDあなたChannelViewer.qmlのルートノードでプロパティchannelNamechannelURLを作成する必要があります。これらのファイル内の各場所で、のchannelinfo.channelNameChannelViewer.qmlroot.channelName、およびGuid.qml - >root.channelNameに設定する必要があるID(例:root)を入力する完全修飾ID:id.propertyNameを使用します。常にidOfTheObject.propertyNameが含まバインディングの完全修飾識別子の

  • 使用法は、問題を回避するのに役立ちます。場合によっては、parentは大丈夫ですが、親が正確に何であるかわからない場合があります)
  • 動的スコープは、コードの使用方法と場所を正確に知っていれば祝福です。本質的により大きいオブジェクトの部分的な定義であり、別のコンテキストでは使用されません。しかしここでは、親ファイルが内部APIを変更した場合、それに応じて子ファイルを適合させる必要があることを知る必要があります。あなたが思うなら、ファイルは再利用のためであり、動的スコープを避け、ファイル内で定義されているものだけを参照するかもしれません。

    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; 
          } 
    

    そして、不要な部分削除:あなたは、このような固定構造を持ってしようとしている場合は

+0

:ここ

も、動的ローダーのアイテムを変更するような状況では、(限り、あなたは何をシャドウしていないとして)動的スコープがちょうどを動作することを示すために簡単な例であります前にこの方法を試してみて、うまくいかなかった。 channelNameは存在しないプロパティです。おそらく私は何か間違っているのですか? –

+0

ああ、そうです。 'ChannelViewer.qml'には' channelName'がなく、 'Guide.qml'にはありません。ファイルルートノードのプロパティのみを設定できます。 – derM

+0

「ChannelInfo」、「VlcVideoPlayer」のいずれかのコードにリンクしていますか?バインディングを設定する場所と同じファイルで宣言されていないプロパティへのバインドを避けてください。ファイルのルートノードに内部プロパティをバインドするプロパティを作成します。次に、コンポーネントを使用するときに適切に設定することができます。 – derM

関連する問題