[QT]自定义的QtabWidget

需求

最近有一个需求就是一个QTabWidget要求有四个tab页在左侧用于显示主页面,在右侧有一个关于按钮,点击后用于弹出窗口显示一些程序相关信息。主要是怎么实现右侧按钮

相关代码

cpp 复制代码
#ifndef MYTABWIDGET_H
#define MYTABWIDGET_H

#include <QWidget>
#include <QTabWidget>
#include <QPaintEvent>
#include <QStyleOptionButton>
#include <QPushButton>
#include <QRect>
#include <QPainter>
#include <QStyle>
#include <QMouseEvent>

class MyTabWidget : public QTabWidget
{
    Q_OBJECT
public:
    explicit MyTabWidget(QWidget *parent = nullptr);
    ~MyTabWidget();
signals:
    void clickHelp();
protected:
    //重绘
    void paintEvent(QPaintEvent *event);
    //hover状态控制
    void mouseMoveEvent(QMouseEvent *event);
    //hover状态控制
    void leaveEvent(QEvent *event);
    //点击状态控制
    void mousePressEvent(QMouseEvent *event);
    //点击状态控制
    void mouseReleaseEvent(QMouseEvent *event);
private:
    QPushButton *m_pushButton = nullptr;//用于辅助绘制按钮将会使用此按钮的样式表
    QStyleOptionButton m_optionButton;//绘制按钮用于控制按钮状态按钮位置等
    bool m_isPressed = false;//按下标志位
    bool m_isReleased = false;//松开标志位
};

#endif // MYTABWIDGET_H
cpp 复制代码
#include "MyTabWidget.h"
#include <QDebug>

MyTabWidget::MyTabWidget(QWidget *parent) : QTabWidget(parent)
{
    setAttribute(Qt::WA_StyledBackground);
    setMouseTracking(true);
    //不要给按钮指定父亲,指定父亲后此按钮会默认显示在父对象上。在析构函数中将它给delete掉,防止内存泄漏
    m_pushButton = new QPushButton;
    m_optionButton.text = QStringLiteral("帮助");
    m_optionButton.state |= QStyle::State_Enabled;
    //使用样式表来控制按钮的外观更加方便
    m_pushButton->setStyleSheet("QPushButton{border:1px solid #adadad;background-color:#e1e1e1} QPushButton:hover{border:1px solid #0078d7;background-color:#e5f1fb}"
                                "QPushButton::pressed{border:1px solid #00559b; background-color:#cde4f7}");
}

MyTabWidget::~MyTabWidget()
{
    delete m_pushButton;
    m_pushButton = nullptr;
}

void MyTabWidget::paintEvent(QPaintEvent *event)
{
    QTabWidget::paintEvent(event);
    QPainter painter(this);
    m_optionButton.rect = QRect(event->rect().topRight().x() - 41, event->rect().topRight().y() + 2, 40, 17);
    //m_pushButton->style()使用按钮的style()接口来绘制是非常重要的
    m_pushButton->style()->drawControl(QStyle::CE_PushButton, &m_optionButton, &painter, m_pushButton);
}

void MyTabWidget::mouseMoveEvent(QMouseEvent *event)
{
    QTabWidget::mouseMoveEvent(event);
    QRect rect = QRect(this->rect().topRight().x() - 41, this->rect().topRight().y() + 2, 40, 17);
    if(rect.contains(event->pos())){
        m_optionButton.state |= QStyle::State_MouseOver;
        this->repaint();
    }else{
        m_optionButton.state &= ~QStyle::State_MouseOver;
        this->repaint();
    }
}

void MyTabWidget::leaveEvent(QEvent *event)
{
    QTabWidget::leaveEvent(event);
    m_optionButton.state &= ~QStyle::State_MouseOver;
    this->repaint();
}

void MyTabWidget::mousePressEvent(QMouseEvent *event)
{
    QTabWidget::mousePressEvent(event);
    QRect rect = QRect(this->rect().topRight().x() - 41, this->rect().topRight().y() + 2, 40, 17);
    if(rect.contains(event->pos())){
        //QStyle::State_Sunken 也就是按钮按下的状态
        m_optionButton.state |= QStyle::State_Sunken;
        this->repaint();
        m_isPressed = true;
    }
}

void MyTabWidget::mouseReleaseEvent(QMouseEvent *event)
{
    QTabWidget::mouseReleaseEvent(event);
    QRect rect = QRect(this->rect().topRight().x() - 41, this->rect().topRight().y() + 2, 40, 17);
    if(rect.contains(event->pos()) && m_isPressed){
        m_isReleased = true;
        emit clickHelp();
        m_isPressed = false;
        m_isReleased = false;
        m_optionButton.state &= ~QStyle::State_Sunken;
        this->repaint();
    }else{
        m_isPressed = false;
        m_optionButton.state &= ~QStyle::State_Sunken;
        this->repaint();
    }
}

效果展示

相关推荐
mahuifa9 分钟前
ubuntu18.04编译qt5.14.2源码
开发语言·数据库·qt
半青年2 小时前
Qt图表库推荐指南与分析
c语言·开发语言·javascript·c++·qt·信息可视化
艾米莉亚糖2 小时前
解决qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed
开发语言·qt·ssl
孙鹏宇.2 小时前
Qt与Hid设备通信
qt
※※冰馨※※3 小时前
彻底解决QT5 中文编译不过问题
c++·windows·qt
achene_ql3 小时前
基于QT和FFmpeg实现自己的视频播放器FFMediaPlayer(一)——项目总览
开发语言·qt·ffmpeg
TNTLWT3 小时前
Qt功能区:Ribbon使用
开发语言·qt·ribbon
范纹杉想快点毕业4 小时前
以项目的方式学QT开发C++(二)——超详细讲解(120000多字详细讲解,涵盖qt大量知识)逐步更新!
c语言·开发语言·c++·windows·vscode·qt·visual studio
「QT(C++)开发工程师」5 小时前
Visual Studio已更新为17.14+集成deepseek实现高效编程
ide·qt·visual studio
mahuifa6 小时前
Qt图表绘制(QtCharts)- 性能优化(13)
python·qt·pyside6·开发经验·qtchart