前面已经讲解了QPainter绘图的基本使用,当需要一些简单的绘制时,比如绘制温度曲线,可以直接使用QPainter
但是,如果需要更加复杂的曲线绘制,或柱状图等的绘制时,可以使用如下两个:

  • QChart
  • QCustomPlot

关于这两个的详细使用,我已录制完成了相应的视频教程
本节使用 Qt 中的QPainter,实现绘制高低温曲线,效果如下:

效果1 效果2

本节包含以下技术点:事件过滤器、画笔颜色和样式、虚线和实线、绘制文本、平滑曲线
接下来开始,从新建工程开始讲解

1. 新建项目

新建一个名为TempCurve的工程,如下:
image-20260813112103791

2. 界面布局

在UI设计师界面,拖拽两个标签并完成布局,如下:

  • 合理地使用了水平、垂直、栅格布局
  • 合理地调整Layout的各种参数,将外边距、内边距都设置为0
  • 在设计阶段,设置了两个标签的背景色:”background-color: rgb(30, 50, 100);”
  • 修改控件名,做到 “见名知意”

布局完成效果如下:
image-20260813112120272

3. 安装事件过滤器

首先,在widget.cpp的构造中,为标签安装事件过滤器,如下:

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 安装事件过滤器
    // 表示由当前窗口 Widget 来负责接收并处理 lblHigh 和 lblLow 上发生的所有事件。
    // 也就是在当前 Widget 的 eventFilter() 函数中处理
    ui->lblHigh->installEventFilter(this);
    ui->lblLow->installEventFilter(this);
}

然后,在widget.h中声明相关函数,如下:

class Widget : public QWidget {
protected:
    bool eventFilter(QObject* watched, QEvent* event);

private:
    void drawTempLine(bool high);  // 绘制温度曲线
    void updateTempValues();       // 更新温度值

private:
    QVector<int> highValues = {24, 20, 26, 26, 21, 24, 24};
    QVector<int> lowValues = {0, 3, -2, 1, -1, 4, 2};
};

最后,在widget.cpp中实现相关函数,如下:

bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if (event->type() == QEvent::Paint) {
        // 当窗口最大化、最小化、缩放窗口时,当手动调用update时,会触发该绘制事件
        qDebug() << "QEvent::Paint";
        drawTempLine(watched == ui->lblHigh);
    } else if (event->type() == QEvent::MouseButtonDblClick) {
        // 当鼠标在高低温标签上双击时,会触发该事件
        qDebug() << "QEvent::MouseButtonDblClick";
        updateTempValues();
    }

    // 其他情况务必调用基类实现
    return QWidget::eventFilter(watched, event);
}

void Widget::drawTempLine(bool high)
{
    qDebug() << "drawTempLine(bool high): " << high;
}

void Widget::updateTempValues()
{
    qDebug() << "updateTempValues()";
}