使用 QScrollArea 和 QQuickWidget

Posted

技术标签:

【中文标题】使用 QScrollArea 和 QQuickWidget【英文标题】:Using QScrollArea with QQuickWidget 【发布时间】:2016-03-07 15:22:50 【问题描述】:

我有一个 QQuickWidget。我想根据其 QML 内容使其自动调整大小,并提供水平和垂直滚动条以防其内容无法适应窗口。

我将 QQuickWidget 放在 QScrollArea 中,并向 QScrollArea 添加布局以使 QQuickWidget 填充它。在父窗口构造函数中我添加了一行:

scroll_area->setWidget(quick_widget);

但是没有滚动条可用,与 QML 内容大小无关。 QQuickWidget 和 QScrollArea 应该如何配置为我需要的工作?

UPDATE1:嗯,我正在尝试通过 QDesigner 来实现。实际的 UI XML 是:

<widget class="QScrollArea" name="scroll_area">
 <property name="sizePolicy">
  <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
   <horstretch>0</horstretch>
   <verstretch>0</verstretch>
  </sizepolicy>
 </property>
 <property name="widgetResizable">
  <bool>true</bool>
 </property>
 <widget class="QQuickWidget" name="quick_widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>502</width>
    <height>269</height>
   </rect>
  </property>
  <property name="sizePolicy">
   <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
    <horstretch>0</horstretch>
    <verstretch>0</verstretch>
   </sizepolicy>
  </property>
  <property name="resizeMode">
   <enum>QQuickWidget::SizeViewToRootObject</enum>
  </property>
  <property name="source">
   <url>
    <string>…</string>
   </url>
  </property>
 </widget>
</widget>

在调试时,我可以看到 QScrollArea.widget() 已经设置为 quick_widget(没有强制调用 scroll_area.setWidget()),但仍然没有可用的滚动条,即使 quick_widget 内容不适合它的大小。

UPDATE2:动态添加项目可能存在问题。也许应该手动修改根对象的高度和宽度(或者不应该?)例如:

if ( object.x + object.width > root.width )
    root.width = object.x + object.width;
if ( object.y + object.height > root.height )
    root.height = object.y + object.height;

【问题讨论】:

【参考方案1】:

我试过下面的代码,效果很好。

//mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

    ui->setupUi(this);

    auto scrollArea = new QScrollArea();
    setCentralWidget(scrollArea);

    auto quickWidget = new QQuickWidget();
    quickWidget->setSource(QUrl("qrc:/main.qml"));
    quickWidget->setResizeMode(QQuickWidget::SizeViewToRootObject);
    scrollArea->setWidget(quickWidget);

//main.qml
//a varying Rectangle
import QtQuick 2.0

Rectangle 
    id: root ;color: "red"; width: 400; height: 500
    Timer
        id: timer
        property real time
        interval: 400
        repeat: true
        onTriggered: 
            root.width = 800 + Math.sin(time*100) *100
            time = time + 1;
            console.log(time)
        
    

    Component.onCompleted: 
        timer.time = 0
        timer.start()
    

【讨论】:

【参考方案2】:

您必须将QScrollAreawidgetResizable 属性设置为false(默认为true)。

您可能还想将水平和垂直对齐方式分别设置为AlignLeftAlignTop

See the docs for widgetResizable property

【讨论】:

以上是关于使用 QScrollArea 和 QQuickWidget的主要内容,如果未能解决你的问题,请参考以下文章

使用 QScrollArea 时发生错误

7.3 QScrollArea滚动视图

QScrollArea可以帮助我们实现让一个widget的内容带有滚动条(QWidget里内置QScrollArea,QScrollArea里再内置其它QWidget)

Qt中QScrollArea类的简单使用心得

将小部件放在 QScrollArea 的中心

PyQt:QScrollArea 内小部件的环绕式布局