Next: 10 - GUI Module, Previous: 08 - Building Storage Module
The Graphical User Interface (GUI) module implements the main window of the application. It uses previously created Generator and Storage modules to generate and store passwords.
We start by creating the gui.h file in the src/apps/PswGen/GUI directory:
/** * @file PswGen/GUI/gui.h */ #ifndef __PSWGEN_GUI_GUI_H # define __PSWGEN_GUI_GUI_H #endif // gui.h
Include the Plugins/iPlugin header file as this is going to be a plugin and also QObject and QString as these are almost always needed:
#include <Plugins/iPlugin> #include <QObject> #include <QString>
We use the eVaf::PswGen::GUI namespace for this module:
namespace eVaf { namespace PswGen { namespace GUI { } // namespace eVaf::PswGen::GUI } // namespace eVaf::PswGen } // namespace eVaf
The module itself can be implemented as one single class derived from the Plugins::iPlugin parent class:
class Module : public Plugins::iPlugin { Q_OBJECT public: Module(); virtual ~Module(); };
Implement pure virtual methods derived from the parent class. The main GUI window is created in the init() method and the module can only be ready when the initialization is completed. We use the mReady flag to indicate this.
virtual bool init(const QString & args); virtual void done(); virtual bool isReady() const { return mReady; } private: bool mReady;
In the private members section we store interfaces from previously written modules:
eVaf::PswGen::iGenerator * mGenerator; eVaf::PswGen::iStorage * mStorage;
Since these are not known yet, we also need to add forward declarations. These go into the eVaf::PswGen namespace at the beginning of the file:
namespace eVaf { namespace PswGen { struct iGenerator; struct iStorage;
The main window needs couple of widgets on it:
/// Widgets on the screen QLineEdit * wMasterPassword; QLineEdit * wName; QSpinBox * wLength; QLineEdit * wPassword; QPushButton * wGenerate; QPushButton * wCopy;
Add slots for push buttons:
private slots: /// 'Generate' button clicked void generateClicked(); /// 'Copy' button clicked void copyClicked();
The private keyword is ignored by the Qt meta-object compiler, but it is a good practice to have it here as an indicator, that these slots are private and should not be used outside of the class.
The Generate push button should be enabled only when the master password and name are given. Add another slot that will be connected to the textChanged() signal from these widgets:
/// Master password or name changed void textChanged(QString const &);
And here is the final gui.h file:
/** * @file PswGen/GUI/gui.h */ #ifndef __PSWGEN_GUI_GUI_H # define __PSWGEN_GUI_GUI_H #include <Plugins/iPlugin> #include <QObject> #include <QString> class QLineEdit; class QSpinBox; class QPushButton; namespace eVaf { namespace PswGen { struct iGenerator; struct iStorage; namespace GUI { /// Graphical User Interface for the PswGen application. class Module : public Plugins::iPlugin { Q_OBJECT public: Module(); virtual ~Module(); virtual bool init(const QString & args); virtual void done(); virtual bool isReady() const { return mReady; } private slots: /// Master password or name changed void textChanged(QString const &); /// 'Generate' button clicked void generateClicked(); /// 'Copy' button clicked void copyClicked(); private: // Members static int const DefaultPasswordLength; /// Flag indicating that the module is ready bool mReady; /// The iGenerator interface eVaf::PswGen::iGenerator * mGenerator; /// The iStorage interface (can be null) eVaf::PswGen::iStorage * mStorage; /// Widgets on the screen QLineEdit * wMasterPassword; QLineEdit * wName; QSpinBox * wLength; QLineEdit * wPassword; QPushButton * wGenerate; QPushButton * wCopy; }; } // namespace eVaf::PswGen::GUI } // namespace eVaf::PswGen } // namespace eVaf #endif // gui.h
Continue implementing the GUI Module.