Russian Qt Forum
Сентябрь 30, 2024, 20:16 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Подгонка QScrollArea под контент  (Прочитано 8852 раз)
Hort
Гость
« : Октябрь 19, 2008, 12:37 »

Есть такой класс
Код:
class ImageViewDialog : public QDialog
{
Q_OBJECT

// Member Variables
private:
double scaleFactor;
QLabel* imageLabel;
QScrollArea* scrollArea;
QPushButton* buttonZoomIn;
QPushButton* buttonZoomOut;

// Constructor & Destructor
public:
ImageViewDialog(const QString& image, QWidget* parent=0);

// Member Functions
private:
void scaleImage(double factor);
void adjustScrollBar(QScrollBar* scrollBar, double factor);
private slots:
void slotZoomIn();
void slotNormalSize();
void slotZoomOut();
};
Код:
ImageViewDialog::ImageViewDialog(const QString& fileName, QWidget* parent) : QDialog(parent)
{
setWindowFlags(windowFlags()|Qt::WindowMaximizeButtonHint);
QImage image(fileName);
if(image.isNull()){
QMessageBox::information(this, tr("Show image"), tr("Cannot load %1.").arg(fileName));
}

imageLabel=new QLabel;
imageLabel->setBackgroundRole(QPalette::Base);
imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
imageLabel->setScaledContents(true);
imageLabel->setPixmap(QPixmap::fromImage(image));
scaleFactor=1.0;

scrollArea=new QScrollArea;
scrollArea->setBackgroundRole(QPalette::Dark);
scrollArea->setWidget(imageLabel);

buttonZoomIn=new QPushButton(tr("Zoom &In"));
QPushButton* buttonNormalSize=new QPushButton(tr("&Normal Size"));
buttonZoomOut=new QPushButton(tr("Zoom &Out"));
QPushButton* buttonClose=new QPushButton(tr("&Close"));
connect(buttonZoomIn, SIGNAL(clicked()), SLOT(slotZoomIn()));
connect(buttonNormalSize, SIGNAL(clicked()), SLOT(slotNormalSize()));
connect(buttonZoomOut, SIGNAL(clicked()), SLOT(slotZoomOut()));
connect(buttonClose, SIGNAL(clicked()), SLOT(accept()));
QHBoxLayout* buttonLayout=new QHBoxLayout;
buttonLayout->setMargin(5);
buttonLayout->addStretch(1);
buttonLayout->addWidget(buttonZoomIn);
buttonLayout->addWidget(buttonNormalSize);
buttonLayout->addWidget(buttonZoomOut);
buttonLayout->addStretch(1);
buttonLayout->addWidget(buttonClose);

QVBoxLayout* layout=new QVBoxLayout;
layout->setSpacing(5); layout->setMargin(5);
layout->addWidget(scrollArea);
layout->addLayout(buttonLayout);
setLayout(layout);
}

void ImageViewDialog::scaleImage(double factor)
{
scaleFactor*=factor;
imageLabel->resize(scaleFactor * imageLabel->pixmap()->size());

adjustScrollBar(scrollArea->horizontalScrollBar(), factor);
adjustScrollBar(scrollArea->verticalScrollBar(), factor);

buttonZoomIn->setEnabled(scaleFactor < 3.0);
buttonZoomOut->setEnabled(scaleFactor > 0.333);
}

void ImageViewDialog::adjustScrollBar(QScrollBar* scrollBar, double factor)
{
scrollBar->setValue(int(factor * scrollBar->value() + ((factor - 1) * scrollBar->pageStep()/2)));
}

void ImageViewDialog::slotZoomIn()
{
scaleImage(1.25);
}

void ImageViewDialog::slotNormalSize()
{
imageLabel->adjustSize();
scaleFactor=1.0;
buttonZoomIn->setEnabled(true);
buttonZoomOut->setEnabled(true);
}

void ImageViewDialog::slotZoomOut()
{
scaleImage(0.8);
}
надо чтобы при вызове диалога картинка гарантрованно помещалась в окне, т.е. чтобы небыло полос прокрутки QScrollArea. Пытался изменять размер и QScrollArea и QScrollArea::viewport() под размер QLabel в конструкторе - ничего не получалось.
Код:
scrollArea->resize(imageLabel->size());
Внизу картинки как есть и как должно быть
« Последнее редактирование: Октябрь 19, 2008, 12:43 от Hort » Записан
shadone
Гость
« Ответ #1 : Октябрь 19, 2008, 14:59 »

мне кажется что простейший вариант - вообще не использовать QScrollArea в данном случае - когда нужно отобразить картинку в реальном масштабе, без полос прокрутки просто использовать потомка QWidget, а когда пользователь хочет увеличить масштаб - добавить QScrollArea и переназначить родителя виджета.

По идее изменение размера виджета QScrollArea под размер viewport также должно работать, но надо пробовать. Что-то вроде scrollArea->resize(scrollArea->viewport()->size())

Кстати Cancel пишется так.
Записан
Hort
Гость
« Ответ #2 : Октябрь 19, 2008, 18:18 »

Оно то может и работает, но я так понимаю после вызова метода exec() все равно все выстраивается по своему.
Вот что я придумал:
Код:
	QSize size=imageLabel->size();
size.rheight()+=2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
size.rwidth()+=2*QApplication::style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
scrollArea->setMinimumSize(size);
теперь все работает корректно, но надо теперь чтобы после вызова exec() minimumSize снимался, чтобы дать пользователю возможность уменьшить окно. Может кто-нибуть подскажет как это реализовать лучше всего?
ЗЫ спасибо за Cancel
« Последнее редактирование: Октябрь 19, 2008, 18:24 от Hort » Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #3 : Октябрь 19, 2008, 18:35 »

2 Hort: Ты непробывал устанавливать свойство widgetResizable в true? Может подойдет такой вариант?

Цитировать
If this property is set to true, the scroll area will automatically resize the widget in order to avoid scroll bars where they can be avoided, or to take advantage of extra space
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Hort
Гость
« Ответ #4 : Октябрь 19, 2008, 18:45 »

2 Hort: Ты непробывал устанавливать свойство widgetResizable в true? Может подойдет такой вариант?

Цитировать
If this property is set to true, the scroll area will automatically resize the widget in order to avoid scroll bars where they can be avoided, or to take advantage of extra space
не подходит - у меня изменяется размер виджета с рисунком (QLabel) при клацаньи на увеличить/уменьшить. при widgetResizable он будет уменьшаться до размерв QScrollArea и при этом не факт, что сохраняться пропорции картинки.
ключевой момент тут imageLabel->setScaledContents(true);
ЗЫ кто знает эвент какой или сигнал чтобы отловить виджет после exec()? или отлавливать наведение на окно мыши?
« Последнее редактирование: Октябрь 19, 2008, 18:47 от Hort » Записан
EhTemka
Гость
« Ответ #5 : Октябрь 20, 2008, 13:09 »

Цитировать
отлавливать наведение на окно мыши?
void QWidget::focusInEvent ( QFocusEvent * event )


Цитировать
чтобы после вызова exec() minimumSize снимался, чтобы дать пользователю возможность уменьшить окно. Может кто-нибуть подскажет как это реализовать лучше всего?

А почему бы после вызова ехес не вызывать функцию "съема" minimumSize?
Ведь ехес то известно где происходит...
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #6 : Октябрь 20, 2008, 13:16 »

Цитировать
отлавливать наведение на окно мыши?
void QWidget::focusInEvent ( QFocusEvent * event )

focusInEvent - это клавиатурный фокус, а надо

void QWidget::enterEvent ( QEvent * event )
Записан
EhTemka
Гость
« Ответ #7 : Октябрь 20, 2008, 14:18 »

Цитировать
отлавливать наведение на окно мыши?
void QWidget::focusInEvent ( QFocusEvent * event )

focusInEvent - это клавиатурный фокус, а надо

void QWidget::enterEvent ( QEvent * event )

Ваша правда, извиняюсь  Улыбающийся
Записан
Hort
Гость
« Ответ #8 : Октябрь 20, 2008, 14:36 »

А почему бы после вызова ехес не вызывать функцию "съема" minimumSize?
Ведь ехес то известно где происходит...
метод ехес останавлтвает выполнение кода пока не закроется окно. следовательно если выполнять после него - уже поздно, а если поставить перед - еще рано.
решил я это путем перегрузки для диалога showEvent( QShowEvent * )
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.193 секунд. Запросов: 22.