Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i make widgets overflow to make a scrollbar appear in Qt?

The structure of my widgets is :

QWidget customized to be a panel with rounded borders.

To contain an area with scrollbar inside the borders with a margin, then I put this inside:

QScrollArea with a QVBoxLayout (vertically adding content)

Then I add inside of it a series of :

QGroupBox with title with spacing 0, and a QFormLayout

The formlayout doesn´t work as I thought it would. The widgets inside are the labels + spinboxes, all of them.

Here's an image:

Image

First. They are not centered. I don´t know why.

Second. They are all given the same fixed size, as I told them, but they are piled anyway, not squashed, so they hide each other. Why doesn´t it stay that size and the parent QScrollArea shows the scrollbar outside?. That´s what i want.

I don´t want the contents to be squashed or stretched. I want them to be on the top. If the screen is very big, the panel will be long, but the contents will be on the top, allways with the same size.


Somebody requested the code, so i copy it here, but the code it really big... I think it's more confusing. But well, ill remove the lines with no meaning. Here is the part you see in that box:

  // THE PANEL OUTSIDE (A QWIDGET) is mainParametersLayout_. This particular scroll bar inside
  // is cameraModeParametersPanel_

  cameraModeParametersPanel_ = new QScrollArea();
  cameraModeParametersPanel_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  cameraModeParametersPanel_->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  mainParametersLayout_->addWidget( cameraModeParametersPanel_ );

  // HERE THERE ARE TWO MORE QGROUP BOXES. THE ONE THAT DOESN´T STAY THE WAY I SHOWED IS THIS. 

  QVBoxLayout* mainCameraLayout = new QVBoxLayout(cameraModeParametersPanel_);
  mainCameraLayout->setSpacing(5);

  // GROUP BOX 
  QGroupBox* activeCameraParametersGroup = new QGroupBox();
  activeCameraParametersGroup->setObjectName( parametersContainerName );
  activeCameraParametersGroup->setTitle(strings->cameraModeCameraParamsTitle);
  mainCameraLayout->addWidget( activeCameraParametersGroup );

  // LAYOUT
  QFormLayout* paramLayout = new QFormLayout( activeCameraParametersGroup );
  paramLayout->setRowWrapPolicy(QFormLayout::DontWrapRows);
  paramLayout->setFormAlignment( Qt::AlignHCenter | Qt::AlignTop );
  paramLayout->setLabelAlignment(Qt::AlignRight);


  // Iso : Spin Integer
  isoSpin = new SmartIntSpinButtons( control->getMinISO(), control->getMaxISO() );
  isoSpin->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
  paramLayout->addRow(strings->cameraISOCapString, isoSpin);

  // FStop: Spin Double
  fstopSpin = new SmartDoubleSpinButtons( control->getMinFStop(), control->getMaxFStop(), 2);
  fstopSpin->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
  paramLayout->addRow(strings->cameraFStopString, fstopSpin);



  // some other spins here...



  // Camera position: 3 Spin Double (X,Y,Z)
  camPosSpinX = new SmartDoubleSpinButtons( control->getMinCamPos(), control->getMaxCamPos(), 1);
  camPosSpinY = new SmartDoubleSpinButtons( control->getMinCamPos(), control->getMaxCamPos(), 1);
  camPosSpinZ = new SmartDoubleSpinButtons( control->getMinCamPos(), control->getMaxCamPos(), 1);

  camPosSpinX->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
  camPosSpinY->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
  camPosSpinZ->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

  paramLayout->addRow( new QLabel( strings->cameraPositionString ) );
  QHBoxLayout* positionLy = new QHBoxLayout();
  positionLy->addWidget( camPosSpinX );
  positionLy->addWidget( camPosSpinY );
  positionLy->addWidget( camPosSpinZ );
  paramLayout->addRow( positionLy );

  // Target Position: 3 Spin Double( X,Y,Z )
  camTargetPosSpinX = new SmartDoubleSpinButtons( control->getMinCamTarget(), control->getMaxCamTarget(), 1);
  camTargetPosSpinY = new SmartDoubleSpinButtons( control->getMinCamTarget(), control->getMaxCamTarget(), 1);
  camTargetPosSpinZ = new SmartDoubleSpinButtons( control->getMinCamTarget(), control->getMaxCamTarget(), 1);

  camTargetPosSpinX->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
  camTargetPosSpinY->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
  camTargetPosSpinZ->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

  paramLayout->addRow( new QLabel( strings->cameraTargetPositionString ));
  QHBoxLayout* targetLy = new QHBoxLayout();
  targetLy->addWidget( camTargetPosSpinX );
  targetLy->addWidget( camTargetPosSpinY );
  targetLy->addWidget( camTargetPosSpinZ );
  paramLayout->addRow( targetLy );

  // and the resoultion spins, which are the same style like the last one (but only X and Y).

Now comes the stylesheet of all:

/* THE PANEL THAT CONTAINS THE QSCROLLBAR OUTSIDE */

SmartPanel
{
    background-image: url(:/resources/images/containers/panel_bg.png);
    background-repeat: repeat-y;
    background-position: left top;
    background-color: white;
    border: 1px solid #aaa;
    border-radius: 10;
    min-width: 20px;
    padding: 5px;

}


QScrollArea#parametersPanelScrollArea
{
    background: transparent;
    border: none;
}


/* the qgroupbox */  


QGroupBox#parametersContainer
{
  background-color: white;
  padding-top: 25px;
  border-style: solid;
  border-width: 1px;
  border-color: #aaa;
  border-radius: 10px;
}

QGroupBox#parametersContainer::title  {
    subcontrol-origin: margin;
    subcontrol-position: top center;
    border: 1px solid #aaa;
    margin-top: -5px;
    padding: 8px 5px 5px 5px;
    font-size: 18px;
    border-radius: 5px;
}    


/* ------------------ SPINBOX WIDGET ------------------------------------------*/

QWidget#intSpin, QWidget#doubleSpin
{
    min-height: 20px;
    border: 1px solid #ccc;
    padding: 0px;
    border-top-left-radius: 4px;
    border-bottom-left-radius: 4px;
    background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #ddd, stop:1 #fff);
}

QPushButton#upSpinBtn,
QPushButton#downSpinBtn
{
    border-radius: 0px;
    /*background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #ddd, stop:1 #fff);*/
    background-repeat: no-repeat;
    background-position: center;
    border: none;
}

QPushButton#upSpinBtn
{   
    background-image: url(:/resources/images/buttons/up_sm_arrow.png);
}

QPushButton#downSpinBtn
{
    background-image: url(:/resources/images/buttons/down_sm_arrow.png);
}
like image 323
Darkgaze Avatar asked Jan 10 '13 09:01

Darkgaze


People also ask

How do I add a scroll bar to my widget?

To add a scrollbar to a ScrollView, wrap the scroll view widget in a Scrollbar widget. Using this widget we can scroll a widget. The scrollbar allows the user to jump into the particular points and also shows how far the user reaches.

How do I add a scrollbar to QT?

A QWidget does not have scrollbars, you need to add a zone which will have scrollbars. Just add a QScrollArea to your window, and put all the widgets in it (buttons, etc...). Don't forget to layout your scroll area to the whole main window.

How do you hide the spacer in Qt?

Try putting the button you want to hide and unhide in another layout. In that layout along with the button put a spacer. Call Button hide and spacer will take over. Spacer takes over hidden button's space.


1 Answers

QScrollArea is not a container. QScrollArea is a "scrolling view" for another widget. You shouldn't set up layout on QScrollArea. You should create widget, fill it with proper layout and then use QScrollArea::setWidget(QWidget *) to make it scrollable.

like image 191
Kamil Klimek Avatar answered Sep 23 '22 21:09

Kamil Klimek