    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Creating Standard GUI Applications</title>
        <link>https://members.accu.org/index.php/journals/682</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">CVu Journal Vol 16, #4 - Aug 2004 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c101/">164</a>
                    (12)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c101-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c101+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Creating Standard GUI Applications</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 August 2004 13:16:06 +01:00 or Tue, 03 August 2004 13:16:06 +01:00</p>
<p><strong>Summary:</strong>&nbsp;<p>In this second installment of our series on GUI programming with the Qt C++ toolkit, we're going to see how to create a standard GUI application, with a menu, toolbar, status bar, and a central area. </p></p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e23" id="d0e23"></a></h2>
</div>
<p>In this second installment of our series on GUI programming with
the Qt C++ toolkit, we're going to see how to create a standard GUI
application, with a menu, toolbar, status bar, and a central area.
The application is a simple image viewer that can display images in
any of the formats that your installed version of Qt supports.</p>
<p>The <tt class="function">main()</tt> function, in <tt class=
"filename">main.cpp</tt>, is straightforward:</p>
<pre class="programlisting">
#include &lt;qapplication.h&gt;
#include &quot;viewer.h&quot;

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);
  Viewer *viewer = new Viewer;
  viewer-&gt;show();
  viewer-&gt;connect(&amp;app,
                  SIGNAL(lastWindowClosed()),
                  &amp;app,
                  SLOT(quit()));
  return app.exec();
}
</pre>
<p>We create a <tt class="classname">QApplication</tt> object and
then the form which we immediately show. The &quot;signal-slot&quot;
connection ensures that when the last top-level window (in this
case the only window) is closed, the application will terminate.
Finally we start the event loop and wait for user interactions.</p>
<p>Qt provides the <tt class="classname">QMainWindow</tt> class as
the base class for main windows, so we will subclass this and
specialise it to our needs. Here's the definition which we've put
in <tt class="filename">viewer.h</tt>:</p>
<pre class="programlisting">
#ifndef VIEWER_H
#define VIEWER_H

#include &lt;qmainwindow.h&gt;

class QAction;
class QLabel;

class Viewer : public QMainWindow {
  Q_OBJECT

public:
  Viewer(QWidget *parent = 0);

private slots:
  void openFile();

private:
  QAction *openFileAction;
  QAction *quitAction;

  QLabel *imageLabel;
  QString fileName;
};

#endif
</pre>
<p>We need the Q_OBJECT macro because we are using Qt's &quot;signals
and slots&quot; mechanism in our subclass. We will connect the &quot;open
file&quot; action (<span class="guimenu">File</span>|<span class=
"guimenuitem">Open</span>) to the <tt class=
"function">openFile()</tt> slot. We'll explain the rest as we
describe the implementation in viewer.cpp, piece by piece, starting
with the includes.</p>
<pre class="programlisting">
#include &lt;qaction.h&gt;
#include &lt;qfiledialog.h&gt;

#include &lt;qimage.h&gt;
#include &lt;qlabel.h&gt;
#include &lt;qmenubar.h&gt;
#include &lt;qpopupmenu.h&gt;
#include &lt;qstatusbar.h&gt;
#include &lt;qtoolbar.h&gt;
#include &quot;viewer.h&quot;
#include &quot;icon.xpm&quot;
#include &quot;openfile.xpm&quot;
</pre>
<p>We include all the Qt classes we need, viewer.h, and also two
XPM files. The XPM file format is an image format that is also
valid C++. XPM images are easy to find on the Internet, and Linux
distributions come with lots of them.</p>
<p>The constructor for a main window application is usually
concerned with the creation of &quot;actions&quot;: these are are
&quot;activated'' when the user clicks their associated menu option or
toolbar button, or types their keyboard shortcut. Main windows
usually have very simple layouts since they often contain either a
single widget or an MDI (multiple document interface)
workspace.</p>
<pre class="programlisting">
Viewer::Viewer(QWidget *parent)
               : QMainWindow(parent),
                 fileName(&quot;.&quot;) {
  imageLabel = new QLabel(this);
  imageLabel-&gt;setAlignment(AlignCenter);
  setCentralWidget(imageLabel);

  openFileAction =
        new QAction(QPixmap(openfile_xpm),
                    &quot;&amp;Open...&quot;,
                    CTRL+Key_O, this);
  connect(openFileAction,
          SIGNAL(activated()), 
          this,
          SLOT(openFile()));
  quitAction = new QAction(&quot;&amp;Quit&quot;,
                           CTRL+Key_Q,
                           this);
  connect(quitAction, SIGNAL(activated()), 
          this, SLOT(close()));

  QPopupMenu *fileMenu = new QPopupMenu(this);
  openFileAction-&gt;addTo(fileMenu);
  quitAction-&gt;addTo(fileMenu);
  menuBar()-&gt;insertItem(&quot;&amp;File&quot;, fileMenu);

  QToolBar *fileTools =
            new QToolBar(&quot;File Tools&quot;, this);
  openFileAction-&gt;addTo(fileTools);
  setCaption(&quot;Image Viewer&quot;);
  setIcon(QPixmap(viewer_xpm));

  statusBar()-&gt;message(&quot;Ready&quot;);
}
</pre>
<div class="c2"><img src="/var/uploads/journals/resources/standard-gui-applications.png"
align="middle"></div>
<p>We begin by creating a label widget that will be used to display
the image. We then create two actions, the first &quot;open file'', has
an icon (<tt class="filename">openfile.xpm</tt>) and a shortcut of
<tt class="literal">Ctrl+O</tt>. We connect the action to our
custom <tt class="function">openFile()</tt> slot (implemented
shortly). The &quot;quit&quot; action is connected to the built-in <tt class=
"function">close()</tt> slot. After the actions are created we want
to give them a visual representation in the user interface. We
create a new menu and add the &quot;open file&quot; action, and the &quot;quit&quot;
action to it. We also create a toolbar and add the &quot;open file&quot;
action to it. Qt automatically keeps menus and toolbars in
sync.</p>
<p>Finally we set the application's caption and icon, and display
&quot;Ready&quot; on the status bar. The first time we call <tt class=
"function">menuBar()</tt> and <tt class=
"function">statusBar()</tt>, Qt creates them; this ensures they are
only created if they're actually used.</p>
<p>When the user invokes the &quot;open file&quot; action (by choosing
<span class="guimenu">File</span>|<span class=
"guimenuitem">Open</span>, by clicking the &quot;open&quot; toolbar button,
or by pressing <tt class="literal">Ctrl+O</tt>), the <tt class=
"function">openFile()</tt> slot is called.</p>
<pre class="programlisting">
void Viewer::openFile() {
  QStringList formats =
                    QImage::inputFormatList();
  QString filters = &quot;Images (*.&quot;
                     + formats.join(&quot; *.&quot;)
                              .lower() + &quot;)&quot;;
  QString newFileName =
      QFileDialog::getOpenFileName(fileName,
                               filters, this);
  if(!newFileName.isEmpty()) {
    fileName = newFileName;
    QPixmap pixmap(fileName);


    imageLabel-&gt;setPixmap(pixmap);
    statusBar()-&gt;message(QString(&quot;%1 %2x%3&quot;)
                  .arg(fileName)
                  .arg(pixmap.width())
                  .arg(pixmap.height()));
  }
}
</pre>
<p>Qt can provide a list of the image formats it can read, and we
use this to create a file filter. For example, the filter might
look like this, &quot;Images (*.bmp *.gif *.jpeg *.pbm *.pgm *.png *.ppm
*.xbm *.xpm)&quot;. We use one of <tt class=
"classname">QFileDialog</tt>'s static convenience functions to get
an image file name, and unless the user clicks <span class=
"guibutton">Cancel</span> (in which case <tt class=
"function">getOpenFileName()</tt> returns an empty string), we load
the image and put some information in the status bar. If we didn't
need to access the image after reading it we could have simply
used:</p>
<pre class="programlisting">
imageLabel-&gt;setPixmap(QPixmap(fileName));
</pre>
<p>To build and run the application, save the files in a directory
of their own (e.g. <tt class="filename">viewer</tt>), change to
that directory, and run the following commands:</p>
<pre class="screen">
qmake -project
qmake viewer.pro
make
</pre>
<p>The first command creates a project file, the second creates a
makefile based on the project file, and the third builds the
application. If you use Visual Studio, use <span class=
"application">nmake</span> instead of <span class=
"application">make</span>.</p>
<p>In the previous article we saw how to create a dialog and lay
out widgets inside it. Now we've seen how to create a main window
application. In the next installment we'll combine this knowledge
to create an application that can interact with the user through a
dialog, and later on we'll see how to create custom widgets with
any look and behaviour we want.</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
