Dialog Partner Library (DlgPtn.lib)
Lingfa Yang
There are dozens, perhaps, hundreds of dialogs in every GUI application.
How to build dialogs? Of curse, every developer knows how to build.
But I am seeking a better way, a simple way, a clean way, a systematic way,
an efficient way, an automatic way . . .,
supporting separation of GUI from core, supporting multiple views . . .,
having advantage of flexibility, versatility, reusability . . .
This page shows my
Dialog
Partner
library
(
Dlg
Ptn.lib
).
With this library programming GUI applications becomes much easier then ever.
The simplest dialog:
Assume an application has a dialog, asking filename and size of an output image.
Here is my code to build a dialog.
It is a real dialog (Fig. 1), and it really works - pass user's inputs to the worker function.
void PlotXynWin::exportImg()
{
QString fileName="test.png";
int w = 512, h = 320;
MyDialog dlg("Export Image");
dlg.add("File Name", &fileName);
dlg.add("Width", &w);
dlg.add("Height", &h);
if(!dlg.exec()) return; // Cancelled
exportImg(fileName, w, h); // worker
}
|
 Fig. 1 The simplest dialog. |
The simplest tab dialog
Tab dialog is a dialog which contains more than one page.
void PlotXynWin::exportImg()
{
QString fileName="test.png";
int w = 512, h = 320;
npMixTab dlg("Tab Dialog");
MyWidget *p1 = dlg.page("Export Image");
p1->add("File Name", &fileName);
p1->add("Width", &w);
p1->add("Height", &h);
MyWidget *p2 = dlg.page("Page 2");
MyWidget *p3 = dlg.page("Page 3");
if(!dlg.exec()) return; // cancelled
// . . .
}
|
 Fig. 2 The simplest tab dialog. |
Pen and Brush
When you draw/paint, you have to pick your pen and brush.
Pen and brush have many attribute such as styles, width, and color and so on.
With my library to build a dialog is so simple: Get it and modify it.
MyDialog dlg;
symbolBrush = symbol.brush(); // Get a brush
dlg.addBrush("Symbol Brush", &symbolBrush); // Modify it
curvePen = crv->pen(); // Get a pen
dlg.addPen("Curve Pen", &curvePen);// Modify it
|
( Reload to active GIF animation to each tab )
Library Features
Bury dialog's implementation
No widget, no layout, no signal/slot are seen.
Why? This makes the code clean and easy to use.
Another advantage is code reusability.
Before I move to Qt, I was a VC developer using MFC.
Whatever, I use the same code as shown above to build the dialog.
Dialog works as a modifier
In this example, we have three local fields, fileName, w, and h declared first and
initialized.
Then, the dialog works as a modifier to change their values.
Bury Data type
To build the dialog just call add() and pass a Name-Pointer pair.
The overloaded method add() automatically matches different primitive types or user-defined types.
Accept/Reject
OK/Cancel button provides to accept/reject the input.
Press Ok to accept the input and pass to the worker; press Cancel abort and return.
Bury process of serialization/deflating/marshalling
Press Ok all display values will be taken. This process is serialized and also hidden for simplicity.
Dialog design patterns
Composition for widgets
class MyFileInfo : public QObject
{
private:
MyDialog *dlg; void build();
// members/fields
QString m_file;
};
|
// put NULL in initializer
MyFileInfo::MyFileInfo( . . .
: dlg(NULL)
{
}
|
// build once
void MyFileInfo::build()
{
if(dlg)return; // build once
dlg = new MyDialog("MyFileInfo");
. . .
}
|
Multiple inheritance
class FileInfoCore
{
public:
FileInfoCore(const QString & file);
protected:
// members/fields
QString m_file;
};
|
class FileInfoGui : public QObject, FileInfoCore
{
private:
MyDialog *dlg; void build();
};
|
Separate of core from GUI ( recommended )
class FileInfoCore
{
public:
FileInfoCore(const QString & file);
protected:
// members/fields
QString m_file;
};
|
class FileInfoGui : public QObject
{
public:
FileInfoGui(FileInfoCore *core);
private:
MyDialog *dlg; void build();
FileInfoCore &core; // must be initialized
// in constructor base/member initializer list
};
|
FileInfoGui::FileInfoGui(FileInfoCore *core)
: dlg(NULL), core(*core)
{
}
|
Dialog jungle (Dialog to/from XML)
With following simplest code, you can see simple or complex dialogs based on your design.
#include <QApplication>
#include "DialogTree.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
DialogFile df("???.xml");
return app.exec();
}
|
(Click snapshots to see the xmls)
User Interface for developers
Build interface
Syntax:
NameXXX *addXXX(const QString &name, XXX *value, QGridLayout *grid=0);
|
Layout interface
void newColumn();
void toTop();
void toMiddle();
void toBottom();
QGridLayout *group(const QString &title="");
|
signals
void memberUpdated(QWidget *widget);
|
slots
void accept();
void reject();
void apply();
void undo();
virtual bool save();
virtual bool saveAs();
bool domSaveAs();
void treeView();
virtual bool open();
virtual bool read();
|
Download Examples :
1 simplest dialog |
2 simplest tab dialog |
3 one xml |
4 group xmls ;
FileInfo Examples:
Composition for widgets |
Multiple inheritance |
Separate of core from GUI |
All above
Dialogs
| Model/View(
List/Tree,
Table, Network)
| XML/
Office 2007 XML
| COM/ActiveX
| Network TCP/IP
| OpenGL
| Online Help ...
|| MyQt
| Qt C++
| C/C++
| eBooks
|