Image Viewer Example |
void ImageViewer::normalSize() { imageLabel->adjustSize(); scaleFactor = 1.0; }
When zooming, we use the QLabel's ability to scale its contents. Such scaling doesn't change the actual size hint of the contents. And since the adjustSize() function use those size hint, the only thing we need to do to restore the normal size of the currently displayed image is to call adjustSize() and reset the scale factor to 1.0.
void ImageViewer::fitToWindow() { bool fitToWindow = fitToWindowAct->isChecked(); scrollArea->setWidgetResizable(fitToWindow); if (!fitToWindow) { normalSize(); } updateActions(); }
The fitToWindow() slot is called each time the user toggled the Fit to Window option. If the slot is called to turn on the option, we tell the scroll area to resize its child widget with the QScrollArea::setWidgetResizable() function. Then we disable the Zoom In, Zoom Out and Normal Size menu entries using the private updateActions() function.
If the QScrollArea::widgetResizable property is set to false (the default), the scroll area honors the size of its child widget. 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. But the scroll area will honor the minimum size hint of its child widget independent of the widget resizable property. So in this example we set imageLabel's size policy to ignored in the constructor, to avoid that scroll bars appear when the scroll area becomes smaller than the label's minimum size hint.
The screenshots below shows an image in its normal size, and the same image with the Fit to window option turned on. Enlarging the window will stretch the image further, as shown in the third screenshot.
If the slot is called to turn off the option, the {QScrollArea::setWidgetResizable} property is set to false. We also restore the image pixmap to its normal size by adjusting the label's size to its content. And in the end we update the view menu entries.
void ImageViewer::about() { QMessageBox::about(this, tr("About Image Viewer"), tr("<p>The <b>Image Viewer</b> example shows how to combine QLabel " "and QScrollArea to display an image. QLabel is typically used " "for displaying a text, but it can also display an image. " "QScrollArea provides a scrolling view around another widget. " "If the child widget exceeds the size of the frame, QScrollArea " "automatically provides scroll bars. </p><p>The example " "demonstrates how QLabel's ability to scale its contents " "(QLabel::scaledContents), and QScrollArea's ability to " "automatically resize its contents " "(QScrollArea::widgetResizable), can be used to implement " "zooming and scaling features. </p><p>In addition the example " "shows how to use QPainter to print an image.</p>")); }
We implement the about() slot to create a message box describing what the example is designed to show.
void ImageViewer::createActions() { openAct = new QAction(tr("&Open..."), this); openAct->setShortcut(tr("Ctrl+O")); connect(openAct, SIGNAL(triggered()), this, SLOT(open())); printAct = new QAction(tr("&Print..."), this); printAct->setShortcut(tr("Ctrl+P")); printAct->setEnabled(false); connect(printAct, SIGNAL(triggered()), this, SLOT(print())); exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcut(tr("Ctrl+Q")); connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); zoomInAct = new QAction(tr("Zoom &In (25%)"), this); zoomInAct->setShortcut(tr("Ctrl++")); zoomInAct->setEnabled(false); connect(zoomInAct, SIGNAL(triggered()), this, SLOT(zoomIn())); zoomOutAct = new QAction(tr("Zoom &Out (25%)"), this); zoomOutAct->setShortcut(tr("Ctrl+-")); zoomOutAct->setEnabled(false); connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(zoomOut())); normalSizeAct = new QAction(tr("&Normal Size"), this); normalSizeAct->setShortcut(tr("Ctrl+S")); normalSizeAct->setEnabled(false); connect(normalSizeAct, SIGNAL(triggered()), this, SLOT(normalSize())); fitToWindowAct = new QAction(tr("&Fit to Window"), this); fitToWindowAct->setEnabled(false); fitToWindowAct->setCheckable(true); fitToWindowAct->setShortcut(tr("Ctrl+F")); connect(fitToWindowAct, SIGNAL(triggered()), this, SLOT(fitToWindow())); aboutAct = new QAction(tr("&About"), this); connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); aboutQtAct = new QAction(tr("About &Qt"), this); connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); }
In the private createAction() function, we create the actions providing the application features.
We assign a short-cut key to each action and connect them to the appropiate slots. We only enable the openAct and exitAxt at the time of creation, the others are updated once an image has been loaded into the application. In addition we make the fitToWindowAct checkable.
void ImageViewer::createMenus() { fileMenu = new QMenu(tr("&File"), this); fileMenu->addAction(openAct); fileMenu->addAction(printAct); fileMenu->addSeparator(); fileMenu->addAction(exitAct); viewMenu = new QMenu(tr("&View"), this); viewMenu->addAction(zoomInAct); viewMenu->addAction(zoomOutAct); viewMenu->addAction(normalSizeAct); viewMenu->addSeparator(); viewMenu->addAction(fitToWindowAct); helpMenu = new QMenu(tr("&Help"), this); helpMenu->addAction(aboutAct); helpMenu->addAction(aboutQtAct); menuBar()->addMenu(fileMenu); menuBar()->addMenu(viewMenu); menuBar()->addMenu(helpMenu); }
In the private createMenu() function, we add the previously created actions to the File, View and Help menus.
The QMenu class provides a menu widget for use in menu bars, context menus, and other popup menus. The QMenuBar class provides a horizontal menu bar that consists of a list of pull-down menu items. So at the end we put the menus in the ImageViewer's menu bar which we retrieve with the QMainWindow::menuBar() function.
void ImageViewer::updateActions() { zoomInAct->setEnabled(!fitToWindowAct->isChecked()); zoomOutAct->setEnabled(!fitToWindowAct->isChecked()); normalSizeAct->setEnabled(!fitToWindowAct->isChecked()); }
The private updateActions() function enables or disables the Zoom In, Zoom Out and Normal Size menu entries depending on whether the Fit to Window option is turned on or off.
void ImageViewer::scaleImage(double factor) { Q_ASSERT(imageLabel->pixmap()); scaleFactor *= factor; imageLabel->resize(scaleFactor * imageLabel->pixmap()->size()); adjustScrollBar(scrollArea->horizontalScrollBar(), factor); adjustScrollBar(scrollArea->verticalScrollBar(), factor); zoomInAct->setEnabled(scaleFactor < 3.0); zoomOutAct->setEnabled(scaleFactor > 0.333); }
In scaleImage(), we use the factor parameter to calculate the new scaling factor for the displayed image, and resize imageLabel. Since we set the scaledContents property to true in the constructor, the call to QWidget::resize() will scale the image displayed in the label. We also adjust the scroll bars to preserve the focal point of the image.
At the end, if the scale factor is less than 33.3% or greater than 300%, we disable the respective menu entry to prevent the image pixmap from becoming too large, consuming too much resources in the window system.
void ImageViewer::adjustScrollBar(QScrollBar *scrollBar, double factor) { scrollBar->setValue(int(factor * scrollBar->value() + ((factor - 1) * scrollBar->pageStep()/2))); }
Whenever we zoom in or out, we need to adjust the scroll bars in consequence. It would have been tempting to simply call
scrollBar->setValue(int(factor * scrollBar->value()));
but this would make the top-left corner the focal point, not the center. Therefore we need to take into account the scroll bar handle's size (the page step).
Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. | Qt 4.4 | |
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD. | ||
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP ! |
Copyright © 2000-2012 - www.developpez.com