Coding between Mouse and Keyboard, Part II
In Part I of this series [LJ, September 2002] we created the GUI of a tiny text editor using Qt Designer. Now, we add missing functionality and translate the application into other languages by using our favourite editor along with make and the g++ C++ compiler, and use Qt Linguist as an attractive working environment during translation.
We use the new qmake utility to write the Makefile for our Qt application; qmake outdates tmake, a Perl tool widely used with older Qt versions.
Our editor GUI already closes windows and the entire application, but we still lack a user dialog that asks whether the old data should be saved or discarded or whether the user wants to stay with the old file. The New, Save and Save As actions do nothing right now, but everything else was completed. The GUI already supports copy, cut and paste, undo and redo. It can switch font characteristics to italic, bold, underlined and any combination of the three. These QTextEdit actions already can be tested in the Qt Designer preview. The About entry in the Help menu will be fully functional as soon as we compile the GUI into a C++ program.
We could write the remaining functions using Qt Designer's built-in code editor. As there are no means to compile the project within the Designer, however, using one's favourite text editor is faster.
Now that we have the user interface ready in a ui file for the interface description, and a ui.h file containing the code already written, it's time to implement the remaining functionality. First we have to convert the XML to C++ with the User Interface Compiler, uic, but using qmake we don't need to worry about this detail. Let's feed it the project file generated by the Designer:
qmake -o Makefile lj-article.pro
A Makefile is created with a subdirectory named .ui that is supposed to store the C++ code generated from the ljeditor.ui and ljeditor.ui.h files. If this fails and you are asked to set the QMAKEPATH, set this variable to the mkspecs subdirectory of your Qt installation, which describes your operating system and compiler. For example:
QMAKEPATH=$QTDIR/mkspecs/linux-g++ export QMAKEPATHDepending on where you have installed Qt, make sure that the search path contains the $QTDIR/bin directory of the used Qt version.
To generate the C++ files simply type:
make .ui/ljeditor.h make .ui/ljeditor.cpp
If problems arise, check the environment variables QTDIR, PATH and LD_LIBRARY_PATH. The first one should point to the directory parenting the Qt 3.0 subdirectories lib and include. The directories where uic, qmake and designer live should be included in the path, and $QTDIR/lib should be added to the linker path.
Editing the two generated files means the changes are lost when the ui file is moved to the Designer and a new conversion round becomes necessary. So, we derive a subclass from ljeditor and add our changes to it instead of to ljeditor.
uic offers the command-line switches -subdecl classname and -subimpl classname to build the appropriate code skeletons. With
uic -o editor.h -subdecl Editor .ui/ljeditor.h \ ljeditor.ui
we obtain editor.h, the header file for the new Editor subclass. On the other hand (mind the argument header file), the following line creates the implementation skeleton in editor.cpp:
uic -o editor.cpp -subimpl Editor editor.h \ ljeditor.uiThese new files need to be added to the project file by adding two lines:
HEADERS += editor.h SOURCES += editor.cppto lj-article.pro. Or you could start Qt Designer, open the project file and add them via Project®Add File. Remember to set the File type to C++ Files, otherwise the file dialog won't find them). If you like the text editor included in the Designer, you even might edit them there.
The subclass code generated by uic always includes skeletons for all functions present in the parent class. Thus, it's a good idea to delete the declarations and function skeletons of all functions that you don't plan to re-implement in the subclass. Remove the lines:
void fileExit(); void helpAbout(); void fileClose();
from editor.h and the relevant code skeletons from editor.cpp, which look like:
void Editor::fileExit()
{
qWarning( "Editor::fileExit() "
"not yet implemented!" );
}
For a complete program we still need a main() function. We may
write it by hand, but Qt Designer can help you a little. Choose
File®New®C++ Main-File (main.cpp) from the menu and the
subsequent dialog.
The dialog shown in Figure 1 asks us to name the main file (we choose ljedit.cpp) and the main widget. Designer does not provide the Editor subclass here; thus we don't really have a choice and choose ljeditor.

Figure 1. Configuring the main File
Choosing this name means we have to correct the generated code. Instead of ljeditor.h, we include editor.h, and instead of creating a new object of the ljeditor class, we need an Editor one. Now our ljedit.cpp should look like this:
#include <qapplication.h>
#include "editor.h"
int main( int argc, char ** argv )
{
QApplication a( argc, argv );
Editor *w = new Editor;
w->show();
a.connect( &a, SIGNAL( lastWindowClosed() ),
&a, SLOT( quit() ) );
return a.exec();
}
As in every usual Qt main(), we create a QApplication object, hand it possible command-line arguments (argv) and create the Editor widget w. Then we show it to the world and enter the application loop with a.exec().
You may notice that a a.setMainWidget( w ); line is missing that defines the main widget of the application (we'll explain this later). However, without a main widget, the application will not quit when the last window is closed. So, we have to connect the application object's signal, lastWindowClosed(), to its quit() slot.
make and a subsequent ./lj-article in the project directory should result in a running, yet not fully functional text editor. If you wish to call the binary by something other than the project file's base name, add the line TARGET = ljedit to lj-article.pro.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.
Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.
Sponsored by ActiveState
| Speed Up Your Web Site with Varnish | Jun 19, 2013 |
| Non-Linux FOSS: libnotify, OS X Style | Jun 18, 2013 |
| Containers—Not Virtual Machines—Are the Future Cloud | Jun 17, 2013 |
| Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer | Jun 12, 2013 |
| Weechat, Irssi's Little Brother | Jun 11, 2013 |
| One Tail Just Isn't Enough | Jun 07, 2013 |
- Speed Up Your Web Site with Varnish
- Containers—Not Virtual Machines—Are the Future Cloud
- Linux Systems Administrator
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- RSS Feeds
- Senior Perl Developer
- Technical Support Rep
- Non-Linux FOSS: libnotify, OS X Style
- UX Designer
- Web & UI Developer (JavaScript & j Query)
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




3 min 28 sec ago
25 min 47 sec ago
30 min 19 sec ago
3 hours 16 min ago
3 hours 33 min ago
4 hours 49 min ago
5 hours 38 min ago
5 hours 41 min ago
5 hours 50 min ago
6 hours 19 min ago