码上通QT实战05--绘制导航按钮

1、前言

在Qt中,导航按钮通常用于界面切换或功能引导,可以通过多种方式实现。以下是常见的实现方案:

使用QPushButton和信号槽机制

导航按钮的视觉样式可以通过QSS进行自定义

cpp 复制代码
QPushButton *navButton = new QPushButton("导航");
connect(navButton, &QPushButton::clicked, this, &MainWindow::navigateToPage);

使用QToolButton实现图标导航

导航按钮的视觉样式可以通过QSS进行自定义

cpp 复制代码
QPushButton {
    background-color: #3498db;
    color: white;
    border-radius: 5px;
    padding: 8px 16px;
}

QPushButton:hover {
    background-color: #2980b9;
}

导航按钮组实现

对于需要多个导航按钮的情况,可以使用QButtonGroup:

cpp 复制代码
QButtonGroup *navGroup = new QButtonGroup(this);
navGroup->addButton(homeButton, 0);
navGroup->addButton(settingsButton, 1);
connect(navGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked),
        [](QAbstractButton *button) {
            // 处理导航逻辑
        });

2、马上干

1、创建自定义控件

在Qt中,创建自定义控件是一个非常灵活和强大的方式,可以让你根据具体需求扩展现有的控件或完全从头开始设计控件,自定义控件继承自QWidget或现有控件类(如QPushButton、QLabel等),重写关键方法实现自定义功能。通过重写paintEvent实现视觉效果定制,使用Q_PROPERTY宏定义可在Qt Designer中编辑的属性,为控件添加自定义信号,通过QSS定制外观,需确保控件正确处理样式。

自定义控件的步骤

  1. 继承 QWidget 或其他控件类 : 创建一个新的类,继承自 QWidget 或其他你希望扩展的控件类。

  2. 重写绘制事件 : 在自定义控件类中,重写 paintEvent 方法来定义控件的绘制逻辑。使用 QPainter 类来进行绘制操作。

  3. 处理其他事件 : 根据需要重写其他事件处理函数,如 mousePressEventkeyPressEvent 等,以实现控件的交互逻辑。

  4. 添加属性和槽函数 : 使用 Qt 的属性系统(通过 Q_PROPERTY 宏)为控件添加自定义属性,并通过槽函数来响应外部信号或内部状态变化。

  5. 注册控件 (可选): 如果你希望将自定义控件集成到 Qt Designer 中,可以通过 Q_PLUGIN_METADATA 宏和 QDesignerCustomWidgetInterface 类来注册控件。

2、添加有关的属性,变量,槽函数,事件

cpp 复制代码
#ifndef NAVBUTTON_H
#define NAVBUTTON_H

#include <QPaintEvent>
#include <QWidget>

class NavButton : public QWidget
{
    Q_OBJECT

    Q_PROPERTY(int icon READ icon WRITE setIcon);
    Q_PROPERTY(QString text READ text WRITE setText);
    Q_PROPERTY(bool isChecked READ isChecked WRITE  setIsChecked);

public:
    explicit NavButton(QWidget *parent = nullptr);
    int icon() const{
        return m_icon;
    }

    QString text() const
    {
        return m_text;
    }

    bool isChecked() const
    {
        return m_isChecked;
    }

public slots:
    void setIcon(int icon)
    {
        if(m_icon==icon) return;
        m_icon = icon;
        // 涉及到控件的重绘
        update();
    }

    void setText(QString text)
    {
        m_text = text;
    }

    void setIsChecked(bool isChecked)
    {
        m_isChecked = isChecked;
    }
private:
    bool isMouseOver=false;
    int m_icon;
    QString m_text;
    bool m_isChecked;
protected:
    void paintEvent(QPaintEvent *event) override;//窗体重绘事件

signals:
};

#endif // NAVBUTTON_H

3、绘制有关图形

paintEvent 基本概念

在 Qt 中,paintEventQWidget 及其子类的一个关键虚函数,用于处理控件的绘制逻辑。当控件需要重绘时(如窗口首次显示、尺寸变化、调用 update()repaint()),系统会自动调用此函数。

重写 paintEvent 方法

自定义绘制需要重写 paintEvent,并通过 QPainter 进行绘图操作。以下是一个基本示例:

cpp 复制代码
void MyWidget::paintEvent(QPaintEvent *event) {
    QPainter painter(this); // 创建 QPainter 对象,绑定当前控件
    painter.setPen(Qt::red); // 设置画笔颜色
    painter.drawLine(0, 0, width(), height()); // 绘制对角线
    painter.drawText(rect(), Qt::AlignCenter, "Hello Qt!"); // 绘制文本
}

关键注意事项

  • 避免直接调用 paintEvent :应通过 update()(异步,合并多次调用)或 repaint()(同步,立即重绘)触发重绘。
  • 性能优化 :通过 event->rect() 获取需要重绘的区域,仅绘制该区域以减少计算量。
  • 双缓冲技术 :复杂绘图可使用 QPixmap 作为缓冲,避免闪烁:

常用绘图操作

  • 几何图形drawLinedrawRectdrawEllipsedrawPolygon
  • 文本drawText,配合 QFont 设置字体。
  • 图像drawPixmapdrawImage 显示图片。
  • 路径QPainterPath 绘制复杂路径。

QPainter 基本概念

QPainter 是 Qt 框架中用于二维图形绘制的核心类,支持在多种绘图设备(如 QWidget、QPixmap、QImage)上绘制形状、文本和图像。其功能涵盖路径绘制、坐标变换、混合模式等高级特性。

初始化与基本用法

创建 QPainter 对象需绑定绘图设备。例如,在 QWidget 的 paintEvent 方法中使用:

cpp 复制代码
void MyWidget::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    painter.setPen(Qt::blue);
    painter.drawLine(0, 0, width(), height());
}

常用绘制操作

绘制形状

绘制文本

绘制图像

坐标变换与状态管理

路径绘制(QPainterPath),复杂路径可通过 QPainterPath 定义后绘制

常见问题

绘图不显示

检查是否在 paintEvent 外创建 QPainter,或未调用 end() 方法。

坐标系统问题

默认坐标系原点在左上角,Y轴向下为正方向。可通过 setViewportsetWindow 调整映射范围。

资源释放

QPainter 通常无需手动释放,但绑定 QPixmap 等设备时需确保设备生命周期覆盖绘图过程。

通过结合上述方法,QPainter 可实现从简单图形到复杂界面的高效绘制。

完整代码

cpp 复制代码
#include "navbutton.h"
#include <QPaintEvent>
#include <QPainter>

NavButton::NavButton(QWidget *parent): QWidget{parent}
{


}


//窗体重绘事件

void NavButton::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    //1、绘制按钮的背景
    if(m_isChecked){//如果选中,则设置线性渐变
        //创建渐变对象
        QLinearGradient gradient(0,0,this->rect().width(),this->rect().height());//从哪开始进行渐变,0,0是起点,终点是矩形的宽度和高度
        gradient.setColorAt(0,QColor(62,155,253));//起点颜色
        gradient.setColorAt(1,QColor(33,97,216));//终点颜色
        painter.setBrush(gradient); //设置笔刷
    }
    else{

    }
    painter.drawRoundedRect(this->rect(),10,10);//绘制带有圆角的矩形,10是圆角半径


    //2、绘制图标
    painter.setPen(QColor(255,255,255));//设置笔的颜色
    QFont iconFont=QFont("zx_icons",22);//创建字体对象
    painter.setFont(iconFont);//设置字体
    //参数1表示位置 ,参数2表示对齐方式,参数3表示文字内容
    painter.drawText(QRect(0,10,this->rect().width(),this->rect().height()),
                     Qt::AlignHCenter,
                     QChar(this->icon()));

    //3、绘制标题
    QFont font=QFont("Microsoft YaHei",9);
    painter.setFont(font);
    painter.drawText(QRect(0,10,this->rect().width(),this->rect().height()-22),
                     Qt::AlignHCenter|Qt::AlignBottom,
                     this->text());

    //4、绘制线边框
    if(m_isChecked){
        QPen pen(QColor(255,150,0),3);
        painter.setPen(pen);
        painter.drawLine(2,10,2,this->rect().height()-10);
    }
}

4、转到界面,提升控件

Qt中的提升概念

在Qt框架中,"提升"(Promotion)通常指将某个基础控件转换为自定义控件的过程。这一功能主要用于Qt Designer中,允许开发者将界面中的标准Qt控件替换为自行编写的派生类控件。

提升的主要用途

通过控件提升可以实现界面设计与代码逻辑的分离。标准控件如QWidget、QPushButton等可以在设计时布局,运行时替换为功能更丰富的自定义控件。

提升操作保留了原始控件的所有属性,同时添加了派生类的新功能。这种方式避免了手动修改UI文件,使得可视化设计与代码扩展能够协同工作。

实现提升的步骤

在Qt Designer中选择需要提升的控件,右键点击选择"Promote to..."。在弹出的对话框中填写提升后的类名和头文件路径。确认后该控件即被标记为自定义类型,实际运行时会实例化指定的派生类。

提升后的类必须满足:是原控件类的直接或间接子类;具有相同的构造函数签名;头文件路径在项目编译时可达。

提升与继承的区别

提升是Qt特有的设计时概念,而继承是面向对象的通用特性。提升侧重于可视化设计工具中的控件替换,继承关注代码层面的类关系。通过提升可以快速将设计器中的标准控件转换为自定义类实例。

实际应用示例

例如将QWidget提升为自定义的ChartWidget类:

  1. 在Qt Designer中放置QWidget
  2. 设置提升信息:基类QWidget,提升类名ChartWidget
  3. 指定头文件"chartwidget.h"
  4. 生成的UI文件将自动包含提升信息
  5. 运行时该部件会实例化为ChartWidget对象

这种方法常用于创建复合控件、定制绘制控件或添加特殊行为的界面元素,同时保持设计器的可视化编辑能力。

5、设置新添加的属性

6、运行测试

3、小结

Qt框架提供了多种方式来实现自定义导航功能,可以通过QML或C++结合Qt Widgets来完成。使用Qt Widgets实现自定义导航,对于传统的桌面应用,可以使用QWidget和QHBoxLayout来创建自定义导航栏。为了提升用户体验,可以为导航添加平滑的过渡动画。对于不同屏幕尺寸,可以调整导航栏的布局,这些方法提供了在Qt应用中实现自定义导航的基础,可以根据具体需求进行扩展和组合。

复制代码
原创不易,打字不易,截图不易,撸码不易,整理不易,走过路过,不要错过,欢迎点赞,收藏,转载,复制,抄袭,留言,灌水,请动动你的金手指,祝您早日实现财务自由。
相关推荐
抹香鲸之海4 分钟前
Easyexcel 多级横向合并表头
java·开发语言·windows
环黄金线HHJX.5 分钟前
【MCP: Tuan编程 + Qt架构 + QoS - 量子-经典混合计算管理控制平台】
ide·人工智能·qt·编辑器·量子计算
superman超哥5 分钟前
Rust 生命周期子类型:类型系统中的偏序关系
开发语言·后端·rust·编程语言·rust生命周期·偏序关系
雒珣6 分钟前
qt界面和图片疯狂变大的bug问题
开发语言·qt·bug
BD_Marathon8 分钟前
SpringMVC——bean加载控制
java·开发语言·数据库
課代表9 分钟前
Python 数据可视化:从单变量到多变量
开发语言·python·信息可视化·数据分析·变量·时间序列·文本分析
leiming611 分钟前
c++qt开发第三天 摄像头采集视频
开发语言·c++·qt
海奥华217 分钟前
Golang Channel 原理深度解析
服务器·开发语言·网络·数据结构·算法·golang
代码游侠19 分钟前
学习笔记——MQTT协议
开发语言·笔记·php
幻影星空VR元宇宙24 分钟前
9D裸眼轨道影院投资多少钱与5D动感影院设备的市场潜力分析
css·百慕大冒险·幻影星空