QScrollArea не соблюдает настройку contentMargins
-
27-10-2019 - |
Вопрос
QScrollArea Область прокрутки, по какой-то причине игнорирует contentMargins
настройка, когда я устанавливаю QGraphicsView ( Графический просмотр ) в качестве его виджета.Глядя на приведенный ниже фрагмент, может кто-нибудь, пожалуйста, сказать, делаю ли я что-то неправильно или это может быть ошибка в SDK?
Фрагмент 1 (работает идеально):
QWidget *appWindow = new QWidget;
QScrollArea *sa = new QScrollArea(appWindow);
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setContentMargins(50, 50, 50, 50);
QWidget *widgetToScroll = new QWidget(sa);
widgetToScroll->resize(5000, 5000);
sa->setWidget(widgetToScroll);
QVBoxLayout *appWindowLayout = new QVBoxLayout(appWindow);
appWindowLayout->addWidget(sa);
appWindow->setLayout(appWindowLayout);
appWindow->show();
Фрагмент 2 (Это как setContentMargins() Установить contentmargins() вызов полностью игнорируется):
QWidget *appWindow = new QWidget;
QScrollArea *sa = new QScrollArea(appWindow);
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setContentMargins(50, 50, 50, 50);
QGraphicsView *widgetToScroll = new QGraphicsView(new QGraphicsScene(sa), sa);
widgetToScroll->setAlignment(Qt::AlignLeft | Qt::AlignTop);
widgetToScroll->resize(5000, 5000);
sa->setWidget(widgetToScroll);
QVBoxLayout *appWindowLayout = new QVBoxLayout(appWindow);
appWindowLayout->addWidget(sa);
appWindow->setLayout(appWindowLayout);
appWindow->show();
Спасибо.
Решение
Похоже, вы путаете структуру того, как вложить QGraphicsView и QGraphicsScene.(Может быть, это была просто опечатка?)
QGraphicsView *widgetToScroll = new QGraphicsView(new QGraphicsScene(sa), sa);
должно быть изменено на
QGraphicsView *widgetToScroll = new QGraphicsView(new QGraphicsScene(), sa);
или
QGraphicsView *widgetToScroll = new QGraphicsView();
sa->setWidget(widgetToScroll);
Когда вы добавляете QWidget в макет, вы меняете родительский элемент виджета.Когда вы устанавливаете виджет (или QGraphicsView) в QScrollArea, вы меняете родительский элемент этого виджета.Видишь Деревья объектов и право собственности для получения дополнительной информации.Итак, если бы вы хотели настроить свой QGraphicsView внутри QScrollArea, ваш код выглядел бы следующим образом:
QWidget *appWindow = new QWidget;
QScrollArea *sa = new QScrollArea(); // No need to specify a parent here if
// you add it to a layout later
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setContentsMargins(50, 50, 50, 50);
QGraphicsView *widgetToScroll = new QGraphicsView();
widgetToScroll->setAlignment(Qt::AlignLeft | Qt::AlignTop);
widgetToScroll->resize(5000, 5000);
sa->setWidget(widgetToScroll); // This sets the parent for widgetToScroll
QVBoxLayout *appWindowLayout = new QVBoxLayout();
appWindowLayout->addWidget(sa); // This sets the parent for sa
appWindow->setLayout(appWindowLayout); // This sets the parent for appWindowLayout
appWindow->show();
В качестве дополнительного примечания...
При использовании QGraphicsViews с QGraphicsScene вместо установки полей с помощью setContentsMargins в QScrollArea я использую автоматическую прокрутку QGraphicsView и просто устанавливаю прямоугольник сцены с большим полем, чем размер моего контента, например, так:
QWidget *appWindow = new QWidget;
QGraphicsView *widgetToScroll = new QGraphicsView();
QGraphicsScene *scene = new QGraphicsScene();
scene->addRect(0,0, 5000, 5000);
widgetToScroll->setSceneRect(-50,-50, 5050, 5050);
widgetToScroll->setScene(scene);
QVBoxLayout *appWindowLayout = new QVBoxLayout(appWindow);
appWindowLayout->addWidget(widgetToScroll);
appWindow->setLayout(appWindowLayout);
appWindow->show();
QGraphicsView включает в себя гораздо больше, чем просто автоматическую прокрутку, когда это необходимо.Вы можете изменить размер всего, что находится внутри него, и даже немного больше.Он отлично подходит для 2D-макетов, взаимодействий и анимации.Смотрите Платформу просмотра графики Qt по адресу http://doc.qt.io/qt-5/graphicsview.html для получения дополнительной информации.
Вот дополнительная информация, которая может быть полезна при использовании полей и отступов: Коробчатая модель используется QStyleSheets.
Другие советы
Чтобы поля содержимого работали должным образом для виджета QScrollArea, я создаю его подкласс и вручную устанавливаю поля области просмотра (что является защищенным методом в QT 4.7)
// Extended class
class QScrollAreaWithMargins : public QScrollArea
{
public:
virtual void resizeEvent(QResizeEvent *event) override
{
// Define content margins here
setViewportMargins(5, 0, 0, 0); // <<<<< SET MARGINS HERE
QScrollArea::resizeEvent(event);
}
};
// Usage
//...
mEditorScrollArea = new QScrollAreaWithMargins();
//...