QML:使用ScrollView会导致元素显示不正确

时间:2014-07-17 04:36:18

标签: qt scrollview qml

我正在使用Qt 5.2.1 for windows(Qt creator 3.0.1)

我有一个自定义QML组件,当我加载到矩形时它可以正常工作:

import QtQuick 2.0
import QtQuick.Controls 1.1
Rectangle {
    id: mainRectangle
    anchors.fill: parent
        Loader {
            anchors.top: parent.top;
            anchors.left: parent.left;
            anchors.right: parent.right;
            id: ld01;
            onLoaded: {
                ld01.visible = true;
                anchors.top = parent.top;
            }
        }
        Loader {
            anchors.top: ld01.bottom;
            anchors.left: parent.left;
            anchors.right: parent.right;
            id: ld02;
            onLoaded: {
                anchors.top = ld01.bottom;
                ld02.visible = true;
            }
        }
        Component.onCompleted: {
            ld01.setSource("View_item2.qml");
            ld02.setSource("View_item2.qml");
        }
 }

但是当我试图将它全部放在ScrollView中时,我的组件元素会被移动到某处。我应该为正确使用ScrollView实现什么样的技巧?

ScrollView {
    id: mainTabLayout
    anchors.fill: parent
    anchors.margins: 4
    //here I put a code from above (except imports, of course)
}

组件代码如下:

import QtQuick 2.1
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.0

Rectangle {
    id: slv_layout
    objectName: "itemColumnLayout"
    anchors.left: parent.left
    anchors.right: parent.right
    anchors.margins: 1
    property int minimal_height: 200
    height: 400
    color: "green"
    MouseArea {
        property bool is_pressed: false
        property int initial_y: 0
        property int proposed_y: 0
        id: resizeStick
        enabled: true
        anchors.bottom: parent.bottom
        height: 10
        width: parent.width
        hoverEnabled: true
        onEntered: {
            cursorShape = Qt.SizeVerCursor;
        }
        onPressed: {
            is_pressed = true;
            initial_y = mouseY;
        }
        onReleased: {
            is_pressed = false;
        }
        onMouseYChanged: {
            if (is_pressed) {
                proposed_y = slv_layout.height + mouseY - initial_y;
                if (proposed_y >= slv_layout.minimal_height) {
                    slv_layout.height += (mouseY - initial_y);
                    initial_y = mouseY;
                }
            }
        }
    }

    Text {
        id: slvTitle
        text: "device name"
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.margins: 2
    }
    Rectangle {
        anchors.top: slvTitle.bottom
        anchors.left: parent.left
        anchors.bottom: parent.bottom
        anchors.right: parent.right
        anchors.topMargin: 2
        color: "blue"
        Button {
            id: slv_butt_run;
            objectName: "slv_butt_run"
            width: 60
            height: width
            text: "Run"
            anchors.top: parent.top
            anchors.left: parent.left
            anchors.margins: 2
        }
        Button {
            id: slv_butt_settings;
            objectName: "slv_butt_settings"
            width: 60
            height: width
            text: "Settings"
            anchors.top: parent.top
            anchors.left: slv_butt_run.right
            anchors.margins: 2
        }
        Button {
            id: slv_butt_stop;
            objectName: "slv_butt_stop"
            width: 60
            height: width
            text: "Stop"
            anchors.top: slv_butt_run.bottom
            anchors.left: parent.left
            anchors.margins: 2
        }
        Button {
            id: slv_butt_expand;
            objectName: "slv_butt_expand"
            width: 60
            height: width
            text: "Expand"
            anchors.top: slv_butt_settings.bottom
            anchors.left: slv_butt_stop.right
            anchors.margins: 2
        }
        TextArea {
            id: slv_log_area
            anchors.left: slv_butt_expand.right
            anchors.top: parent.top
            anchors.bottom: parent.bottom
            anchors.right: parent.right
            anchors.margins: 3
        }
    }
}

一切正常时的外观如何: How it looks when all is ok 不好的时候看起来怎么样: How it looks when not ok

2 个答案:

答案 0 :(得分:4)

实际上,我仍然不知道为什么代码如上所述。但我找到了可以用其他方式解决任务的可接受方法。

看起来"把针插入鸡蛋,鸡蛋放入鸭子,鸭子放入兔子": ScrollView必须包含一个ListView组件,该组件具有相应的ListModel,并且自定义组件应该充当委托。只有使用ListModel,我才能获得正确的自动滚动和相对安装支持。

ScrollView {
    id: id_scrollView
    anchors.fill: parent
    objectName: "ScrollView"
    frameVisible: true
    highlightOnFocus: true

    style: ScrollViewStyle {
        transientScrollBars: true
        handle: Item {
            implicitWidth: 14
            implicitHeight: 26
            Rectangle {
                color: "#424246"
                anchors.fill: parent
                anchors.topMargin: 6
                anchors.leftMargin: 4
                anchors.rightMargin: 4
                anchors.bottomMargin: 6
            }
        }
        scrollBarBackground: Item {
            implicitWidth: 14
            implicitHeight: 26
        }
    }

ListView {

    id: id_listView
    objectName: "ListView"
    anchors.top: parent.top
    anchors.left: parent.left
    anchors.right: parent.right
    anchors.rightMargin: 11
    flickableDirection: Flickable.VerticalFlick
    boundsBehavior: Flickable.StopAtBounds
    delegate: view_component
    model: id_listModel

    ListModel {
        id :id_listModel
        objectName: "ListModel"
    }

    //delegate: View_item2.Item
    Component {
        id: view_component
        View_item2 {
            objectName: name
        }
    }

}

答案 1 :(得分:3)

根据ScrollView documentation

  

ScrollView可用于替换Flickable或装饰现有的Flickable。 ...子项的宽度和高度将用于定义内容区域的大小。

ScrollView需要知道两个宽度 - 高度对:第一个是用于显示区域的宽度和高度,第二个是内容的宽度和高度。如果内容的区域大于显示区域,则显示区域将在其上添加滚动条。

在你的例子中:

ScrollView {
    id: mainTabLayout
    anchors.fill: parent
    //other properties

    Rectangle {
        id: mainRectangle
        anchors.fill: parent
        //...
    }
}

内容的宽度和高度绑定到显示区域,使两个区域的大小相同。显示区域的宽度和高度是mainTabLayout中的宽度和高度,它与它的父级绑定;内容的宽度和高度是mainRectangle中的内容,它与父亲mainTabLayout绑定。mainRectangle。因此ScrollView无法正常工作,因为ScrollView期望这两个值不同,而不是绑定在一起。

要解决您的问题,您可以明确指定mainRectangle的宽度和高度。不要使用anchors.fill:parentScrollView { id: mainTabLayout anchors.fill: parent //other properties Rectangle { id: mainRectangle width: 800; height: 800 //not binding to parent.width & height //... } } 的宽度和高度绑定到它的父级。

{{1}}

这可以正常工作。