Qt图形图像开发之QT滚动区控件(滚动条)QScrollArea
的详细⽅法⽤法图解与实例
QT滚动区控件(滚动条控件)QScrollArea简介
滚动区域控件QScrollArea⽤于显⽰⼀个画⾯中的⼦部件的内容。如果部件超过画⾯的⼤⼩,视图可以提供滚动条,这样就可以看到部件的整个区域。
QScrollArea属于控件容器类,可以直接在ui中拖出来。
对于QScrollArea,最难搞懂的就是:如何控制它,才能让它在我们想要出现滚动条的时候出现滚动条。
我们拖⼊⼀个QScrollArea,再向他⾥⾯拖⼊4个button,观察信息如下:
可以发现,4个button并不是直接位于QScrollArea中的,⽽是位于它的成员scorllAreaWidgetContents中的,这个成员的类型也是控件类型QWidget,也就是说,QScrollArea这个容器本⾝就套了两层,我们放⼊的按钮等控件,都处在scrllAreaWidgetContents层,下⽂中我把QScrollArea.widget统⼀称之为“内部容器”或者"内容层",内部容器是QScrollArea这个控件的⼦控件。
"内容层"相当于⼀块很⼤的幕布,按钮、label等控件都被绘制在了幕布上,⽽QScrollArea相当于⼀个⼩窗⼝,透过这个⼩窗⼝我们看⼀看到幕布上的⼀⼩部分内容,拖动滚动条相当于在窗⼝后⾯移动幕布,这样我们就能透过窗⼝看到幕布上不同位置的内容。
这个幕布本质上就是⼀个QWidget,如果QScrollArea是从UI设计师界⾯拖出来的,那么QT会⾃动为我们创建这个幕布,如果你是⽤代码new出来的QScrollArea,那么不要忘记同时new⼀个幕布widget,并通过QScrollArea::setWidget(QWidget *)把幕布和QScrollArea关联起来。
这⾥有⼀个坑,如果你写了⼀个功能更强的QScrollArea的⼦类,假设叫QScrollAreaEx(⾥⾯⾃带幕布,幕布中⾃带⼀些按钮什么的),在ui设计师界⾯把QScrollArea提升为QScrollAreaEx的时候,你会发现,按钮并没有显⽰出来,why?因为QT ⾃动⽣成的ui代码中,new了⼀个幕布控件,并把这个空的幕布赋给了QScrollAreaEx对象,这真是太坑了。解决⽅案有两种,①⾃⼰⽤代码new QScrollAreaEx,②在ui中拖出⼀个⾮QScrollArea的QWidget控件,然后提升为QScrollAreaEx。
⼀旦理解了幕布和观察窗⼝的关系,就能很容易的总结出QScrollArea的标准编程步骤,分这么⼏种情况:QScrollArea纯代码实现
(1) new QscrollArea
(2) new 内部的幕布容器
(3) new 布局,例如⽹格布局QGridLayout(前3步不分先后顺序)或者你想⽤的其他布局
(4) 向布局中添加你想要的控件(这⼀步必须位于步骤3之后,这不是废话吗)
(5) 关联"幕布控件"和"布局"(如果在创建布局时,就把布局构造在了幕布控件中,那么这⼀步就省了)
(6) 给QScroolArea设置幕布,也即调⽤QScrollArea::setWidget(QWidget *),这⼀步必须位于步骤4、5之后。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHBoxLayout>
#include <QPushButton>
#include <QScrollArea>
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;
}
QScrollArea是直接从ui⾥拖出来
滚动区⾥⾯的控件是代码new的,那么编程步骤如下:
只做上⼀种情形的步骤(3)(4)(5)即可。
QScrollArea和它⾥⾯的控件都是直接在ui⾥拖出来的
这种情形不⽤写代码,只要在滚动区域把控件摆放好,然后使⽤任意⼀种布局即可,如下2图所⽰:
⼀句话总结QScrollArea何时出现滚动条
只要幕布控件scorllAreaWidgetContents的⼤⼩超过了QScrollArea的⼤⼩,就会⾃动出现滚动条;如果幕布⽐观察窗⼝还⼩,那就不会出现滚动条。
最后再看⼏个实例
我给scorllAreaWidgetContents成员设置宽⾼最⼩值为500*1000,这么⾼的scorllAreaWidgetContents,显然QScrollArea在⾼度上是⽆法容纳下的。实际上,看效果发现,还没有运⾏程序,就已经有滚动条了:
我们运⾏⼀下程序,然后把窗⼝缩⼩,看看是不是当窗⼝<scorllAreaWidgetContents最⼩值500*1000时,会⾃动出现⽔平滚动条。看下图发现,并没有出现我们期望的效果。
原因就是,⽔平滚动条,只有当QScrollArea<;内部的QWidget时,才会出现,显然上图中,QScrollArea虽然没显⽰全,但是QScrollArea的宽度仍然保持原值,只是被遮住了⽽已。要想使QScrollArea的宽度变⼩,要么通过程序直接修改,要么通过设置布局,使QScrollArea的宽度随窗体的宽度减⼩⽽减⼩。我们这⾥就简单⼀点,直接给窗体设置⽹格布局:
使得QScrollArea的⼤⼩受窗体⼤⼩驱动。运⾏起来,再看下效果:
再补充⼏点:
内部的⼩QWidget与QScrollArea的关系,就像是给QScrollArea设置了⽹格布局,然后把⼩QWidget放进了这个布局中,如果给⼩QWidget设置的最⼤宽⾼<QScrollArea的实时⼤⼩,那么QScrollArea会显⽰出空⽩,⽽空⽩部分是⽆法放置/显⽰我们⾃⼰拖⼊的控件的,如下图:
技巧:
通过上述操作,我们知道了,我们可以通过设置内部⼩QWidget的宽、⾼最⼩值,来让外部QScrollArea适时的出现滚动条,那么到底把⼩QWidget的宽、⾼最⼩值设置为多少合适呢?
答案是显然的:把⼩QWidget的宽、⾼最⼩值设置为刚好能容纳内部的按钮等控件,这样看起来最舒服。难道我要先计算或者观察⼀下按钮等控件占⽤的⾯积之后,才能去设置⼩QWidget的宽、⾼最⼩值吗?
这样做太费劲了,我们肯定不会去这样做,除⾮是⽤ui设计师拖控件时,所见即所得,才⽆需计算⼩QWidget的宽、⾼最⼩值。⽤代码写界⾯时,最好的做法是:
1、向⼩QWidget中添加按钮等控件时,随着添加的按钮增多,⼩QWidget⾃动变⼤,显然⽤QGridLayout来做就能实现这个⾃动增⼤这个需求。⾃动增⼤也只是出现创建内部容器阶段,⼀旦内部容器和布局、布局内的控件都创建和添加完毕,后续即使再向布局中添加控件,内部容器也不会⾃动增⼤了,这时只有靠setGeometry或者resize⼿动修改内部容器的⼤⼩了。
2、添加完控件后,⼿动调⽤⼀下adjustSize函数,该函数会根据所有⼦控件的⼤⼩之和,来调整⽗控件的⼤⼩。
步骤如下:先在ui中拖⼊⼀个QScrollArea控件,名字为scrollArea,然后添加代码:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGridLayout *pLayout = new QGridLayout();//⽹格布局
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);//把按钮添加到布局控件中
}
ui->scrollArea->widget()->setLayout(pLayout);//把布局放置到QScrollArea的内部QWidget中
}
本⽂主要讲解了QT滚动区控件(滚动条)QScrollArea的详细⽅法⽤法图解与实例,更多关于QT图形图像开发知识请查看下⾯的相关链接

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。