Sophie

Sophie

distrib > Fedora > 18 > x86_64 > by-pkgid > ff187cb994c94c614ecc64c5a8528b1b > files > 7975

qt-doc-4.8.5-10.fc18.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- imageviewer.qdoc -->
  <title>Qt 4.8: Image Viewer Example</title>
  <link rel="stylesheet" type="text/css" href="style/style.css" />
  <script src="scripts/jquery.js" type="text/javascript"></script>
  <script src="scripts/functions.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="style/superfish.css" />
  <link rel="stylesheet" type="text/css" href="style/narrow.css" />
  <!--[if IE]>
<meta name="MSSmartTagsPreventParsing" content="true">
<meta http-equiv="imagetoolbar" content="no">
<![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie6.css">
<![endif]-->
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie7.css">
<![endif]-->
<!--[if IE 8]>
<link rel="stylesheet" type="text/css" href="style/style_ie8.css">
<![endif]-->

<script src="scripts/superfish.js" type="text/javascript"></script>
<script src="scripts/narrow.js" type="text/javascript"></script>

</head>
<body class="" onload="CheckEmptyAndLoadList();">
 <div class="header" id="qtdocheader">
    <div class="content"> 
    <div id="nav-logo">
      <a href="index.html">Home</a></div>
    <a href="index.html" class="qtref"><span>Qt Reference Documentation</span></a>
    <div id="narrowsearch"></div>
    <div id="nav-topright">
      <ul>
        <li class="nav-topright-home"><a href="http://qt.digia.com/">Qt HOME</a></li>
        <li class="nav-topright-dev"><a href="http://qt-project.org/">DEV</a></li>
        <li class="nav-topright-doc nav-topright-doc-active"><a href="http://qt-project.org/doc/">
          DOC</a></li>
        <li class="nav-topright-blog"><a href="http://blog.qt.digia.com/">BLOG</a></li>
      </ul>
    </div>
    <div id="shortCut">
      <ul>
        <li class="shortCut-topleft-inactive"><span><a href="index.html">Qt 4.8</a></span></li>
        <li class="shortCut-topleft-active"><a href="http://qt-project.org/doc/">ALL VERSIONS        </a></li>
      </ul>
     </div>
 <ul class="sf-menu" id="narrowmenu"> 
             <li><a href="#">API Lookup</a> 
                 <ul> 
                     <li><a href="classes.html">Class index</a></li> 
           <li><a href="functions.html">Function index</a></li> 
           <li><a href="modules.html">Modules</a></li> 
           <li><a href="namespaces.html">Namespaces</a></li> 
           <li><a href="qtglobal.html">Global Declarations</a></li> 
           <li><a href="qdeclarativeelements.html">QML elements</a></li> 
             </ul> 
             </li> 
             <li><a href="#">Qt Topics</a> 
                 <ul> 
                        <li><a href="qt-basic-concepts.html">Programming with Qt</a></li>  
                        <li><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li>  
                        <li><a href="qt-gui-concepts.html">UI Design with Qt</a></li>  
                        <li><a href="supported-platforms.html">Supported Platforms</a></li>  
                        <li><a href="technology-apis.html">Qt and Key Technologies</a></li>  
                        <li><a href="best-practices.html">How-To's and Best Practices</a></li>  
              </ul> 
                 </li> 
                 <li><a href="#">Examples</a> 
                     <ul> 
                       <li><a href="all-examples.html">Examples</a></li> 
                       <li><a href="tutorials.html">Tutorials</a></li> 
                       <li><a href="demos.html">Demos</a></li> 
                       <li><a href="qdeclarativeexamples.html">QML Examples</a></li> 
                </ul> 
                     </li> 
                 </ul> 
    </div>
  </div>
  <div class="wrapper">
    <div class="hd">
      <span></span>
    </div>
    <div class="bd group">
      <div class="sidebar">
        <div class="searchlabel">
          Search index:</div>
        <div class="search" id="sidebarsearch">
          <form id="qtdocsearch" action="" onsubmit="return false;">
            <fieldset>
              <input type="text" name="searchstring" id="pageType" value="" />
 <div id="resultdialog"> 
 <a href="#" id="resultclose">Close</a> 
 <p id="resultlinks" class="all"><a href="#" id="showallresults">All</a> | <a href="#" id="showapiresults">API</a> | <a href="#" id="showarticleresults">Articles</a> | <a href="#" id="showexampleresults">Examples</a></p> 
 <p id="searchcount" class="all"><span id="resultcount"></span><span id="apicount"></span><span id="articlecount"></span><span id="examplecount"></span>&nbsp;results:</p> 
 <ul id="resultlist" class="all"> 
 </ul> 
 </div> 
            </fieldset>
          </form>
        </div>
        <div class="box first bottombar" id="lookup">
          <h2 title="API Lookup"><span></span>
            API Lookup</h2>
          <div  id="list001" class="list">
          <ul id="ul001" >
              <li class="defaultLink"><a href="classes.html">Class index</a></li>
              <li class="defaultLink"><a href="functions.html">Function index</a></li>
              <li class="defaultLink"><a href="modules.html">Modules</a></li>
              <li class="defaultLink"><a href="namespaces.html">Namespaces</a></li>
              <li class="defaultLink"><a href="qtglobal.html">Global Declarations</a></li>
              <li class="defaultLink"><a href="qdeclarativeelements.html">QML elements</a></li>
            </ul> 
          </div>
        </div>
        <div class="box bottombar" id="topics">
          <h2 title="Qt Topics"><span></span>
            Qt Topics</h2>
          <div id="list002" class="list">
            <ul id="ul002" >
               <li class="defaultLink"><a href="qt-basic-concepts.html">Programming with Qt</a></li> 
               <li class="defaultLink"><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li> 
               <li class="defaultLink"><a href="qt-gui-concepts.html">UI Design with Qt</a></li> 
               <li class="defaultLink"><a href="supported-platforms.html">Supported Platforms</a></li>  
               <li class="defaultLink"><a href="technology-apis.html">Qt and Key Technologies</a></li> 
               <li class="defaultLink"><a href="best-practices.html">How-To's and Best Practices</a></li> 
            </ul>  
          </div>
        </div>
        <div class="box" id="examples">
          <h2 title="Examples"><span></span>
            Examples</h2>
          <div id="list003" class="list">
        <ul id="ul003">
              <li class="defaultLink"><a href="all-examples.html">Examples</a></li>
              <li class="defaultLink"><a href="tutorials.html">Tutorials</a></li>
              <li class="defaultLink"><a href="demos.html">Demos</a></li>
              <li class="defaultLink"><a href="qdeclarativeexamples.html">QML Examples</a></li>
            </ul> 
          </div>
        </div>
      </div>
      <div class="wrap">
        <div class="toolbar">
          <div class="breadcrumb toolblock">
            <ul>
              <li class="first"><a href="index.html">Home</a></li>
              <!--  Breadcrumbs go here -->
<li><a href="all-examples.html">Examples</a></li>
<li>Image Viewer Example</li>
            </ul>
          </div>
          <div class="toolbuttons toolblock">
            <ul>
              <li id="smallA" class="t_button">A</li>
              <li id="medA" class="t_button active">A</li>
              <li id="bigA" class="t_button">A</li>
              <li id="print" class="t_button"><a href="javascript:this.print();">
                <span>Print</span></a></li>
            </ul>
        </div>
        </div>
        <div class="content mainContent">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#imageviewer-class-definition">ImageViewer Class Definition</a></li>
<li class="level1"><a href="#imageviewer-class-implementation">ImageViewer Class Implementation</a></li>
</ul>
</div>
<h1 class="title">Image Viewer Example</h1>
<span class="subtitle"></span>
<!-- $$$widgets/imageviewer-description -->
<div class="descr"> <a name="details"></a>
<p>Files:</p>
<ul>
<li><a href="widgets-imageviewer-imageviewer-cpp.html">widgets/imageviewer/imageviewer.cpp</a></li>
<li><a href="widgets-imageviewer-imageviewer-h.html">widgets/imageviewer/imageviewer.h</a></li>
<li><a href="widgets-imageviewer-main-cpp.html">widgets/imageviewer/main.cpp</a></li>
<li><a href="widgets-imageviewer-imageviewer-pro.html">widgets/imageviewer/imageviewer.pro</a></li>
</ul>
<p>The Image Viewer example shows how to combine <a href="qlabel.html">QLabel</a> and <a href="qscrollarea.html">QScrollArea</a> to display an image.<p><a href="qlabel.html">QLabel</a> is typically used for displaying text, but it can also display an image. <a href="qscrollarea.html">QScrollArea</a> provides a scrolling view around another widget. If the child widget exceeds the size of the frame, <a href="qscrollarea.html">QScrollArea</a> automatically provides scroll bars.</p>
<p>The example demonstrates how <a href="qlabel.html">QLabel</a>'s ability to scale its contents (<a href="qlabel.html#scaledContents-prop">QLabel::scaledContents</a>), and <a href="qscrollarea.html">QScrollArea</a>'s ability to automatically resize its contents (<a href="qscrollarea.html#widgetResizable-prop">QScrollArea::widgetResizable</a>), can be used to implement zooming and scaling features. In addition the example shows how to use <a href="qpainter.html">QPainter</a> to print an image.</p>
<p class="centerAlign"><img src="images/imageviewer-example.png" alt="Screenshot of the Image Viewer example" /></p><p>With the Image Viewer application, the users can view an image of their choice. The <b>File</b> menu gives the user the possibility to:</p>
<ul>
<li><b>Open..&#x2e;</b> - Open an image file</li>
<li><b>Print..&#x2e;</b> - Print an image</li>
<li><b>Exit</b> - Exit the application</li>
</ul>
<p>Once an image is loaded, the <b>View</b> menu allows the users to:</p>
<ul>
<li><b>Zoom In</b> - Scale the image up by 25%</li>
<li><b>Zoom Out</b> - Scale the image down by 25%</li>
<li><b>Normal Size</b> - Show the image at its original size</li>
<li><b>Fit to Window</b> - Stretch the image to occupy the entire window</li>
</ul>
<p>In addition the <b>Help</b> menu provides the users with information about the Image Viewer example in particular, and about Qt in general.</p>
<a name="imageviewer-class-definition"></a>
<h2>ImageViewer Class Definition</h2>
<pre class="cpp"> <span class="keyword">class</span> ImageViewer : <span class="keyword">public</span> <span class="type"><a href="qmainwindow.html">QMainWindow</a></span>
 {
     Q_OBJECT

 <span class="keyword">public</span>:
     ImageViewer();

 <span class="keyword">private</span> <span class="keyword">slots</span>:
     <span class="type">void</span> open();
     <span class="type">void</span> print();
     <span class="type">void</span> zoomIn();
     <span class="type">void</span> zoomOut();
     <span class="type">void</span> normalSize();
     <span class="type">void</span> fitToWindow();
     <span class="type">void</span> about();

 <span class="keyword">private</span>:
     <span class="type">void</span> createActions();
     <span class="type">void</span> createMenus();
     <span class="type">void</span> updateActions();
     <span class="type">void</span> scaleImage(<span class="type">double</span> factor);
     <span class="type">void</span> adjustScrollBar(<span class="type"><a href="qscrollbar.html">QScrollBar</a></span> <span class="operator">*</span>scrollBar<span class="operator">,</span> <span class="type">double</span> factor);

     <span class="type"><a href="qlabel.html">QLabel</a></span> <span class="operator">*</span>imageLabel;
     <span class="type"><a href="qscrollarea.html">QScrollArea</a></span> <span class="operator">*</span>scrollArea;
     <span class="type">double</span> scaleFactor;

 <span class="preprocessor">#ifndef QT_NO_PRINTER</span>
     <span class="type"><a href="qprinter.html">QPrinter</a></span> printer;
 <span class="preprocessor">#endif</span>

     <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>openAct;
     <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>printAct;
     <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>exitAct;
     <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>zoomInAct;
     <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>zoomOutAct;
     <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>normalSizeAct;
     <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>fitToWindowAct;
     <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>aboutAct;
     <span class="type"><a href="qaction.html">QAction</a></span> <span class="operator">*</span>aboutQtAct;

     <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>fileMenu;
     <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>viewMenu;
     <span class="type"><a href="qmenu.html">QMenu</a></span> <span class="operator">*</span>helpMenu;
 };</pre>
<p>The <tt>ImageViewer</tt> class inherits from <a href="qmainwindow.html">QMainWindow</a>. We reimplement the constructor, and create several private slots to facilitate the menu entries. In addition we create four private functions.</p>
<p>We use <tt>createActions()</tt> and <tt>createMenus()</tt> when constructing the <tt>ImageViewer</tt> widget. We use the <tt>updateActions()</tt> function to update the menu entries when a new image is loaded, or when the <b>Fit to Window</b> option is toggled. The zoom slots use <tt>scaleImage()</tt> to perform the zooming. In turn, <tt>scaleImage()</tt> uses <tt>adjustScrollBar()</tt> to preserve the focal point after scaling an image.</p>
<a name="imageviewer-class-implementation"></a>
<h2>ImageViewer Class Implementation</h2>
<pre class="cpp"> ImageViewer<span class="operator">::</span>ImageViewer()
 {
     imageLabel <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qlabel.html">QLabel</a></span>;
     imageLabel<span class="operator">-</span><span class="operator">&gt;</span>setBackgroundRole(<span class="type"><a href="qpalette.html">QPalette</a></span><span class="operator">::</span>Base);
     imageLabel<span class="operator">-</span><span class="operator">&gt;</span>setSizePolicy(<span class="type"><a href="qsizepolicy.html">QSizePolicy</a></span><span class="operator">::</span>Ignored<span class="operator">,</span> <span class="type"><a href="qsizepolicy.html">QSizePolicy</a></span><span class="operator">::</span>Ignored);
     imageLabel<span class="operator">-</span><span class="operator">&gt;</span>setScaledContents(<span class="keyword">true</span>);

     scrollArea <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qscrollarea.html">QScrollArea</a></span>;
     scrollArea<span class="operator">-</span><span class="operator">&gt;</span>setBackgroundRole(<span class="type"><a href="qpalette.html">QPalette</a></span><span class="operator">::</span>Dark);
     scrollArea<span class="operator">-</span><span class="operator">&gt;</span>setWidget(imageLabel);
     setCentralWidget(scrollArea);

     createActions();
     createMenus();

     setWindowTitle(tr(<span class="string">&quot;Image Viewer&quot;</span>));
     resize(<span class="number">500</span><span class="operator">,</span> <span class="number">400</span>);
 }</pre>
<p>In the constructor we first create the label and the scroll area.</p>
<p>We set <tt>imageLabel</tt>'s size policy to <a href="qsizepolicy.html#Policy-enum">ignored</a>, making the users able to scale the image to whatever size they want when the <b>Fit to Window</b> option is turned on. Otherwise, the default size polizy (<a href="qsizepolicy.html#Policy-enum">preferred</a>) will make scroll bars appear when the scroll area becomes smaller than the label's minimum size hint.</p>
<p>We ensure that the label will scale its contents to fill all available space, to enable the image to scale properly when zooming. If we omitted to set the <tt>imageLabel</tt>'s <a href="qlabel.html#scaledContents-prop">scaledContents</a> property, zooming in would enlarge the <a href="qlabel.html">QLabel</a>, but leave the pixmap at its original size, exposing the <a href="qlabel.html">QLabel</a>'s background.</p>
<p>We make <tt>imageLabel</tt> the scroll area's child widget, and we make <tt>scrollArea</tt> the central widget of the <a href="qmainwindow.html">QMainWindow</a>. At the end we create the associated actions and menus, and customize the <tt>ImageViewer</tt>'s appearance.</p>
<pre class="cpp"> <span class="type">void</span> ImageViewer<span class="operator">::</span>open()
 {
     <span class="type"><a href="qstring.html">QString</a></span> fileName <span class="operator">=</span> <span class="type"><a href="qfiledialog.html">QFileDialog</a></span><span class="operator">::</span>getOpenFileName(<span class="keyword">this</span><span class="operator">,</span>
                                     tr(<span class="string">&quot;Open File&quot;</span>)<span class="operator">,</span> <span class="type"><a href="qdir.html">QDir</a></span><span class="operator">::</span>currentPath());
     <span class="keyword">if</span> (<span class="operator">!</span>fileName<span class="operator">.</span>isEmpty()) {
         <span class="type"><a href="qimage.html">QImage</a></span> image(fileName);
         <span class="keyword">if</span> (image<span class="operator">.</span>isNull()) {
             <span class="type"><a href="qmessagebox.html">QMessageBox</a></span><span class="operator">::</span>information(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">&quot;Image Viewer&quot;</span>)<span class="operator">,</span>
                                      tr(<span class="string">&quot;Cannot load %1.&quot;</span>)<span class="operator">.</span>arg(fileName));
             <span class="keyword">return</span>;
         }</pre>
<p>In the <tt>open()</tt> slot, we show a file dialog to the user. The easiest way to create a <a href="qfiledialog.html">QFileDialog</a> is to use the static convenience functions. <a href="qfiledialog.html#getOpenFileName">QFileDialog::getOpenFileName</a>() returns an existing file selected by the user. If the user presses <b>Cancel</b>, <a href="qfiledialog.html">QFileDialog</a> returns an empty string.</p>
<p>Unless the file name is a empty string, we check if the file's format is an image format by constructing a <a href="qimage.html">QImage</a> which tries to load the image from the file. If the constructor returns a null image, we use a <a href="qmessagebox.html">QMessageBox</a> to alert the user.</p>
<p>The <a href="qmessagebox.html">QMessageBox</a> class provides a modal dialog with a short message, an icon, and some buttons. As with <a href="qfiledialog.html">QFileDialog</a> the easiest way to create a <a href="qmessagebox.html">QMessageBox</a> is to use its static convenience functions. <a href="qmessagebox.html">QMessageBox</a> provides a range of different messages arranged along two axes: severity (question, information, warning and critical) and complexity (the number of necessary response buttons). In this particular example an information message with an <b>OK</b> button (the default) is sufficient, since the message is part of a normal operation.</p>
<pre class="cpp">         imageLabel<span class="operator">-</span><span class="operator">&gt;</span>setPixmap(<span class="type"><a href="qpixmap.html">QPixmap</a></span><span class="operator">::</span>fromImage(image));
         scaleFactor <span class="operator">=</span> <span class="number">1.0</span>;

         printAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">true</span>);
         fitToWindowAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">true</span>);
         updateActions();

         <span class="keyword">if</span> (<span class="operator">!</span>fitToWindowAct<span class="operator">-</span><span class="operator">&gt;</span>isChecked())
             imageLabel<span class="operator">-</span><span class="operator">&gt;</span>adjustSize();
     }
 }</pre>
<p>If the format is supported, we display the image in <tt>imageLabel</tt> by setting the label's <a href="qlabel.html#pixmap-prop">pixmap</a>. Then we enable the <b>Print</b> and <b>Fit to Window</b> menu entries and update the rest of the view menu entries. The <b>Open</b> and <b>Exit</b> entries are enabled by default.</p>
<p>If the <b>Fit to Window</b> option is turned off, the <a href="qscrollarea.html#widgetResizable-prop">QScrollArea::widgetResizable</a> property is <tt>false</tt> and it is our responsibility (not <a href="qscrollarea.html">QScrollArea</a>'s) to give the <a href="qlabel.html">QLabel</a> a reasonable size based on its contents. We call {<a href="qwidget.html#adjustSize">QWidget::adjustSize</a>()}{adjustSize()} to achieve this, which is essentially the same as</p>
<pre class="cpp"> imageLabel<span class="operator">-</span><span class="operator">&gt;</span>resize(imageLabel<span class="operator">-</span><span class="operator">&gt;</span>pixmap()<span class="operator">-</span><span class="operator">&gt;</span>size());</pre>
<p>In the <tt>print()</tt> slot, we first make sure that an image has been loaded into the application:</p>
<pre class="cpp"> <span class="type">void</span> ImageViewer<span class="operator">::</span>print()
 {
     Q_ASSERT(imageLabel<span class="operator">-</span><span class="operator">&gt;</span>pixmap());
 <span class="preprocessor">#ifndef QT_NO_PRINTER</span></pre>
<p>If the application is built in debug mode, the <tt>Q_ASSERT()</tt> macro will expand to</p>
<pre class="cpp"> <span class="keyword">if</span> (<span class="operator">!</span>imageLabel<span class="operator">-</span><span class="operator">&gt;</span>pixmap())
      <a href="qtglobal.html#qFatal">qFatal</a>(<span class="string">&quot;ASSERT: &quot;</span> imageLabel<span class="operator">-</span><span class="operator">&gt;</span>pixmap() <span class="string">&quot; in file ...&quot;</span>);</pre>
<p>In release mode, the macro simply disappear. The mode can be set in the application's <tt>.pro</tt> file. One way to do so is to add an option to <b>qmake</b> when building the appliction:</p>
<pre class="cpp"> qmake &quot;CONFIG += debug&quot; foo.pro</pre>
<p>or</p>
<pre class="cpp"> qmake &quot;CONFIG += release&quot; foo.pro</pre>
<p>Another approach is to add this line directly to the <tt>.pro</tt> file.</p>
<pre class="cpp">     <span class="type"><a href="qprintdialog.html">QPrintDialog</a></span> dialog(<span class="operator">&amp;</span>printer<span class="operator">,</span> <span class="keyword">this</span>);
     <span class="keyword">if</span> (dialog<span class="operator">.</span>exec()) {
         <span class="type"><a href="qpainter.html">QPainter</a></span> painter(<span class="operator">&amp;</span>printer);
         <span class="type"><a href="qrect.html">QRect</a></span> rect <span class="operator">=</span> painter<span class="operator">.</span>viewport();
         <span class="type"><a href="qsize.html">QSize</a></span> size <span class="operator">=</span> imageLabel<span class="operator">-</span><span class="operator">&gt;</span>pixmap()<span class="operator">-</span><span class="operator">&gt;</span>size();
         size<span class="operator">.</span>scale(rect<span class="operator">.</span>size()<span class="operator">,</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>KeepAspectRatio);
         painter<span class="operator">.</span>setViewport(rect<span class="operator">.</span>x()<span class="operator">,</span> rect<span class="operator">.</span>y()<span class="operator">,</span> size<span class="operator">.</span>width()<span class="operator">,</span> size<span class="operator">.</span>height());
         painter<span class="operator">.</span>setWindow(imageLabel<span class="operator">-</span><span class="operator">&gt;</span>pixmap()<span class="operator">-</span><span class="operator">&gt;</span>rect());
         painter<span class="operator">.</span>drawPixmap(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="operator">*</span>imageLabel<span class="operator">-</span><span class="operator">&gt;</span>pixmap());
     }
 <span class="preprocessor">#endif</span>
 }</pre>
<p>Then we present a print dialog allowing the user to choose a printer and to set a few options. We construct a painter with a <a href="qprinter.html">QPrinter</a> as the paint device. We set the painter's window and viewport in such a way that the image is as large as possible on the paper, but without altering its <a href="qt.html#AspectRatioMode-enum">aspect ratio</a>.</p>
<p>In the end we draw the pixmap at position (0, 0).</p>
<pre class="cpp"> <span class="type">void</span> ImageViewer<span class="operator">::</span>zoomIn()
 {
     scaleImage(<span class="number">1.25</span>);
 }

 <span class="type">void</span> ImageViewer<span class="operator">::</span>zoomOut()
 {
     scaleImage(<span class="number">0.8</span>);
 }</pre>
<p>We implement the zooming slots using the private <tt>scaleImage()</tt> function. We set the scaling factors to 1.25 and 0.8, respectively. These factor values ensure that a <b>Zoom In</b> action and a <b>Zoom Out</b> action will cancel each other (since 1.25 * 0.8 == 1), and in that way the normal image size can be restored using the zooming features.</p>
<p>The screenshots below show an image in its normal size, and the same image after zooming in:</p>
<table class="generic">
<tr valign="top" class="odd"><td ><img src="images/imageviewer-original_size.png" alt="" /></td><td ><img src="images/imageviewer-zoom_in_1.png" alt="" /></td><td ><img src="images/imageviewer-zoom_in_2.png" alt="" /></td></tr>
</table>
<pre class="cpp"> <span class="type">void</span> ImageViewer<span class="operator">::</span>normalSize()
 {
     imageLabel<span class="operator">-</span><span class="operator">&gt;</span>adjustSize();
     scaleFactor <span class="operator">=</span> <span class="number">1.0</span>;
 }</pre>
<p>When zooming, we use the <a href="qlabel.html">QLabel</a>'s ability to scale its contents. Such scaling doesn't change the actual size hint of the contents. And since the <a href="qwidget.html#adjustSize">adjustSize()</a> 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 <tt>adjustSize()</tt> and reset the scale factor to 1.0&#x2e;</p>
<pre class="cpp"> <span class="type">void</span> ImageViewer<span class="operator">::</span>fitToWindow()
 {
     <span class="type">bool</span> fitToWindow <span class="operator">=</span> fitToWindowAct<span class="operator">-</span><span class="operator">&gt;</span>isChecked();
     scrollArea<span class="operator">-</span><span class="operator">&gt;</span>setWidgetResizable(fitToWindow);
     <span class="keyword">if</span> (<span class="operator">!</span>fitToWindow) {
         normalSize();
     }
     updateActions();
 }</pre>
<p>The <tt>fitToWindow()</tt> slot is called each time the user toggled the <b>Fit to Window</b> option. If the slot is called to turn on the option, we tell the scroll area to resize its child widget with the <a href="qscrollarea.html#widgetResizable-prop">QScrollArea::setWidgetResizable</a>() function. Then we disable the <b>Zoom In</b>, <b>Zoom Out</b> and <b>Normal Size</b> menu entries using the private <tt>updateActions()</tt> function.</p>
<p>If the <a href="qscrollarea.html#widgetResizable-prop">QScrollArea::widgetResizable</a> property is set to <tt>false</tt> (the default), the scroll area honors the size of its child widget. If this property is set to <tt>true</tt>, 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 <tt>imageLabel</tt>'s size policy to <a href="qsizepolicy.html#Policy-enum">ignored</a> in the constructor, to avoid that scroll bars appear when the scroll area becomes smaller than the label's minimum size hint.</p>
<p>The screenshots below shows an image in its normal size, and the same image with the <b>Fit to window</b> option turned on. Enlarging the window will stretch the image further, as shown in the third screenshot.</p>
<table class="generic">
<tr valign="top" class="odd"><td ><img src="images/imageviewer-original_size.png" alt="" /></td><td ><img src="images/imageviewer-fit_to_window_1.png" alt="" /></td><td ><img src="images/imageviewer-fit_to_window_2.png" alt="" /></td></tr>
</table>
<p>If the slot is called to turn off the option, the {QScrollArea::setWidgetResizable} property is set to <tt>false</tt>. 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.</p>
<pre class="cpp"> <span class="type">void</span> ImageViewer<span class="operator">::</span>about()
 {
     <span class="type"><a href="qmessagebox.html">QMessageBox</a></span><span class="operator">::</span>about(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">&quot;About Image Viewer&quot;</span>)<span class="operator">,</span>
             tr(<span class="string">&quot;&lt;p&gt;The &lt;b&gt;Image Viewer&lt;/b&gt; example shows how to combine QLabel &quot;</span>
                <span class="string">&quot;and QScrollArea to display an image. QLabel is typically used &quot;</span>
                <span class="string">&quot;for displaying a text, but it can also display an image. &quot;</span>
                <span class="string">&quot;QScrollArea provides a scrolling view around another widget. &quot;</span>
                <span class="string">&quot;If the child widget exceeds the size of the frame, QScrollArea &quot;</span>
                <span class="string">&quot;automatically provides scroll bars. &lt;/p&gt;&lt;p&gt;The example &quot;</span>
                <span class="string">&quot;demonstrates how QLabel's ability to scale its contents &quot;</span>
                <span class="string">&quot;(QLabel::scaledContents), and QScrollArea's ability to &quot;</span>
                <span class="string">&quot;automatically resize its contents &quot;</span>
                <span class="string">&quot;(QScrollArea::widgetResizable), can be used to implement &quot;</span>
                <span class="string">&quot;zooming and scaling features. &lt;/p&gt;&lt;p&gt;In addition the example &quot;</span>
                <span class="string">&quot;shows how to use QPainter to print an image.&lt;/p&gt;&quot;</span>));
 }</pre>
<p>We implement the <tt>about()</tt> slot to create a message box describing what the example is designed to show.</p>
<pre class="cpp"> <span class="type">void</span> ImageViewer<span class="operator">::</span>createActions()
 {
     openAct <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qaction.html">QAction</a></span>(tr(<span class="string">&quot;&amp;Open...&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     openAct<span class="operator">-</span><span class="operator">&gt;</span>setShortcut(tr(<span class="string">&quot;Ctrl+O&quot;</span>));
     connect(openAct<span class="operator">,</span> SIGNAL(triggered())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(open()));

     printAct <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qaction.html">QAction</a></span>(tr(<span class="string">&quot;&amp;Print...&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     printAct<span class="operator">-</span><span class="operator">&gt;</span>setShortcut(tr(<span class="string">&quot;Ctrl+P&quot;</span>));
     printAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">false</span>);
     connect(printAct<span class="operator">,</span> SIGNAL(triggered())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(print()));

     exitAct <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qaction.html">QAction</a></span>(tr(<span class="string">&quot;E&amp;xit&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     exitAct<span class="operator">-</span><span class="operator">&gt;</span>setShortcut(tr(<span class="string">&quot;Ctrl+Q&quot;</span>));
     connect(exitAct<span class="operator">,</span> SIGNAL(triggered())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(close()));

     zoomInAct <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qaction.html">QAction</a></span>(tr(<span class="string">&quot;Zoom &amp;In (25%)&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     zoomInAct<span class="operator">-</span><span class="operator">&gt;</span>setShortcut(tr(<span class="string">&quot;Ctrl++&quot;</span>));
     zoomInAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">false</span>);
     connect(zoomInAct<span class="operator">,</span> SIGNAL(triggered())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(zoomIn()));

     zoomOutAct <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qaction.html">QAction</a></span>(tr(<span class="string">&quot;Zoom &amp;Out (25%)&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     zoomOutAct<span class="operator">-</span><span class="operator">&gt;</span>setShortcut(tr(<span class="string">&quot;Ctrl+-&quot;</span>));
     zoomOutAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">false</span>);
     connect(zoomOutAct<span class="operator">,</span> SIGNAL(triggered())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(zoomOut()));

     normalSizeAct <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qaction.html">QAction</a></span>(tr(<span class="string">&quot;&amp;Normal Size&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     normalSizeAct<span class="operator">-</span><span class="operator">&gt;</span>setShortcut(tr(<span class="string">&quot;Ctrl+S&quot;</span>));
     normalSizeAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">false</span>);
     connect(normalSizeAct<span class="operator">,</span> SIGNAL(triggered())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(normalSize()));

     fitToWindowAct <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qaction.html">QAction</a></span>(tr(<span class="string">&quot;&amp;Fit to Window&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     fitToWindowAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">false</span>);
     fitToWindowAct<span class="operator">-</span><span class="operator">&gt;</span>setCheckable(<span class="keyword">true</span>);
     fitToWindowAct<span class="operator">-</span><span class="operator">&gt;</span>setShortcut(tr(<span class="string">&quot;Ctrl+F&quot;</span>));
     connect(fitToWindowAct<span class="operator">,</span> SIGNAL(triggered())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(fitToWindow()));

     aboutAct <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qaction.html">QAction</a></span>(tr(<span class="string">&quot;&amp;About&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     connect(aboutAct<span class="operator">,</span> SIGNAL(triggered())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(about()));

     aboutQtAct <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qaction.html">QAction</a></span>(tr(<span class="string">&quot;About &amp;Qt&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     connect(aboutQtAct<span class="operator">,</span> SIGNAL(triggered())<span class="operator">,</span> qApp<span class="operator">,</span> SLOT(aboutQt()));
 }</pre>
<p>In the private <tt>createAction()</tt> function, we create the actions providing the application features.</p>
<p>We assign a short-cut key to each action and connect them to the appropiate slots. We only enable the <tt>openAct</tt> and <tt>exitAxt</tt> at the time of creation, the others are updated once an image has been loaded into the application. In addition we make the <tt>fitToWindowAct</tt> <a href="qaction.html#checkable-prop">checkable</a>.</p>
<pre class="cpp"> <span class="type">void</span> ImageViewer<span class="operator">::</span>createMenus()
 {
     fileMenu <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qmenu.html">QMenu</a></span>(tr(<span class="string">&quot;&amp;File&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     fileMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(openAct);
     fileMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(printAct);
     fileMenu<span class="operator">-</span><span class="operator">&gt;</span>addSeparator();
     fileMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(exitAct);

     viewMenu <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qmenu.html">QMenu</a></span>(tr(<span class="string">&quot;&amp;View&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     viewMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(zoomInAct);
     viewMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(zoomOutAct);
     viewMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(normalSizeAct);
     viewMenu<span class="operator">-</span><span class="operator">&gt;</span>addSeparator();
     viewMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(fitToWindowAct);

     helpMenu <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qmenu.html">QMenu</a></span>(tr(<span class="string">&quot;&amp;Help&quot;</span>)<span class="operator">,</span> <span class="keyword">this</span>);
     helpMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(aboutAct);
     helpMenu<span class="operator">-</span><span class="operator">&gt;</span>addAction(aboutQtAct);

     menuBar()<span class="operator">-</span><span class="operator">&gt;</span>addMenu(fileMenu);
     menuBar()<span class="operator">-</span><span class="operator">&gt;</span>addMenu(viewMenu);
     menuBar()<span class="operator">-</span><span class="operator">&gt;</span>addMenu(helpMenu);
 }</pre>
<p>In the private <tt>createMenu()</tt> function, we add the previously created actions to the <b>File</b>, <b>View</b> and <b>Help</b> menus.</p>
<p>The <a href="qmenu.html">QMenu</a> class provides a menu widget for use in menu bars, context menus, and other popup menus. The <a href="qmenubar.html">QMenuBar</a> 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 <tt>ImageViewer</tt>'s menu bar which we retrieve with the <a href="qmainwindow.html#menuBar">QMainWindow::menuBar</a>() function.</p>
<pre class="cpp"> <span class="type">void</span> ImageViewer<span class="operator">::</span>updateActions()
 {
     zoomInAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="operator">!</span>fitToWindowAct<span class="operator">-</span><span class="operator">&gt;</span>isChecked());
     zoomOutAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="operator">!</span>fitToWindowAct<span class="operator">-</span><span class="operator">&gt;</span>isChecked());
     normalSizeAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="operator">!</span>fitToWindowAct<span class="operator">-</span><span class="operator">&gt;</span>isChecked());
 }</pre>
<p>The private <tt>updateActions()</tt> function enables or disables the <b>Zoom In</b>, <b>Zoom Out</b> and <b>Normal Size</b> menu entries depending on whether the <b>Fit to Window</b> option is turned on or off.</p>
<pre class="cpp"> <span class="type">void</span> ImageViewer<span class="operator">::</span>scaleImage(<span class="type">double</span> factor)
 {
     Q_ASSERT(imageLabel<span class="operator">-</span><span class="operator">&gt;</span>pixmap());
     scaleFactor <span class="operator">*</span><span class="operator">=</span> factor;
     imageLabel<span class="operator">-</span><span class="operator">&gt;</span>resize(scaleFactor <span class="operator">*</span> imageLabel<span class="operator">-</span><span class="operator">&gt;</span>pixmap()<span class="operator">-</span><span class="operator">&gt;</span>size());

     adjustScrollBar(scrollArea<span class="operator">-</span><span class="operator">&gt;</span>horizontalScrollBar()<span class="operator">,</span> factor);
     adjustScrollBar(scrollArea<span class="operator">-</span><span class="operator">&gt;</span>verticalScrollBar()<span class="operator">,</span> factor);

     zoomInAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(scaleFactor <span class="operator">&lt;</span> <span class="number">3.0</span>);
     zoomOutAct<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(scaleFactor <span class="operator">&gt;</span> <span class="number">0.333</span>);
 }</pre>
<p>In <tt>scaleImage()</tt>, we use the <tt>factor</tt> parameter to calculate the new scaling factor for the displayed image, and resize <tt>imageLabel</tt>. Since we set the <a href="qlabel.html#scaledContents-prop">scaledContents</a> property to <tt>true</tt> in the constructor, the call to <a href="qwidget.html#size-prop">QWidget::resize</a>() will scale the image displayed in the label. We also adjust the scroll bars to preserve the focal point of the image.</p>
<p>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.</p>
<pre class="cpp"> <span class="type">void</span> ImageViewer<span class="operator">::</span>adjustScrollBar(<span class="type"><a href="qscrollbar.html">QScrollBar</a></span> <span class="operator">*</span>scrollBar<span class="operator">,</span> <span class="type">double</span> factor)
 {
     scrollBar<span class="operator">-</span><span class="operator">&gt;</span>setValue(<span class="type">int</span>(factor <span class="operator">*</span> scrollBar<span class="operator">-</span><span class="operator">&gt;</span>value()
                             <span class="operator">+</span> ((factor <span class="operator">-</span> <span class="number">1</span>) <span class="operator">*</span> scrollBar<span class="operator">-</span><span class="operator">&gt;</span>pageStep()<span class="operator">/</span><span class="number">2</span>)));
 }</pre>
<p>Whenever we zoom in or out, we need to adjust the scroll bars in consequence. It would have been tempting to simply call</p>
<pre class="cpp"> scrollBar<span class="operator">-</span><span class="operator">&gt;</span>setValue(<span class="type">int</span>(factor <span class="operator">*</span> scrollBar<span class="operator">-</span><span class="operator">&gt;</span>value()));</pre>
<p>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 <a href="qabstractslider.html#pageStep-prop">page step</a>).</p>
</div>
<!-- @@@widgets/imageviewer -->
      </div>
    </div>
    </div> 
    <div class="ft">
      <span></span>
    </div>
  </div> 
  <div class="footer">
    <p>
      <acronym title="Copyright">&copy;</acronym> 2013 Digia Plc and/or its
      subsidiaries. Documentation contributions included herein are the copyrights of
      their respective owners.</p>
    <br />
    <p>
      The documentation provided herein is licensed under the terms of the
      <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation
      License version 1.3</a> as published by the Free Software Foundation.</p>
    <p>
      Documentation sources may be obtained from <a href="http://www.qt-project.org">
      www.qt-project.org</a>.</p>
    <br />
    <p>
      Digia, Qt and their respective logos are trademarks of Digia Plc 
      in Finland and/or other countries worldwide. All other trademarks are property
      of their respective owners. <a title="Privacy Policy"
      href="http://en.gitorious.org/privacy_policy/">Privacy Policy</a></p>
  </div>

  <script src="scripts/functions.js" type="text/javascript"></script>
</body>
</html>