QT的自动滚动区QScrollArea的用法,图文详解

您所在的位置:网站首页 滚动界面 QT的自动滚动区QScrollArea的用法,图文详解

QT的自动滚动区QScrollArea的用法,图文详解

2023-09-06 06:17| 来源: 网络整理| 查看: 265

转自 https://blog.csdn.net/qq_31073871/article/details/83117430

QScrollArea属于控件容器类,可以直接在ui中拖出来。

对于QScrollArea,最难搞懂的就是:如何控制它,才能让它在我们想要出现滚动条的时候出现滚动条。

我们拖入一个QScrollArea,再向他里面拖入4个button,观察信息如下:

可以发现,4个button并不是直接位于QScrollArea中的,而是位于它的成员scorllAreaWidgetContents中的,这个成员的类型也是控件类型QWidget,也就是说,QScrollArea这个容器本身就套了两层,我们放入的按钮等控件,都处在scrllAreaWidgetContents层,下文中我把QScrollArea.widget统一称之为“内部容器”,内部容器是QScrollArea这个控件的子控件。

补充一点,内层的这个scrllAreaWidgetContents,我们可以更换掉它,方法就是QScrollArea::setWidget(QWidget *),如果scrollArea控件是用鼠标拖出来的,那么QT会自动为我们new一个内部容器,如果scrollArea控件是用代码创建的,那么不忘忘了为这个滚动区创建内部容器。

帮助文档还指出,setWidget应当在“把想加的控件都加到内部容器”之后再调用,否则会无法显示(然而,我测试发现,帮助说的不对,即使我们在setWidget之前没有给内部容器设置布局也不要紧,只要在setWidget之后,内部容器调用一下adjustSize,就可以把内部容器的控件显示出来,当然,为了保险起见,或者后续程序兼容性起见,还是按照帮助文档来做吧)。

总结一下滚动区的标准编程步骤:

(1)new QscrollArea (2)new 内部容器 (3)new 布局,例如网格布局QGridLayout(前3步不分先后顺序) (4)向布局中添加你想要的控件(这一步必须位于步骤3之后,这不是废话吗) (5)关联"内部容器"和"布局"(如果在创建布局时,就把布局构造在了内部容器中,那么这一步就省了) (6)关联"内部容器"和"滚动区",也即调用QScrollArea::setWidget(QWidget *),这一步必须位于步骤4、5之后。

 

 

一句话总结何时出现滚动条:

只要QScrollArea的尺寸 < 内部容器的尺寸,就会自动出现滚动条。下面举个具体的例子:

程序初始时我们通过setGeometry设置内部容器的尺寸为100X100,QScrollArea放置在主界面的布局中,也即QScrollArea的尺寸是随着用户鼠标拖动窗口变化而变化的,那么当用户拖大窗口时,QScrollArea也变得很大,而内部容器还是100X100,这时,滚动条就消失了;如果用户用鼠标缩小了窗口,QScrollArea也随之变的很小了,而内部容器还是100X100,QScrollArea就会自动出现滚动条。

记住一句话,除非你在程序运行时修改了内部容器的大小,否则,内部容器将一直保持它初始的大小。那么

 

 

下面讲如何控制滚动条何时出现?

有了上面的分析,我们已经知道了QScrollArea有两层,QScrollArea本身是个QWidget,它内部又套了一个小QWidget。在默认情况下,内部的这个小QWidget,也即scorllAreaWidgetContents,它的大小总是等于外部QWidget(也即QScrollArea)的大小。除非我们给scorllAreaWidgetContents设置了宽高的最小值,这时,当QScrollArea的宽或高,一旦小于scorllAreaWidgetContents的宽或高,就会出现滚动条。

这个scorllAreaWidgetContents是从哪来的?查看QT自动生成的ui代码(也即:ui->setupUi(this)函数)可见,它是在QScrollArea构造完成之后,再被new出来的,然后调用了QScrollArea::setWidget()。这一点对于我们编程非常重要,否则一不小心就中了坑,假设我们自己继承QScrollArea写了一个新的子类,在子类的构造函数中我们通过QScrollArea::setWidget()设置好了自己的小QWidget,然后在ui中把QScrollArea提升为自己写的这个子类,这时就扯淡了,我们在子类构造函数中为小QWidget添加的控件都没有显示出来,因为QT自作主张,在我们自己的构造函数执行完之后,重新new了小QWidget,并通过setWidget函数设置给了这个子类!这真是太坑了。如果你想通过ui提升的方式来使用自己写的子类,那么请你在ui拖入一个Frame容器或者widget容器等等进行提升,反正不要用拖入的QScrollArea容器进行提升。如果你非得想用QScrollArea容器进行提升,那么你想在QScrollArea的内部容器中添加控件时,请不要把添加控件的代码写在QScrollArea子类的构造函数中。

下面继续研究滚动条问题。

直接看例子,我给scorllAreaWidgetContents成员设置宽高最小值为500*1000,这么高的scorllAreaWidgetContents,显然QScrollArea在高度上是无法容纳下的。实际上,看效果发现,还没有运行程序,就已经有滚动条了

我们运行一下程序,然后把窗口缩小,看看是不是当窗口setMinimumSize(QSize(60,30)); //width height pLayout->addWidget(pBtn);//把按钮添加到布局控件中 } ui->scrollArea->widget()->setLayout(pLayout);//把布局放置到QScrollArea的内部QWidget中 }

 根据原著者的描述,转载人补充如下代码,展示在不使用ui拖拽的情况下,实现滚动条:

#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QScrollArea * scrollArea = new QScrollArea(this); QWidget * pWgt = new QWidget; QHBoxLayout *pLayout = new QHBoxLayout();//网格布局 for(int i = 0; i < 100; i++) { QPushButton *pBtn = new QPushButton(); pBtn->setText(QString("按钮%1").arg(i)); pBtn->setMinimumSize(QSize(60,30)); //width height pLayout->addWidget(pBtn);//把按钮添加到布局控件中 } pWgt->setLayout(pLayout); //这一句setWidget必须放在pWgt里面的内容都准备完毕之后,否则显示有问题 scrollArea->setWidget(pWgt); setCentralWidget(scrollArea); } MainWindow::~MainWindow() { delete ui; }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3