Qt之实现自定义控件的两种方式——提升法


前言

  可以通过Qt设计师拖拽原生控件进行界面开发,但有时候原生控件不能满足项目需求。此时,就需要实现自定义控件。
  Qt中实现自定义控件,有两种方式,即提升法和插件法。本篇介绍提升法。

一、需求

  自定义实现一个电池电量显示控件,可以通过设置参数的方式修改电池电量值。电量值等级不同,颜色不同。
  低电量时,效果如下:
在这里插入图片描述
  电量较高或满电时,效果如下:
在这里插入图片描述

二、实现

1、新建项目

新建项目,项目名称为myBattery,在widget.ui中拖拽一个Widget控件和QSlider控件,如下:
在这里插入图片描述

2、自定义控件类

新建一个自定义控件类,类名为MyBattery,继承于QWidget类,该类主要负责实现自定义控件。
核心代码如下:

void MyBattery::paintEvent(QPaintEvent *)
{
    //绘制准备工作,启用反锯齿
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    //绘制边框
    drawBorder(&painter);
    //绘制背景
    drawBg(&painter);
    //绘制头部
    drawHead(&painter);
}

void MyBattery::drawBorder(QPainter *painter)
{
    painter->save();

    double headWidth = width() / 15;
    double batteryWidth = width() - headWidth;

    //绘制电池边框
    QPointF topLeft(borderWidth, borderWidth);
    QPointF bottomRight(batteryWidth, height() - borderWidth);
    batteryRect = QRectF(topLeft, bottomRight);

    painter->setPen(QPen(borderColorStart, borderWidth));
    painter->setBrush(Qt::NoBrush);
    painter->drawRoundedRect(batteryRect, borderRadius, borderRadius);

    painter->restore();
}

void MyBattery::drawBg(QPainter *painter)
{
    if (value == minValue) {
        return;
    }

    painter->save();

    QLinearGradient batteryGradient(QPointF(0, 0), QPointF(0, height()));
    if (currentValue <= alarmValue) {
        batteryGradient.setColorAt(0.0, alarmColorStart);
        batteryGradient.setColorAt(1.0, alarmColorEnd);
    } else {
        batteryGradient.setColorAt(0.0, normalColorStart);
        batteryGradient.setColorAt(1.0, normalColorEnd);
    }

    int margin = qMin(width(), height()) / 20;
    double unit = (batteryRect.width() - (margin * 2)) / 100;
    double width = currentValue * unit;
    QPointF topLeft(batteryRect.topLeft().x() + margin, batteryRect.topLeft().y() + margin);
    QPointF bottomRight(width + margin + borderWidth, batteryRect.bottomRight().y() - margin);
    QRectF rect(topLeft, bottomRight);

    painter->setPen(Qt::NoPen);
    painter->setBrush(batteryGradient);
    painter->drawRoundedRect(rect, bgRadius, bgRadius);

    painter->restore();
}

void MyBattery::drawHead(QPainter *painter)
{
    painter->save();

    QPointF headRectTopLeft(batteryRect.topRight().x(), height() / 3);
    QPointF headRectBottomRight(width(), height() - height() / 3);
    QRectF headRect(headRectTopLeft, headRectBottomRight);

    QLinearGradient headRectGradient(headRect.topLeft(), headRect.bottomLeft());
    headRectGradient.setColorAt(0.0, borderColorStart);
    headRectGradient.setColorAt(1.0, borderColorEnd);

    painter->setPen(Qt::NoPen);
    painter->setBrush(headRectGradient);
    painter->drawRoundedRect(headRect, headRadius, headRadius);

    painter->restore();
}

3、提升

在设计师中,选中原生widget控件,右键,选择菜单中的“提升为”选项,弹出“提升的窗口部件”对话框,选择基类名称,此处为QWidget,填写提升的类名称,此处为MyBattery,头文件名称会同步。如下:
在这里插入图片描述
在这里插入图片描述
依次点击“添加”和“提升”按钮后,可以看到widget控件的类型由QWidget提升为MyBattery类型。
在这里插入图片描述

4、效果

编译运行后,效果如下:
在这里插入图片描述

  • 9
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
下面是一个简单的 Qt 自定义控件的例子,实现了一个带有渐变背景色和圆角边框的按钮: ```cpp #include <QPainter> #include <QMouseEvent> #include <QColor> class CustomButton : public QWidget { Q_OBJECT public: CustomButton(QWidget *parent = nullptr) : QWidget(parent) { setFixedSize(100, 30); setMouseTracking(true); } void setText(const QString &text) { m_text = text; update(); } QString text() const { return m_text; } protected: void paintEvent(QPaintEvent *event) override { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); // 绘制背景色 QLinearGradient gradient(0, 0, 0, height()); gradient.setColorAt(0, QColor(100, 100, 100)); gradient.setColorAt(1, QColor(150, 150, 150)); painter.setBrush(gradient); painter.drawRoundedRect(rect(), 5, 5); // 绘制文字 painter.setPen(QColor(255, 255, 255)); painter.drawText(rect().center() - QRectF(0, 0, 0, 14).center(), m_text); } void enterEvent(QEvent *event) override { // 鼠标进入控件时改变背景色 m_oldBrush = palette().brush(backgroundRole()); QLinearGradient gradient(0, 0, 0, height()); gradient.setColorAt(0, QColor(150, 150, 150)); gradient.setColorAt(1, QColor(200, 200, 200)); QBrush brush(gradient); palette().setBrush(backgroundRole(), brush); update(); } void leaveEvent(QEvent *event) override { // 鼠标离开控件时恢复背景色 palette().setBrush(backgroundRole(), m_oldBrush); update(); } void mousePressEvent(QMouseEvent *event) override { // 发射 clicked 信号 emit clicked(); } signals: void clicked(); private: QString m_text; QBrush m_oldBrush; }; ``` 在上面的代码中,我们继承了 QWidget 类,实现了自己的 paintEvent()、enterEvent()、leaveEvent() 和 mousePressEvent() 函数,分别用于绘制控件、改变背景色、恢复背景色和响应鼠标点击事件。我们还定义了一个 clicked 信号,用于通知外部程序按钮被点击了。 这个自定义控件是一个简单的按钮,但是可以通过修改代码和样式表来实现更多的功能和效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码的雪糕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值