Coding between Mouse and Keyboard, Part I
Closing a widget in Qt is easy: every Qt widget inherits a close() function from the mother of all Qt widgets, QWidget. This is not really much code, so it would be nice if we could fill the fileClose() slot with this one line.
A right-mouse click on the ljeditor form opens a context menu. The choice of its Source... entry does the trick. A code editor window appears and allows us to fill in the one-liner (see Figure 8):
void ljeditor::fileClose()
{
close();
}
So why not fill the fileExit() slot as well? To quit the entire application, the application object's closeAllWindows() function is called:
void ljeditor::fileExit()
{
qApp->closeAllWindows();
}
As the Designer usually does not deal with QApplication objects itself, qapplication.h (which provides the qApp proxy for the real application object) is not included by default, and the code generated from the ui description would not compile.
Fortunately, the Object Explorer allows us to include additional header files. By default it shows the Widgets tab (see Figure 4, bottom left), but we need the Source tab right now. Right-clicking the empty Includes (in Implementation) folder allows us to add a header file (New). Don't forget the <> brackets around a global include like <qapplication.h> (Figure 9).
Another slot we can fill with life without being afraid of getting too many compilation errors is helpAbout(). It is called when the user opens the About... entry in ljeditor's Help menu and simply pops up a message box with the caption About ljedit and some information about the program. By surrounding all text strings with tr() we make sure that the program can be localized painlessly, a task we will fulfill in Part II. For example:
void ljeditor::helpAbout()
{
QMessageBox::about( this, tr( "About ljedit" ),
tr( "A tiny text editor.\n"
"(C) 2002 Patricia Jung for Linux Journal\n"
"Using Qt 3.0.4 and Qt Designer." ) );
}
To be able to use QMessageBox::about(), we have to include <qmessagebox.h> the same way we did with <qapplication.h>. We add the remaining functionality in a subclass next time. Thus, all we have left to do with the Designer is clean up the new GUI.
Before we leave the Designer for good, we check that none of the assigned keyboard shortcuts has been used twice. This is done by choosing Check Accelerators from the Edit menu.
Additionally, we clean up all the ljeditor slots that we weren't going to implement anyway or that we used TextEdit slots for instead. By choosing Slots from the Edit menu (one way to do it), we open the dialog that allows us to mark editUndo() and remove it with a mouse click on Delete Slots (Figure 7). The same fate applies to editRedo(), editCut(), editCopy(), editPaste(), editFind(), helpIndex(), helpContents() and filePrint().
Furthermore, we check the GUI preview for separators that don't fit. As we decided against using the editFindAction, a single separator can be found at the end of ljeditor's Edit menu: once upon a time there was a Find entry below. To erase the separator, right-click on it in the form and choose Delete Item. The same applies to one of the two separators above the Exit entry in the file menu.
All GUI elements are in their place—time to let Qt adjust the widget proportions. Once again, we choose the entire form and select Lay Out Vertically from Layout in the main menu. If a user adjusts the application window size now, the TextEdit widget will follow. If we wish to place widget elements differently onto the form, we need to break the layout first.
Last but not least, we want this GUI to be stamped as ours. To do this we fill in the Author name and a description in the dialog raised by choosing Form Settings from the Edit menu (see Figure 10). Here it is possible to decide whether we want to store the icons in a subdirectory of our project directory or whether we include them directly in the user-interface description.
A final selection of Save all from the File menu and an XML file with the user-interface description (best named after the relevant class, e.g., ljeditor.ui) along with ljeditor.ui.h, the file storing the code we typed into the code editor, becomes part of the project.

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
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- RSS Feeds
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- New Products
- Using Salt Stack and Vagrant for Drupal Development
- A Topic for Discussion - Open Source Feature-Richness?
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Validate an E-Mail Address with PHP, the Right Way
- What's the tweeting protocol?
- Tech Tip: Really Simple HTTP Server with Python
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
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?







1 hour 14 min ago
5 hours 41 min ago
9 hours 17 min ago
9 hours 50 min ago
12 hours 13 min ago
12 hours 16 min ago
12 hours 18 min ago
16 hours 42 min ago
18 hours 33 min ago
23 hours 47 min ago