QT 自定义控件的重绘优化

上一篇文章提到在嵌入式运行时,自定义控件的整体重绘会消耗较多的CPU从而影响系统的实时性,因此考虑将调整控件的结构,把需要重绘的部件放到一块易于指定的区域内,从而达到每次重绘时只更新该区域来节省开销

查看update的定义了解到update本身支持只重绘指定的区域

void QWidget::update(const QRect &rect)
This is an overloaded function.
This version updates a rectangle rect inside the widget.
void QWidget::update(const QRegion &rgn)
This is an overloaded function.
This version repaints a region rgn inside the widget.

因此通过定义一个变量hasInitBackPixmap,初始值为false,在第一次paintEvent时绘制所有内容后置为true,在调用update时传入需要重绘的区域,此时则不再对不需要绘制的背景进行绘制

void gaugeColor::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate(width()/2,height()/2);
    int side=qMin(width(),height());
    painter.scale(side/200.0,side/200.0);
    if(!hasInitBackPixmap)
    {
        drawScale(&painter);
        drawScaleNum(&painter);
        hasInitBackPixmap=true;
    }
    drawNumericValue(&painter);
    drawIndicator(&painter);
}
void gaugeColor::UpdateAngle(double newvalue)
{
    m_value=newvalue;
    int side=qMin(width(),height());
    double k=side/200.0;
    QRegion region(width()/2-64*k,height()/2-64*k,128*k,128*k,QRegion::Ellipse);
    update(region);
}

上述代码的作用是只更新内部指针及数字显示部分所在圆形区域内,不再更新刻度尺等内容

调整后的效果如下图所示

另外,这样设计还有个小问题,是在窗口尺寸变化时,会引起部件的整体重绘,这样,由于hasInitBackPixmap已经为true,导致背景没有重新绘制产生下面的显示效果 

查看paintEvent(QPaintEvent *)的帮助内容了解到QPaintEvent实际有传入重绘的区域:

The QPaintEvent class contains event parameters for paint events.

Paint events are sent to widgets that need to update themselves, for instance when part of a widget is exposed because a covering widget was moved.

The event contains a region() that needs to be updated, and a rect() that is the bounding rectangle of that region. Both are provided because many widgets cannot make much use of region(), and rect() can be much faster than region().boundingRect().

因此在paintEvent中作如下调整即可解决 该问题

void gaugeColor::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate(width()/2,height()/2);
    int side=qMin(width(),height());
    painter.scale(side/200.0,side/200.0);
    if((!hasInitBackPixmap)||(event->rect().x()==0))
    {
        drawScale(&painter);
        drawScaleNum(&painter);
        hasInitBackPixmap=true;
    }
    drawNumericValue(&painter);
    drawIndicator(&painter);
}

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于在Qt自定义控件并进行重绘,您可以按照以下步骤进行操作: 1. 创建自定义控件类:首先,您需要创建一个继承自QWidget或其子类的自定义控件类。您可以使用Qt Designer来设计控件的外观,并生成相应的.ui文件。 2. 重写绘制事件:在自定义控件类中,重写paintEvent()函数来实现控件的绘制操作。在这个函数中,可以使用Qt提供的绘图工具类(如QPainter)来绘制您想要的图形、文本等。 例如,以下是一个简单的自定义控件类,名为MyWidget: ```cpp class MyWidget : public QWidget { public: MyWidget(QWidget *parent = nullptr) : QWidget(parent) {} protected: void paintEvent(QPaintEvent *event) override { QPainter painter(this); painter.fillRect(rect(), Qt::white); // 填充背景为白色 painter.setPen(Qt::blue); painter.drawRect(10, 10, width() - 20, height() - 20); // 绘制蓝色边框矩形 painter.drawText(rect(), Qt::AlignCenter, "Hello, World!"); // 绘制文本居中显示 } }; ``` 3. 使用自定义控件:在需要使用自定义控件的地方,将其实例化,并添加到您的窗口或布局中即可。 ```cpp MyWidget *widget = new MyWidget(this); layout->addWidget(widget); // 假设layout是您的布局对象 ``` 通过以上步骤,您就可以自定义控件重绘它的外观了。当控件需要更新时,Qt会自动触发重绘事件,调用paintEvent()函数来重新绘制控件。 希望对您有所帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值