qt中设置setWidgetResizable为true后滚动区自定义widget无法上下滚动
Customized widget in scroll area cannot be scrolled up or down after setting setWidgetResizable to true in qt
我在使用 QScrollArea 时遇到问题。主要是,我想将自定义小部件添加到滚动区域以达到:
- 如果小部件的大小大于父级(
scroll
)则滚动小部件
- 如果自定义小部件小于
scroll
,它可以自动调整其大小以填充 scroll
的所有 space
但是我失败了。将 setWidgetResizable
设置为 true 可以调整小部件的大小但不能滚动。否则,滚动小部件不能调整大小。
我正在使用 qt-5。15.x。这是最小的例子,如果我注释掉 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);
}
添加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;
}
一个可能的解决方案是将 sizePolicy 设置为最小值:
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);
}
我在使用 QScrollArea 时遇到问题。主要是,我想将自定义小部件添加到滚动区域以达到:
- 如果小部件的大小大于父级(
scroll
)则滚动小部件 - 如果自定义小部件小于
scroll
,它可以自动调整其大小以填充
scroll
的所有 space
但是我失败了。将 setWidgetResizable
设置为 true 可以调整小部件的大小但不能滚动。否则,滚动小部件不能调整大小。
我正在使用 qt-5。15.x。这是最小的例子,如果我注释掉 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);
}
添加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;
}
一个可能的解决方案是将 sizePolicy 设置为最小值:
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);
}