1 <!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html lang=
"et" xmlns=
"http://www.w3.org/1999/xhtml" xml:
lang=
"et">
5 <meta http-equiv=
"CONTENT-TYPE" content=
"text/html; charset=utf-8" />
6 <title>eVaf Tutorial -
09 - GUI Module
</title>
7 <meta name=
"Author" content=
"Enar Väikene" />
8 <meta name=
"description" content=
"eVaf Tutorial" />
9 <meta name=
"keywords" content=
"evaf c++ application development framework tutorial password generator" />
10 <link rel=
"StyleSheet" href=
"evaf.css" type=
"text/css" media=
"all" />
11 <link rel=
"StyleSheet" href=
"highlight.css" type=
"text/css" media=
"all" />
16 <h1>eVaf Tutorial
</h1>
18 <h2>09 - GUI Module
</h2>
20 <p>The Graphical User Interface (
<tt>GUI
</tt>) module implements the main window of the application. It uses previously
21 created
<tt>Generator
</tt> and
<tt>Storage
</tt> modules to generate and store passwords.
</p>
23 <p>We start by creating the
<tt>gui.h
</tt> file in the
<tt>src/apps/PswGen/GUI
</tt> directory:
</p>
25 <pre class=
"hl"><span class=
"hl com">/**
</span>
26 <span class=
"hl com"> *
@file PswGen/GUI/gui.h
</span>
27 <span class=
"hl com"> */
</span>
29 <span class=
"hl ppc">#ifndef __PSWGEN_GUI_GUI_H
</span>
30 <span class=
"hl ppc"># define __PSWGEN_GUI_GUI_H
</span>
32 <span class=
"hl ppc">#endif
</span> <span class=
"hl slc">// gui.h
</span><span class=
"hl ppc"></span></pre>
34 <p>Include the
<tt>Plugins/iPlugin
</tt> header file as this is going to be a plugin and also
<tt>QObject
</tt> and
35 <tt>QString
</tt> as these are almost always needed:
</p>
37 <pre class=
"hl"><span class=
"hl ppc">#include
<Plugins/iPlugin
></span>
38 <span class=
"hl ppc">#include
<QObject
></span>
39 <span class=
"hl ppc">#include
<QString
></span></pre>
41 <p>We use the
<tt>eVaf::PswGen::GUI
</tt> namespace for this module:
</p>
43 <pre class=
"hl"><span class=
"hl kwa">namespace
</span> eVaf
<span class=
"hl opt">{
</span>
44 <span class=
"hl kwa">namespace
</span> PswGen
<span class=
"hl opt">{
</span>
45 <span class=
"hl kwa">namespace
</span> GUI
<span class=
"hl opt">{
</span>
47 <span class=
"hl opt">}
</span> <span class=
"hl slc">// namespace eVaf::PswGen::GUI
</span>
48 <span class=
"hl opt">}
</span> <span class=
"hl slc">// namespace eVaf::PswGen
</span>
49 <span class=
"hl opt">}
</span> <span class=
"hl slc">// namespace eVaf
</span></pre>
51 <p>The module itself can be implemented as one single class derived from the
<tt>Plugins::iPlugin
</tt> parent class:
</p>
53 <pre class=
"hl"><span class=
"hl kwc">class
</span> Module
<span class=
"hl opt">:
</span> <span class=
"hl kwc">public
</span> Plugins
<span class=
"hl opt">::
</span>iPlugin
54 <span class=
"hl opt">{
</span>
57 <span class=
"hl kwc">public
</span><span class=
"hl opt">:
</span>
59 <span class=
"hl kwd">Module
</span><span class=
"hl opt">();
</span>
61 <span class=
"hl kwc">virtual
</span> <span class=
"hl opt">~
</span><span class=
"hl kwd">Module
</span><span class=
"hl opt">();
</span>
63 <span class=
"hl opt">};
</span></pre>
65 <p>Implement pure virtual methods derived from the parent class. The main GUI window is created in the
<tt>init()
</tt> method
66 and the module can only be ready when the initialization is completed. We use the
<tt>mReady
</tt> flag to indicate this.
</p>
68 <pre class=
"hl"> <span class=
"hl kwc">virtual
</span> <span class=
"hl kwb">bool
</span> <span class=
"hl kwd">init
</span><span class=
"hl opt">(
</span><span class=
"hl kwb">const
</span> QString
<span class=
"hl opt">&</span> args
<span class=
"hl opt">);
</span>
70 <span class=
"hl kwc">virtual
</span> <span class=
"hl kwb">void
</span> <span class=
"hl kwd">done
</span><span class=
"hl opt">();
</span>
72 <span class=
"hl kwc">virtual
</span> <span class=
"hl kwb">bool
</span> <span class=
"hl kwd">isReady
</span><span class=
"hl opt">()
</span> <span class=
"hl kwb">const
</span> <span class=
"hl opt">{
</span> <span class=
"hl kwa">return
</span> mReady
<span class=
"hl opt">; }
</span>
74 <span class=
"hl kwc">private
</span><span class=
"hl opt">:
</span>
76 <span class=
"hl kwb">bool
</span> mReady
<span class=
"hl opt">;
</span></pre>
78 <p>In the private members section we store interfaces from previously written modules:
</p>
81 eVaf
<span class=
"hl opt">::
</span>PswGen
<span class=
"hl opt">::
</span>iGenerator
<span class=
"hl opt">*
</span> mGenerator
<span class=
"hl opt">;
</span>
83 eVaf
<span class=
"hl opt">::
</span>PswGen
<span class=
"hl opt">::
</span>iStorage
<span class=
"hl opt">*
</span> mStorage
<span class=
"hl opt">;
</span></pre>
85 <p>Since these are not known yet, we also need to add forward declarations. These go into the
<tt>eVaf::PswGen
</tt> namespace
86 at the beginning of the file:
</p>
89 <span class=
"hl kwa">namespace
</span> eVaf
<span class=
"hl opt">{
</span>
90 <span class=
"hl kwa">namespace
</span> PswGen
<span class=
"hl opt">{
</span>
91 <span class=
"hl kwb">struct
</span> iGenerator
<span class=
"hl opt">;
</span>
92 <span class=
"hl kwb">struct
</span> iStorage
<span class=
"hl opt">;
</span></pre>
94 <p>The main window needs couple of widgets on it:
</p>
97 <li>Master password - a QLineEdit widget;
</li>
98 <li>Name of the password - a QLineEdit widget;
</li>
99 <li>Length of the password - a QSpinBox widget;
</li>
100 <li>Generated password - a QLineEdit widget that we make read-only;
</li>
101 <li>Generate button - a QPushButton widget;
</li>
102 <li>Copy button that copies generated passwords to the clipboard - a QPushButton widget.
</li>
106 <span class=
"hl slc">/// Widgets on the screen
</span>
107 QLineEdit
<span class=
"hl opt">*
</span> wMasterPassword
<span class=
"hl opt">;
</span>
108 QLineEdit
<span class=
"hl opt">*
</span> wName
<span class=
"hl opt">;
</span>
109 QSpinBox
<span class=
"hl opt">*
</span> wLength
<span class=
"hl opt">;
</span>
110 QLineEdit
<span class=
"hl opt">*
</span> wPassword
<span class=
"hl opt">;
</span>
111 QPushButton
<span class=
"hl opt">*
</span> wGenerate
<span class=
"hl opt">;
</span>
112 QPushButton
<span class=
"hl opt">*
</span> wCopy
<span class=
"hl opt">;
</span></pre>
114 <p>Add slots for push buttons:
</p>
116 <pre class=
"hl"><span class=
"hl kwc">private
</span> slots
<span class=
"hl opt">:
</span>
118 <span class=
"hl slc">/// 'Generate' button clicked
</span>
119 <span class=
"hl kwb">void
</span> <span class=
"hl kwd">generateClicked
</span><span class=
"hl opt">();
</span>
121 <span class=
"hl slc">/// 'Copy' button clicked
</span>
122 <span class=
"hl kwb">void
</span> <span class=
"hl kwd">copyClicked
</span><span class=
"hl opt">();
</span></pre>
124 <p>The
<tt>private
</tt> keyword is ignored by the Qt meta-object compiler, but it is a good practice to have it here
125 as an indicator, that these slots are private and should not be used outside of the class.
</p>
127 <p>The
<tt>Generate
</tt> push button should be enabled only when the master password and name are given. Add another
128 slot that will be connected to the
<tt>textChanged()
</tt> signal from these widgets:
</p>
131 <span class=
"hl slc">/// Master password or name changed
</span>
132 <span class=
"hl kwb">void
</span> <span class=
"hl kwd">textChanged
</span><span class=
"hl opt">(
</span>QString
<span class=
"hl kwb">const
</span> <span class=
"hl opt">&);
</span></pre>
134 <p>And here is the final
<tt>gui.h
</tt> file:
</p>
136 <pre class=
"hl"><span class=
"hl com">/**
</span>
137 <span class=
"hl com"> *
@file PswGen/GUI/gui.h
</span>
138 <span class=
"hl com"> */
</span>
139 <span class=
"hl ppc">#ifndef __PSWGEN_GUI_GUI_H
</span>
140 <span class=
"hl ppc"># define __PSWGEN_GUI_GUI_H
</span>
142 <span class=
"hl ppc">#include
<Plugins/iPlugin
></span>
144 <span class=
"hl ppc">#include
<QObject
></span>
145 <span class=
"hl ppc">#include
<QString
></span>
147 <span class=
"hl kwc">class
</span> QLineEdit
<span class=
"hl opt">;
</span>
148 <span class=
"hl kwc">class
</span> QSpinBox
<span class=
"hl opt">;
</span>
149 <span class=
"hl kwc">class
</span> QPushButton
<span class=
"hl opt">;
</span>
151 <span class=
"hl kwa">namespace
</span> eVaf
<span class=
"hl opt">{
</span>
152 <span class=
"hl kwa">namespace
</span> PswGen
<span class=
"hl opt">{
</span>
153 <span class=
"hl kwb">struct
</span> iGenerator
<span class=
"hl opt">;
</span>
154 <span class=
"hl kwb">struct
</span> iStorage
<span class=
"hl opt">;
</span>
155 <span class=
"hl kwa">namespace
</span> GUI
<span class=
"hl opt">{
</span>
157 <span class=
"hl com">/// Graphical User Interface for the PswGen application.
</span>
158 <span class=
"hl kwc">class
</span> Module
<span class=
"hl opt">:
</span> <span class=
"hl kwc">public
</span> Plugins
<span class=
"hl opt">::
</span>iPlugin
159 <span class=
"hl opt">{
</span>
162 <span class=
"hl kwc">public
</span><span class=
"hl opt">:
</span>
164 <span class=
"hl kwd">Module
</span><span class=
"hl opt">();
</span>
166 <span class=
"hl kwc">virtual
</span> <span class=
"hl opt">~
</span><span class=
"hl kwd">Module
</span><span class=
"hl opt">();
</span>
168 <span class=
"hl kwc">virtual
</span> <span class=
"hl kwb">bool
</span> <span class=
"hl kwd">init
</span><span class=
"hl opt">(
</span><span class=
"hl kwb">const
</span> QString
<span class=
"hl opt">&</span> args
<span class=
"hl opt">);
</span>
170 <span class=
"hl kwc">virtual
</span> <span class=
"hl kwb">void
</span> <span class=
"hl kwd">done
</span><span class=
"hl opt">();
</span>
172 <span class=
"hl kwc">virtual
</span> <span class=
"hl kwb">bool
</span> <span class=
"hl kwd">isReady
</span><span class=
"hl opt">()
</span> <span class=
"hl kwb">const
</span> <span class=
"hl opt">{
</span> <span class=
"hl kwa">return
</span> mReady
<span class=
"hl opt">; }
</span>
174 <span class=
"hl kwc">private
</span> slots
<span class=
"hl opt">:
</span>
176 <span class=
"hl slc">/// Master password or name changed
</span>
177 <span class=
"hl kwb">void
</span> <span class=
"hl kwd">textChanged
</span><span class=
"hl opt">(
</span>QString
<span class=
"hl kwb">const
</span> <span class=
"hl opt">&);
</span>
179 <span class=
"hl slc">/// 'Generate' button clicked
</span>
180 <span class=
"hl kwb">void
</span> <span class=
"hl kwd">generateClicked
</span><span class=
"hl opt">();
</span>
182 <span class=
"hl slc">/// 'Copy' button clicked
</span>
183 <span class=
"hl kwb">void
</span> <span class=
"hl kwd">copyClicked
</span><span class=
"hl opt">();
</span>
185 <span class=
"hl kwc">private
</span><span class=
"hl opt">:
</span> <span class=
"hl slc">// Members
</span>
187 <span class=
"hl kwb">static int const
</span> DefaultPasswordLength
<span class=
"hl opt">;
</span>
189 <span class=
"hl slc">/// Flag indicating that the module is ready
</span>
190 <span class=
"hl kwb">bool
</span> mReady
<span class=
"hl opt">;
</span>
192 <span class=
"hl slc">/// The iGenerator interface
</span>
193 eVaf
<span class=
"hl opt">::
</span>PswGen
<span class=
"hl opt">::
</span>iGenerator
<span class=
"hl opt">*
</span> mGenerator
<span class=
"hl opt">;
</span>
195 <span class=
"hl slc">/// The iStorage interface (can be null)
</span>
196 eVaf
<span class=
"hl opt">::
</span>PswGen
<span class=
"hl opt">::
</span>iStorage
<span class=
"hl opt">*
</span> mStorage
<span class=
"hl opt">;
</span>
198 <span class=
"hl slc">/// Widgets on the screen
</span>
199 QLineEdit
<span class=
"hl opt">*
</span> wMasterPassword
<span class=
"hl opt">;
</span>
200 QLineEdit
<span class=
"hl opt">*
</span> wName
<span class=
"hl opt">;
</span>
201 QSpinBox
<span class=
"hl opt">*
</span> wLength
<span class=
"hl opt">;
</span>
202 QLineEdit
<span class=
"hl opt">*
</span> wPassword
<span class=
"hl opt">;
</span>
203 QPushButton
<span class=
"hl opt">*
</span> wGenerate
<span class=
"hl opt">;
</span>
204 QPushButton
<span class=
"hl opt">*
</span> wCopy
<span class=
"hl opt">;
</span>
205 <span class=
"hl opt">};
</span>
207 <span class=
"hl opt">}
</span> <span class=
"hl slc">// namespace eVaf::PswGen::GUI
</span>
208 <span class=
"hl opt">}
</span> <span class=
"hl slc">// namespace eVaf::PswGen
</span>
209 <span class=
"hl opt">}
</span> <span class=
"hl slc">// namespace eVaf
</span>
211 <span class=
"hl ppc">#endif
</span> <span class=
"hl slc">// gui.h
</span><span class=
"hl ppc"></span>
214 <p>Continue implementing the
<a href=
"pswgen10.html">GUI Module
</a>.
</p>