Paintevent understanding of QT key problem solving


Basic concepts:

The paintEvent(QPaintEvent*) function is a virtual function in the QWidget class. It is used for ui drawing and will be automatically called by other functions in many cases, such as update().

Running time:

A repaint event is used to repaint all or part of a widget. A repaint event occurs for any of the following reasons:

(1) The repaint() function or the update() function is called;

(2) Hidden widgets are now redisplayed;

(3) Some other reasons.

Optimize the drawing event method:

        1. Most components can simply redraw their entire interface, but some components that draw relatively slowly need to be optimized and only draw the required area (you can use QPaintEvent::region() to get the area), this speed The optimization does not affect the results.

        2. Qt also speeds up drawing by combining multiple redraw events into one event. When the update() function is called multiple times, or the window system sends multiple redraw events, then Qt will combine these events into one event , and this event has the largest area that needs to be repainted. The update() function will not redraw immediately, and will not be redrawn until Qt returns to the main event loop, so multiple calls to the update() function generally only cause one paintEvent() function call.

        3. Calling the repaint() function will immediately call the paintEvent() function to repaint the component. The repaint() function is only used when the repaint operation must be performed immediately (such as in animation).

        4. The update() function allows Qt to optimize speed and reduce flickering, but the repaint() function does not support such optimization, so it is recommended to use the update() function as much as possible in general.

        5. Also note that when the program starts to run, it will automatically send a repaint event and call the paintEvent() function. In addition, do not call the update() or repaint() function in the paintEvent() function.

        6. When a repaint event occurs, the area to be updated is generally erased and then drawn on the background of the widget.

How to reimplement paintevent:

       How to draw?

       where to paint?

       What to paint with?

1. QPainter class

       This class mainly provides the function of drawing on forms or other drawing devices.

       Use the following in paintEvent(QPaintEvent*): QPainter painter(this);  

       Commonly used functions in this class are:

       The drawXXX() function is used to draw graphics, text and paths, etc.;

       The fillXXX() function is used for filling, which can be filled in the specified area;

       brush() and pen() operations related to brushes and pens

2. QPainterPath class

        This class provides a container for drawing and is mainly used to describe the drawing path.

        You can pass the function setFillRule(Qt::WindingFill);

        To set the filling rules, add the drawing area through the addRect() function.

 

3. QColor class

This class provides color support, where the color can define four properties: QColor ( int r, int g, int b, int a = 255 ), that is, red, green, blue, and transparency. In addition, these four values ​​can also be set individually, which can be set by functions like setAlpha(), which is very helpful for designing progressive effects.

 

E.g:


  1. void ABC::paintEvent(QPaintEvent *)  
  2. {  
  3.     QPainterPath path;  
  4.     path.setFillRule(Qt::WindingFill);  
  5.     path.addRect(10, 10, this->width()-20, this->height()-20);  
  6.   
  7.     QPainter painter(this);  
  8.     painter.setRenderHint(QPainter::Antialiasing, true);  
  9.     painter.fillPath(path, QBrush(Qt::white));  
  10.   
  11.     QColor color(0, 0, 0, 50);  
  12.     for(int i=0; i<10; i++)  
  13.     {  
  14.         QPainterPath path;  
  15.         path.setFillRule(Qt::WindingFill);  
  16.         path.addRect(10-i, 10-i, this->width()-(10-i)*2, this->height()-(10-i)*2);  
  17.         color.setAlpha(150 - qSqrt(i)*50);  
  18.         painter.setPen(color);  
  19.         painter.drawPath(path);  
  20.     }  


Other related functions:

one. Mainly understand a few methods and properties:

1.QWidget * QScrollView::viewport () const

2. void QWidget::paintEvent ( QPaintEvent * ) [virtual protection]

3.void QWidget::repaint ( int x, int y, int w, int h, bool erase = TRUE ) [槽]

4.void QWidget::update () [槽]

5.void QWidget::erase ( int x, int y, int w, int h )

6.bool updatesEnabled

two. Now introduce in detail:

1.QWidget * QScrollView::viewport () const

Returns the viewport widget in the scroll view that contains the content widget or area to draw.

2. void QWidget::paintEvent ( QPaintEvent * ) [virtual protection]

Called whenever the widget needs to be redrawn.

Every widget that wants to display output must implement it.

This event handler can be reimplemented in subclasses to receive paint events. It can be the result of repaint() or update().

Many widgets simply repaint the entire interface when they are requested, but some widgets optimize by painting only the requested region QPaintEvent::region() , for example, QListView and QCanvas do this.

Qt can also speed up drawing by combining multiple drawing events into one. When update() is called several times or the window system sends several paint events, Qt combines them into one event for a larger region (see QRegion::unite()). repaint() does not allow this optimization, so we try to use update() whenever possible.

When a paint event occurs, the update area is usually erased. With some exceptions, you can tell if the widget has been erased via QPaintEvent::erased().

3.void QWidget::repaint ( int x, int y, int w, int h, bool erase = TRUE ) [槽]

The widget is repainted directly by calling paintEvent() immediately. If erase is true, Qt erases the area (x, y, w, h) before paintEvent() is called. If w is negative, it is replaced by width()-x, and if h is negative, it is replaced by height()-y.

It is recommended to use repaint() if you need to repaint immediately, such as during animations.

In most cases, update() is better because it allows Qt to optimize speed and prevent flickering. Warning: If you call repaint() in a function that is itself called by paintEvent(), you may see an infinite loop. The update() function never generates a loop.

4.void QWidget::update () [槽]

Updating the widget, when Qt returns to the main event, it schedules the paint event to handle. This allows Qt to optimize for faster speed and less flicker than calling repaint(). The result of several calls to update() is usually just one paintEvent() call. Qt normally erases the widget's area before paintEvent() is called, only if the WRepaintNoErase widget flag is set.

5.void QWidget::erase ( int x, int y, int w, int h )

Erases the specified area (x, y, w, h) in the widget without generating paint events.

If w is negative, it is replaced by width()-x. If h is negative, it is replaced by height()-y.

Child widgets are not affected.

6.bool updatesEnabled

This property holds whether the update takes effect.

If the update fails, calling update() and repaint() has no effect.

If the update fails, paint events from the windowing system are handled normally.

setUpdatesEnabled() is typically used to disable updates for a short period of time, such as to avoid screen flickering during large changes.

Example:

    setUpdatesEnabled( FALSE );

    bigVisualChanges();

    setUpdatesEnabled( TRUE );

    repaint();

Set the property value with setUpdatesEnabled() and get the property value with isUpdatesEnabled().

Reprinted from: https://blog.csdn.net/u012151242/article/details/78947024


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324682934&siteId=291194637