Qt GUI Toolkit
Flickering is a common problem in graphics programming. Some GUI programs do updating by clearing the area of a widget and then draw the different graphics elements. This process normally takes enough time for the eye to notice the clearing and drawing process. The widget flickers, the program looks unprofessional and fatigues the eyes of the users.
A technique called double-buffering can be used to solve this problem. A pixmap (i.e., pixel map—an off-screen memory segment used as if it were a part of the screen raster buffer) is used, and all drawing is done off-screen on this pixmap. The pixmap is then transferred to the screen in one lightning-fast operation. This pixmap transfer is normally so fast that on most systems it appears instantaneous to the human eye.
Sometimes a pixmap the size of the widget to update is used, in other cases, only certain parts of the widget are double-buffered. Which method will be most effective must be considered in each case.
Pixmaps often contain large amounts of data and are often slow to create and handle (in CPU-time). A good technique is to store the buffer pixmap as a part of the widget. When the widget needs to update itself (in Qt, whenever it receives a paint event), it simply copies the required part of the buffer pixmap to the part of the widget that must be repainted.
Often, it is useful to include a dirty flag as a part of the widget. All state changes (i.e., changes to member variables) that affect the visual appearance of the widget can then simply set this flag to TRUE telling the widget to repaint itself. The paint event function then checks the dirty flag, and updates the buffer pixmap before it updates the screen. This ensures that all widget painting code is in one place, making the widget easier to maintain and debug.
I've found this technique to be very useful and powerful and have used it on a variety of GUI-systems, as well as Qt.
OK, now that we've looked at different parts of Qt, let's use it to build a custom-made software component that can display an image and rotate it by an angle. This widget should contain slots with instructions to let the user choose a file on disk, and it should have the ability to print the rotated image on a printer.
As a start we decide to give it the following signals and slots:
public slots:
void setAngle( int degrees );
void load();
void print();
signals:
void angleChanged( int );
void filePathChanged( const char * );
We can now set the rotation angle setAngle, let the user choose a new image file load, and print the image print. We choose to implement the functionality we need for the first version first. Later this component can be expanded to include slots like setPixmap(QPixmap) or setFilePath(QString).
The two signals tell the world about a change in the rotation angle (angleChanged) or the image file being displayed (filePathChanged).
Next, we include two member functions to fetch the angle and file path:
public:
int angle() const { return ang; }
const char *filePath() const { return name; }
And we include the following member variables:
private:
int ang;
QString name;
QPixmap pix;
QPrinter printer;
QFileDialog fileDlg;
QPixmap bufferPix;
bool dirty;
By setting these variables, we store an angle, file name, pixmap, printer and file selection dialog in the component. We want the widget to update itself smoothly and have decided to use the double-buffering technique, so we store a buffer pixmap. In addition, we have a dirty flag which is set when the widget needs to update the buffer pixmap. The combination of a buffer pixmap and a dirty flag is a very useful and powerful GUI technique that can be used in a large range of widgets.
Also, the widget has a paint event function and a resize event function, see code Listing 3 for the full class declaration.
Since we want to be able to paint to both the screen and a printer, we put the drawing code in a private member function that operates on a QPainter:
void PixmapRotator::paintRotatedPixmap(QPainter *p)
{
// need device width and height
QPaintDeviceMetrics m( p->device() );
// center point
p-$gt;translate( (m.width())/2,
(m.height()) / 2 );
p->rotate( ang );
p->drawPixmap( - (pix.width())/2,
- (pix.height())/2, pix );
}
First we fetch the metrics of the device the painter is operating on. We use the width and height of the device to put the center (0,0) of our coordinate system in the middle of the device. Next we rotate the coordinate system by the wanted angle and draw the pixmap with its center point at (0,0). In other words, the center point of the pixmap is put at the center point of the device.
The paint event function looks like this:
void PixmapRotator::paintEvent( QPaintEvent *e )
{
if ( dirty ) { // buffer needs update?
// same size as widget
bufferPix.resize( size() );
// clear pixmap
bufferPix.fill( backgroundColor() );
QPainter p;
// paint on buffer pixmap
p.begin( &bufferPix );
paintRotatedPixmap( &p );
p.end();
dirty = FALSE; // buffer now new and clean
} // update exposed region:
bitBlt( this, e->rect().topLeft(), &bufferPix,
e->rect() );
}
If the widget is “dirty”, we need to update the buffer pixmap. We set its size to the size of the widget, clear it and call our local painting function. Don't forget to reset the dirty flag when a buffer pixmap has been updated.
Finally, we use the QPaintEvent pointer to find out which part of the widget must be updated and call bitBlt. bitBlt is a global function that can transfer data from one paint device to another as fast as possible. bitBlt is common GUI shorthand for “bit block transfer”.
With double-buffering and a dirty flag, the resize event function becomes trivial:
void PixmapRotator::resizeEvent( QResizeEvent *e )
{
dirty = TRUE; // need to redraw
}
Again, it is never necessary to repaint a widget in a resize event, since Qt automatically sends a paint event after the resize event.
With a common drawing function doing printing is also easy:
void PixmapRotator::print()
{
// opens printer dialog
if ( printer.setup(this) ) {
QPainter p;
p.begin( &printer ); // paint on printer
paintRotatedPixmap( &p );
p.end(); // send job to printer
}
}
First we let the user setup the printer, then we open a painter on that printer, and finally, call the drawing function.
Loading a new image takes a bit more code:
void PixmapRotator::load()
{
QString newFile;
QPixmap tmpPix;
while ( TRUE ) {
// open file dialog
if ( fileDlg.exec() != QDialog::Accepted )
return; // the user clicked cancel
// get the file path
newFile = fileDlg.selectedFile();
// is it an image?
if ( tmpPix.load( newFile ) )
break; // yes, break the loop
QString s; // build a message string
s.sprintf("Could not load \"%s\"",
newFile.data() );
// sorry!
QMessageBox::message( "Error", s );
}
pix = tmpPix; // keep the pixmap
name = newFile; // new file name
emit filePathChanged( name ); // tell world
dirty = TRUE; // need to redraw
repaint( FALSE ); // paint the whole widget
}
We set up a loop that opens the file dialog box. If the user has selected a file that cannot be loaded, we tell her and let her try again. If a valid file has been selected, we copy the new pixmap and the file path. Finally, we emit a signal to tell the world, mark the widget as dirty and repaint all of it (the FALSE argument means that Qt should not clear the widget before sending the paint event).
We have now made a new software component which can be connected to others through the signal/slot mechanism. See www.troll.no/qt for the full code of the PixmapRotator widget.
Today’s modular x86 servers are compute-centric, designed as a least common denominator to support a wide range of IT workloads. Those generic, virtualized IT workloads have much different resource optimization requirements than hyperscale and cloud applications. They have resulted in a “one size fits all” enterprise IT architecture that is not optimized for a specific set of IT workloads, and especially not emerging hyperscale workloads, such as web applications, big data, and object storage. In this report, you will learn how shifting the focus from traditional compute-centric IT architectures to an innovative disaggregated fabric-based architecture can optimize and scale your data center.
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
| 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 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
| Trying to Tame the Tablet | May 08, 2013 |
- Using Salt Stack and Vagrant for Drupal Development
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- New Products
- Validate an E-Mail Address with PHP, the Right Way
- Drupal Is a Framework: Why Everyone Needs to Understand This
- A Topic for Discussion - Open Source Feature-Richness?
- The Pari Package On Linux
- Home, My Backup Data Center
- New Products
- Developer Poll
- This is the easiest tutorial
4 hours 19 min ago - Ahh, the Koolaid.
9 hours 58 min ago - git-annex assistant
15 hours 58 min ago - direct cable connection
16 hours 20 min ago - Agreed on AirDroid. With my
16 hours 30 min ago - I just learned this
16 hours 35 min ago - enterprise
17 hours 5 min ago - not living upto the mobile revolution
19 hours 56 min ago - Deceptive Advertising and
20 hours 31 min ago - Let\'s declare that you have
20 hours 32 min ago
Enter to Win an Adafruit Prototyping Pi Plate 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 Prototyping Pi Plate 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
- Next winner announced on 5-21-13!
Free Webinar: Linux Backup and Recovery
Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.
In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.




Comments
GUI deveopment using QT
i wanted to know as to how a GUI can be developed using QT with C++ program give an example .
linux
sir,
i am troubling about qt.i am begineer of linux.In my project i am doing in linux.for gui designing we use qt design.i not very well about qt:gui design and where we write code in qt,and how to complie in c++ coding.i am using fedora.pls give me steps for designing and coding... i am waiting..