LINUX.ORG.RU

[Qt] QScrollArea vs QWidget vs resize

 


0

0

Есть виджет фиксированного размера, унаследованный от QWidget. Есть QScrollArea произвольного размера, в которую запихнут предыдущий виджет. Если первый больше второй, всё прекрасно: скролбары скролят и я счастлив. Если наоборот, то всё уже не очень прекрасно: QWidget рисуется в углу QScrollArea, а мне хотелось бы ровно по центру. Как мне задать положение QWidget'а если я не знаю размера QScrollArea?

★★★★★

Поместить свой виджет на промежуточный, лейоут которого будет смещать свой виджет в центр. Размер промежуточного всегда равен размеру своего виджета, за исключением, когда QScrollArea::viewport() становится больше. Следить за размерами через фильтры событий.

Dendy ★★★★★
()
Ответ на: комментарий от Dendy

Вот вам мини-пример. Картинку (image.png) найдёте сами.

#include <QApplication>
#include <QScrollArea>
#include <QLabel>
#include <QPixmap>
#include <QHBoxLayout>




class Centrifier : public QWidget
{
public:
	Centrifier( QScrollArea * area, QWidget * widget ) :
		area_( area ), widget_( widget )
	{
		widget_->setParent( this );
		area_->setWidget( this );

		area_->viewport()->installEventFilter( this );
		widget_->installEventFilter( this );

		_relayout();
	}

protected:
	bool eventFilter( QObject * o, QEvent * e )
	{
		if (
			(o == area_->viewport() && e->type() == QEvent::Resize) ||
			(o == widget_ && e->type() == QEvent::Resize) )
		{
			_relayout();
			return false;
		}

		return QWidget::eventFilter( o, e );
	}

private:
	void _relayout()
	{
		const QSize widgetSize = widget_->size();
		const QSize viewportSize = area_->viewport()->size();

		resize( QSize(
			qMax( widgetSize.width(), viewportSize.width() ),
			qMax( widgetSize.height(), viewportSize.height() ) ) );

		const QSize diffSize = viewportSize - widgetSize;

		widget_->move(
			diffSize.width() <= 0 ? 0 : diffSize.width() / 2,
			diffSize.height() <= 0 ? 0 : diffSize.height() / 2 );
	}

private:
	QScrollArea * area_;
	QWidget * widget_;
};




int main( int argc, char ** argv )
{
	QApplication app( argc, argv );

	QScrollArea area;

	QLabel * label = new QLabel;
	label->setPixmap( QPixmap( "image.png" ) );

	Centrifier * centrifier = new Centrifier( &area, label );

	area.show();

	return app.exec();
}
Dendy ★★★★★
()

рекомендую использовать setMinimumSize вместо setFixedSize для виджета в QScrollArea. ну и во внутреннем виджете обрабатывать ситуацию, когда его размер больше необходимого (т.е. рисовать с центрированием). хотя может проще будет создать промежуточный виджет, зависит от задачи.

arsi ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.