c++ - qt中设置setWidgetResizable为true后,滚动区自定义小部件无法上下滚动
问题描述
使用 QScrollArea 时遇到问题。主要是,我想在滚动区域中添加一个自定义小部件以达到:
- 如果小部件的大小大于父级(
scroll
) ,则滚动小部件 - 自定义小部件可以自动调整其大小以填充所有空间,
scroll
如果它小于scroll
但我失败了。设置setWidgetResizable
为 true 可以调整小部件的大小,但不能滚动。否则,滚动小部件不能调整大小。
我正在使用 qt-5.15.x。这是最小的示例,如果我注释掉行,我可以滚动它scroll->setWidgetResizable(true);
:
自定义小部件.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);
}
添加主窗口.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
主窗口.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);
}
推荐阅读
- php - PHP代码没有在wordpress中读取正确的post_type数据
- wordpress - 仅在特定页面上重定向未登录的用户
- python - 如何制作不同尺寸的图像并将它们存储在 django 中?
- c# - 如何获取 OpenIdConnectOptions StateDataFormat
- pytest - 让 pytest 测试发现从导入中跳过测试方法的方法
- node.js - Mongoose 模式不会调用中间件来散列密码
- excel - 保存时出现运行时错误 1004 (Thisworkbook.save) 在一台机器上工作,而不是在另一台机器上工作
- ruby - 通过 websocket 连接到 CoinEx 时如何修复 Errno::ENETUNREACH?
- google-scholar - 如何将 CRAN 中发布的 R 包索引到 Google Scholar?
- r - 我在 ggplot 调用中使用收集如何影响输出?