Home > Back-end >  Customized widget in scroll area cannot be scrolled up or down after setting setWidgetResizable to t
Customized widget in scroll area cannot be scrolled up or down after setting setWidgetResizable to t

Time:09-25

I have a problem when working with QScrollArea. Mainly, I want to add a customized widget into a scroll area to reach:

  1. scroll widget if widget's size is larger than parent(scroll)
  2. customized widget can automatically resize its size to fill all space of scroll if it is smaller than scroll

But I failed. Setting setWidgetResizable to true can resize widget but cannot scroll. Otherwise, can scroll widget not resize.

I'm using qt-5.15.x. Here is the minimal example, I can scroll it if I comment out line scroll->setWidgetResizable(true);:

customwidget.h

#ifndef CUSTOMWIDGET_H
#define CUSTOMWIDGET_H

#include <QWidget>
#include <QSize>
#include <QResizeEvent>

class CustomWidget : public QWidget
{
  Q_OBJECT
public:
  explicit CustomWidget(QWidget *parent = nullptr);
  ~CustomWidget()=default;
protected:
  void paintEvent(QPaintEvent *e);
  void resizeEvent(QResizeEvent *e);
  QSize sizeHint() const override;

private:
  QVector<QRectF> _rects;
  QSize _size;
};

#endif // CUSTOMWIDGET_H

customwidget.cpp

#include "customwidget.h"
#include <QPainter>

CustomWidget::CustomWidget(QWidget *parent) : QWidget(parent)
{
  _size = QSize(120, 200);
  for(int i = 0; i < 10; i  )
  {
    QRectF rect(QPointF(10, 60*i 2),QSize(100, 50));
    _rects.push_back(rect);
  }
}

void CustomWidget::paintEvent(QPaintEvent *e)
{
  QPainter painter(this);

  // background
  painter.setBrush(QColor(130,130,130));
  painter.drawRect(QRectF(QPointF(0,0), _size));

  // items
  for(int i = 0; i < 10; i  )
  {
    painter.setBrush(QColor(43,43,43));
    painter.drawRect(_rects[i]);
    painter.setPen(QColor(255,255,255));
    painter.drawText(_rects[i], QString("ITEM %1").arg(QString::number(i)));
    }
}

void CustomWidget::resizeEvent(QResizeEvent *e)
{
  _size = e->size();
}

QSize CustomWidget::sizeHint() const
{
  int rows = _rects.size();
  int height = rows * 60 2;

  height = std::max(height, parentWidget()->height());
  int width = 120;

  return QSize(width, height);
}

Add the mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
  Q_OBJECT

public:
  MainWindow(QWidget *parent = nullptr);
  ~MainWindow();

private:
  Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QScrollArea>
#include "customwidget.h"
#include <QVBoxLayout>

MainWindow::MainWindow(QWidget *parent)
  : QMainWindow(parent)
  , ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  setGeometry(0,0,300,200);

  QVBoxLayout *layout = new QVBoxLayout(centralWidget());
  layout->setContentsMargins(0,0,0,0);

  CustomWidget *cw = new CustomWidget();
  QScrollArea *scroll = new QScrollArea(this);
  scroll->setWidgetResizable(true);
  scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  scroll->setStyleSheet("QScrollArea{background:rgb(0,0,0);border:none;}");
  scroll->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  scroll->setWidget(cw);

  layout->addWidget(scroll);
}

MainWindow::~MainWindow()
{
  delete ui;
}

CodePudding user response:

A possible solution is to set the sizePolicy to Minimum:

CustomWidget::CustomWidget(QWidget *parent) : QWidget(parent)
{
    _size = QSize(120, 200);
    for(int i = 0; i < 10; i  )
    {
        QRectF rect(QPointF(10, 60*i 2),QSize(100, 50));
        _rects.push_back(rect);
    }
    setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
}
  •  Tags:  
  • c qt
  • Related