【问题标题】:Center elements inside ScrollviewScrollview 中的中心元素
【发布时间】:2016-02-27 23:01:41
【问题描述】:

ScrollView 中将 QML 对象居中时遇到问题。我想滚动图像和其他 QML 元素,它们应该居中。但它们总是粘在左上角。

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0

ApplicationWindow{
    id: appWindow
    width:Screen.width
    height:Screen.height
    visible: true
    ScrollView {
        anchors.fill: parent
        Rectangle {
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.verticalCenter: parent.verticalCenter
            width: 800
            height: 800
            color : "yellow"
        }
    }
}

【问题讨论】:

    标签: qml scrollview qt5 rectangles center-align


    【解决方案1】:

    您需要考虑两个方面。直接来自docs

    只有一个 Item 可以是 ScrollView 的直接子项,并且子项被隐式锚定以填充滚动视图。

    所以你不能有多个Rectangle,只是所有Rectangles(实际上是图像,如你的问题所述)的容器。

    此外,应再次从文档中指出:

    子项的宽度和高度将用于定义内容区域的大小

    因此,ScrollView 只需要一个孩子,并确保它从父母那里得到正确的大小。为此,我会使用ColumnLayout。最终示例代码在这里:

    import QtQuick 2.2
    import QtQuick.Controls 1.1
    import QtQuick.Window 2.0
    import QtQuick.Layouts 1.1
    
    ApplicationWindow{
        id: appWindow
        width: 200
        height: 100
        visible: true
        ScrollView {
            anchors.fill: parent
    
            ColumnLayout {                  // unique child
                spacing: 10
                width: appWindow.width      // ensure correct width
                height: children.height     // ensure correct height
    
                // your children hereon...
                Repeater {
                    model: 4
                    delegate: Rectangle  {
                        Layout.alignment: Qt.AlignHCenter
                        width: 50
                        height: 50
                        color : "yellow"
                    }
                }
            }
        }
    }
    

    编辑

    根据 OP,提供的解决方案不能完全满足他的需求,这很合理。特别是:

    1. 如果水平调整窗口大小,则不显示水平滚动条
    2. 一显示垂直滚动条就会显示水平滚动条

    这两个问题都与使用的方法有关。问题1是由父widthScrollViewwidth之间的绑定引起的:因为可见width总是等于总width,所以即使包含的项目是比窗户大。问题2是1的结果:由于width等于应用程序,所以只要添加了垂直滚动条,水平的也会添加以显示垂直滚动条覆盖的水平空间。

    这两个问题都可以通过将width 绑定更改为等于包含的项目width(解决问题1)或等于viewportwidth(解决问题2)来解决,正如this other answer 中所讨论的那样。最后,应移除锚定以避免绑定循环。这是一个按预期工作的完整示例:

    import QtQuick 2.5
    import QtQuick.Controls 1.4
    import QtQuick.Window 2.2
    import QtQuick.Layouts 1.1
    
    ApplicationWindow{
        id: appWindow
        width: 200
        height: 100
        visible: true
    
        ScrollView {
            id: scroller
            width: appWindow.width          // NO ANCHORING TO AVOID binding loops!
            height: appWindow.height
    
            ColumnLayout {     // <--- unique child
                spacing: 10
                width: Math.max(scroller.viewport.width, implicitWidth)      // ensure correct width
                height: children.height                                      // ensure correct height
    
                // your children hereon...
                Repeater {
                    model: 3
                    delegate: Rectangle  {                  
                        Layout.alignment: Qt.AlignHCenter
                        width: 150
                        height: 150
                        color : "yellow"
                    }
                }
            }
        }
    }
    

    绑定到窗口width水平滚动不显示,即使包含的项目大于窗口

    【讨论】:

    • 如何让它居中?我检查你的代码并得到结果:左上角。
    • 为什么要编辑代码?它在我的机器上完美运行,width: appWindow.width。您正在转发布局的宽度,因为它应该与ScrollView 的父项一样大,在本例中为ApplicationWindow。坚持示例,然后适应您的需求。
    • 为您的代码尝试我的测试:1. 设置:id:appWindow 宽度:700 高度:500 尝试仅水平调整大小以最小化窗口(我得到:窗口不滚动 - 这是错误)2 . 设置:id:appWindow 宽度:700 高度:500 并尝试仅垂直调整大小以最小化窗口(我得到:滚动水平侧 - 这是错误)
    • 这就是原因。在您的情况下,一侧调整大小无法正常工作。
    • 第二个不是错误:由于内容区域由所有可用空间给出(正如我定义的示例),你会得到水平滚动条:垂直滚动条覆盖了部分可见区域来自ScrollBar pov。我看到了第一个案例的问题。问题是,ScrollView 滚动条粘在内容上(参见文档图片);因为我们伪造了项目居中的宽度,但我们失去了在调整大小时水平滚动的能力。我认为它可以重新考虑。也许采用不同的方法,例如使用Flickable + 自定义滚动条会是更好的方法。
    【解决方案2】:

    来自文档 (http://qt-project.org/doc/qt-5/qml-qtquick-controls-scrollview.html):

    只有一个 Item 可以是 ScrollView 的直接子项,并且 该子项被隐式锚定以填充滚动视图。

    所以你无法通过锚定内容来实现你想要的。您必须更改 ScrollView 的大小和锚点

    例如:

    ApplicationWindow{
        id: appWindow;
        width:Screen.width;
        height:Screen.height;
        visible: true;
    
        ScrollView
        {
            anchors.centerIn: parent;
            width: Math.min(content.width + 30, appWindow.width);
            height: Math.min(content.height, appWindow.height);
    
            Rectangle
            {
                id: content;
                width: 800;
                height: 800;
                color : "yellow"
            }
        }
    }
    

    【讨论】:

    • 不是跨平台解决方案
    【解决方案3】:

    您可以插入Rectangle 或您喜欢的其他类似QML 项目作为ScrollView 和您需要居中的QML 项目之间的中间层,并将其颜色设置为“透明”。这应该是一个跨平台的解决方案。

    我已经修改了你的代码,例如:

    import QtQuick 2.2
    import QtQuick.Controls 1.1
    import QtQuick.Window 2.0
    
    ApplicationWindow {
    
        id: appWindow
    
        width:Screen.width
        height:Screen.height
    
        visible: true
    
        ScrollView {
            anchors.fill: parent
    
            Rectangle {
                width:  Math.max(appWindow.width, rect.width)
                height: Math.max(appWindow.height, rect.height)
    
                color: "transparent"
    
                Rectangle {
                    id: rect
    
                    anchors.centerIn: parent
    
                    width: 800
                    height: 800
    
                    color : "yellow"
                }
            }
        }
    }
    

    我使用 Qt 5.5。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-15
      • 2011-10-12
      • 2012-10-09
      • 2011-06-16
      • 2014-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多