QML:所有委托实例的触发功能

时间:2018-01-19 15:44:56

标签: qt qml components

我在google / stackoverflow上搜索了很多这个问题,但没有找到适合我的解决方案。我已经了解到,如果没有一些技巧,访问子ID /属性是不可行的。 我尝试使用多个别名属性,但我无法建立别名链,因为我无法在组件中定义属性。

我的问题是我有一个MainGrid.qml(GridView),它显示我的所有视频和一个Footer.qml,我想在其中实现一个播放栏。

GridView {


x: videoWallWindow.x
y: videoWallWindow.y
width: videoWallWindow.width
height: videoWallWindow.height
cellWidth: 300
cellHeight: 300

property alias deleg : loader.item

Loader {
    id: loader
    sourceComponent: videoDelegate
    visible: false
}

Component {
    id: videoDelegate
    Rectangle {
        id: container
        property alias streamVid : stream
        width: 256
        height: 240
        color: "#4f4f4f"
        border.color: "black"
        border.width: 3
        Stream {
            id: stream
        }

        Playbar {
            x: 0
            y: container.height - 20
            width: container.width
            height: 20
        }

        Text {
            id: textId
            text: name //defined in a ListModel

        }
    }
}

model: StreamList {}
delegate: videoDelegate
focus: true
}

(MainGrid.qml) (厌倦了别名属性,我的最后一次尝试是使用Loader)

ToolBar {

property MainGrid myGrid

id: footer
x: 0
y: window.height - footer.height
width: window.width
background: Rectangle {
    implicitHeight: 45
    color: "#212121"

    Rectangle {
        width: parent.width
        height: 1
        anchors.bottom: parent.bottom
        color: "transparent"
        border.color: "#212121"
    }
}

Row {
    anchors.centerIn: parent
    PlaybarButton {
        id: pauseButton
        height: footer.height
        width: footer.height

        property bool currentState: true

        onClicked: {
            currentState ? myGrid.deleg.streamVid.pause() : myGrid.deleg.streamVid.play() //<----- here is the problem
            currentState = !currentState
        }
        Image {
            id: pauseImage
            anchors.fill: parent
            source: parent.currentState ? ("pics/pause.png") : ("pics/play.png")
        }
    }
}
}

(Footer.qml)

Video {
id: streamVideo
width: mainGrid.cellWidth
height: mainGrid.cellHeight
anchors.fill: parent

source: portrait //defined as the path in a ListModel

MouseArea {
    anchors.fill: parent
    onClicked: {
        video.playbackState == MediaPlayer.PlayingState ? video.pause() : video.play()
    }
}
autoPlay: true
loops: MediaPlayer.Infinite
focus: true

}

(Stream.qml)

ApplicationWindow {
id: window
visible: true

width: Screen.desktopAvailableWidth
height: Screen.desktopAvailableHeight

...
MainGrid {
    id: mainGrid
}

Footer {
    id: footer
    myGrid: mainGrid
}
}

(main.qml)

所以我希望代码足够可读。任何人都可以帮我弄清楚如何从我的GridView(MainGrid.qml)中正确访问Footer.qml中的视频/流。或者我是否必须完全重建我当前的程序?

提前致谢

1 个答案:

答案 0 :(得分:1)

您无法从外部访问委托内的任何内容,因为委托只是要创建的对象的原型。您只能访问委托实际实例对象中的内容。

然而,代理人仍然可以访问它们之外的东西,因为那是定义的对象结构。

由于您要做的是播放或暂停每个委托中的所有视频,最简单的解决方案是绑定到对象树下某处的外部属性或信号。例如:

// in main.qml
signal togglePlayback

// in delegate
Connections {
  target: mainQMLFile
  onTogglePlayback: video.playbackState == MediaPlayer.PlayingState ? video.pause() : video.play()
}

您还可以通过信号传递实际值,并检查是否在所有代表中获得一致的行为,因为您获得状态不匹配的奇怪机会,以便实现一致的状态,而不是仅仅在播放和暂停之间切换。