需求
最近有一个需求就是一个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();
}
}