Double buffered flicker-free drawing in QT components

Source: Internet
Author: User
Tags drawtext polyline

Double-buffered drawing
In Qt4, all widgets are plotted by default using double buffering. With double buffering, you can lighten the flicker of the drawing. In some cases, users want to turn off double buffering and manage their own drawings. The following statement sets the Qt::wa_paintonscreen property of the widget to close the double buffering of the widget.
Mywidget->setattribute (Qt::wa_paintonscreen);

Because QT4 no longer provides an XOR pen, the combined mode Qpainter::compostionmode_xor () is not an XOR pen, QT4 only provides drawing feedback that qrubberband implement rectangles and lines. So to implement dynamic in the drawing
Feedback must use other methods. A double loop punch is used in the program to solve this problem. During the drawing process, a buffer draws temporary memory, a buffer holds the well-drawn content, and finally merges.
During the interactive drawing process, the program copies the image buffer to a temporary buffer, draws it on the temporary buffer, finishes drawing the result into the image buffer, and, if there is no interactive copy, displays the image buffer directly on the screen.

Double buffered flicker-free drawing in QT components
Flashing first, to reduce the flicker, set the component's background mode to Nobackground.
Setbackgroundmode (Nobackground);

Second, the PaintEvent () function of the overloaded component is rewritten as follows:
void Mywidget::p aintevent (qpaintevent *e)
{
Qrect ur=e->rect ();//Get component Size
QPIXMAP pix (Ur.size ());//Create a bitmap variable with this parameter
Pix.fill (This,ur.topleft ());//Fill bitmap
Qpainter p (&pic);//Create a Qpainter object as a bitmap parameter

P.translate (-ur.x (),-ur.y ());//painting on Qpainter
...//drawing

P.end ();//painting complete

BitBlt (This,ur.topleft (). &pix);//paste the bitmap onto the component

Note Starting with Qt4, the BitBlt function is not used and is replaced by Drawpixmap.
}

This is the key to a random plot of points, without setting this property, the default equivalent to every QT will complete the last screen erase,

There is no repaint (BOOL) interface in the new version of Qt.

W.setattribute (qt::wa_opaquepaintevent);

Old TV Snowflake effect every time you need to erase redraw to avoid the overlap of points so that the statement comment out

W.setattribute (qt::wa_opaquepaintevent);

(The following is the implementation of the private function:

void Plotter::updaterubberbandregion ()

{

Qrect rect = rubberbandrect.normalized ();

Update (Rect.left (), Rect.top (), Rect.width (), 1);Update (Rect.left (), Rect.top (), 1, Rect.height ());Update (Rect.left (), Rect.bottom (), Rect.width (), 1);Update (Rect.right (), Rect.top (), 1, Rect.height ());}The function Updaterubberband () is called in Mousepressevent (), Mousemoveevent (), and mousereleaseevent () to remove or redraw the rubber line. The function calls four update (), with four draw events to complete the drawing of four small rectangles consisting of a rubber line (two vertical and horizontal lines). QT also provides a class Qrubberband to draw rubber lines, but the control itself provides a better drawing functionvoid Plotter::refreshpixmap (){pixmap = qpixmap (Size ());Pixmap.fill (this, 0, 0);qpainter painter (&pixmap);Painter.initfrom (this);DrawGrid (&painter);drawcurves (&painter);update ();}The function refreshpixmap () plots plot to the picture and updates the display. First we adjust the size of the picture to the same size as the current control, and then fill the entire picture with the background color of the control. This color is the "dark" section of the current toner version, because setbackgroundrole () is called in the plotter constructor. If the background brush is non-solid (solid brush, brush style, only color, no pattern of that simplest),Qpixmap::fill () needs to know the offset of the brush in the control so that the picture snaps to the brush mode. Here the picture corresponds to the entire control, so the offset position is (0,0). Next we create a Qpainter object to draw the picture,Qpainter::initfrom () sets the brush, background, and font required to draw the picture, and this indicates that these settings are consistent with the corresponding settings of the plotter control. We then call DrawGrid (), drawcurves () to draw the mesh and curve. Finally, the update () function arranges the drawing event for the entire control and copies the picture to the control in the Painteevent () function. void Plotter::d rawgrid (qpainter *painter){qrect rect (margin, margin,width ()-2 * margin, height ()-2 * margin);if (!rect.isvalid ())return;plotsettings settings = Zoomstack[curzoom];Qpen Quitedark = Palette (). Dark (). Color (). Light ();Qpen light = palette (). Light (). color ();for (int i = 0; I <= settings.numxticks; ++i) {int x = rect.left () + (I * (Rect.width ()-1)/settings.numxticks);Double label = Settings.minx + (i * Settings.spanx ()/settings.numxticks);Painter->setpen (Quitedark);painter->drawline (x, Rect.top (), X, Rect.bottom ());Painter->setpen (light);painter->drawline (x, Rect.bottom (), X, Rect.bottom () + 5);Painter->drawtext (x-50, Rect.bottom () + 5,Qt::alignhcenter | Qt::aligntop,qstring::number (label));    }For (int j = 0; J <= settings.numyticks; ++j) {int y = Rect.bottom ()-(J * (Rect.height ()-1)/settings.numyticks);Double label = Settings.miny + (J * Settings.spany ()/settings.numyticks);Painter->setpen (Quitedark);Painter->drawline (Rect.left (), Y, Rect.right (), y);Painter->setpen (light);Painter->drawline (Rect.left ()-5, Y, Rect.left (), y);Painter->drawtext (Rect.left ()-Margin, y-10, Margin-5,Qt::alignright | Qt::alignvcenter,qstring::number (label));    }Painter->drawrect (rect.adjusted (0, 0,-1,-1));}the function DrawGrid () draws a grid below the axes and curves. This area is determined by a rectangle, and if the control is too small, no drawing is returned immediately. The first loop draws the vertical line of the grid and the scale along the x axis. The second loop draws the horizontal line of the grid and the scale along the y-axis. Finally, a rectangle is drawn along the boundary. DrawText () Draws a number that corresponds to a tick mark on two axes. The function Painter->drawtext () syntax is as follows:painter->drawtext (x, y, width, height, alignment, text);where (x,y,width,height) determines the rectangle, alignment determines the position of the text in the rectangle. void Plotter::d rawcurves (qpainter *painter){static const Qcolor Colorforids[6] = {qt::red, Qt::green, Qt::blue, Qt::cyan, Qt::magenta, Qt::yellow    };plotsettings settings = Zoomstack[curzoom];qrect rect (margin, margin,width ()-2 * margin, height ()-2 * margin);if (!rect.isvalid ())return;Painter->setcliprect (rect.adjusted (+1, +1,-1,-1));Qmapiterator<int, qvector<qpointf> > I (curvemap);While (I.hasnext ()) {I.next ();int id = i.key ();const Qvector<qpointf> &data = I.value ();qpolygonf polyline (Data.count ());For (int j = 0; J < Data.count (); ++j) {Double dx = data[j].x ()-Settings.minx;double dy = data[j].y ()-Settings.miny;Double x = rect.left () + (DX * (Rect.width ()-1)/Settings.spanx ());Double y = Rect.bottom ()-(DY * (Rect.height ()-1)/Settings.spany ());Polyline[j] = qpointf (x, y);        }Painter->setpen (colorforids[uint (ID)% 6]);Painter->drawpolyline (polyline);    }}the function drawcurves () draws a curve on the upper layer of the grid. The qpainter::setcliprect () function is called to set the clipping area of the qpainter to the rectangular area containing the curve (excluding the surrounding gaps and the picture's bounding box). Qpainter will ignore pixels outside of this area. then we use the Java-style iterator, traversing all the curves, and traversing all of its qpointf points for each curve. The function key () Gets the curve of the Id,value () function to get the data of the qvector<qpointf> type of the curve. The inner loop converts the plotter coordinates of each qpointf record to the control coordinates, saving the results in the polyline variable.

After converting coordinates, we set the color of the brush (using pre-defined colors in front of the function), calling DrawPolyline () to draw the curve, passing through all the points on the curve.

Http://blog.csdn.net/Last_Impression/archive/2008/05/20/2463647.aspx

Double buffered flicker-free drawing in QT components

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.