当前位置:   article > 正文

QT自定义标题栏_自定义标题栏 qt

自定义标题栏 qt

QT自定义标题栏

  • 概述
    以QWidget作为基类,派生出自定义标题栏类DlgTitle,DlgTitle类可用于QMainWindow和QDialog窗口。同时使用QSS进行资源加载和简单界面美化。
  • 开发环境
    Qt5.4.2 + VS2013 + QT VS TOOLS
  • 代码
    自定义标题栏类DlgTitle.h如下:
#ifndef DLGTITLE_H
#define DLGTITLE_H

#include <QtWidgets>

enum ButtonType
{
	MINI_BUTTON, //最小化按钮和关闭按钮
	MINI_MAX_BUTTON, //最小化、最大化、还原和关闭按钮
	ONLY_CLOSE_BUTTON //关闭按钮
};

class DlgTitle : public QWidget
{
	Q_OBJECT

public:
	explicit DlgTitle(QWidget* parent = 0);
	~DlgTitle();
	
	void init(); //初始化
	void setButtonType(ButtonType buttontype); //设置按钮类型
	void setDlgIcon(const QString& fileName); //设置标题栏Icon
	void setDlgTitle(const QString& title); //设置标题栏标题

private:
	void setButtonStyle(); //设置按钮样式

	void mousePressEvent(QMouseEvent *event);
	void mouseReleaseEvent(QMouseEvent *event);
	void mouseDoubleClickEvent(QMouseEvent *event);
	void mouseMoveEvent(QMouseEvent *event);
	void paintEvent(QPaintEvent *event);

private slots:
	void miniButtonClicked();
	void restoreButtonClicked();
	void maxButtonClicked();
	void closeButtonClicked();

private:
	QLabel *m_pIconLabel; //表示标题栏Icon
	QLabel *m_pTitleLabel; //表示标题栏标题
	
	QPushButton *m_pMiniButton; //表示最小化按钮
	QPushButton *m_pMaxButton; //表示最大化按钮
	QPushButton *m_pRestoreButton; //表示还原按钮
	QPushButton *m_pCloseButton; //表示关闭按钮

	bool m_isPressed; //鼠标按下flag
	QPoint m_startMovePos; //鼠标移动的初始位置
	ButtonType m_buttonType; //按钮类型
};

#endif //DLGTITLE_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

自定义标题栏类DlgTitle.cpp如下:

#include "DlgTitle.h"

#define BUTTON_WIDTH  42 //按钮宽度
#define BUTTON_HEIGHT 32 //按钮高度
#define TITLE_HEIGHT  40 //标题栏高度

DlgTitle::DlgTitle(QWidget* parent)
: QWidget(parent)
, m_isPressed(false)
{
	init();
}

DlgTitle::~DlgTitle()
{

}

void DlgTitle::init()
{
	m_pIconLabel = new QLabel;
	m_pTitleLabel = new QLabel;
	m_pTitleLabel->setContentsMargins(5, 0, 0, 0); 
	m_pTitleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); //标题宽度可扩展

	m_pMiniButton = new QPushButton;
	m_pMaxButton = new QPushButton;
	m_pRestoreButton = new QPushButton;
	m_pCloseButton = new QPushButton;

	//按钮大小固定
	m_pMiniButton->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
	m_pMaxButton->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
	m_pRestoreButton->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
	m_pCloseButton->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
	
	setButtonStyle();

	//对Icon、标题和按钮使用水平布局
	QHBoxLayout *pHLayout = new QHBoxLayout;
	pHLayout->addWidget(m_pIconLabel);
	pHLayout->addWidget(m_pTitleLabel);
	pHLayout->addWidget(m_pMiniButton);
	pHLayout->addWidget(m_pMaxButton);
	pHLayout->addWidget(m_pRestoreButton);
	pHLayout->addWidget(m_pCloseButton);

	pHLayout->setContentsMargins(5, 1, 1, 6); //TITLE_HEIGHT-BUTTON_HEIGHT-1为6
	pHLayout->setSpacing(0);
	this->setLayout(pHLayout);
	this->setFixedHeight(TITLE_HEIGHT); //标题栏高度固定
	
	//按钮的信号槽连接
	connect(m_pMiniButton, SIGNAL(clicked()), this, SLOT(miniButtonClicked()));
	connect(m_pMaxButton, SIGNAL(clicked()), this, SLOT(maxButtonClicked()));
	connect(m_pRestoreButton, SIGNAL(clicked()), this, SLOT(restoreButtonClicked()));
	connect(m_pCloseButton, SIGNAL(clicked()), this, SLOT(closeButtonClicked()));
}

void DlgTitle::setButtonType(ButtonType buttontype)
{
	m_buttonType = buttontype;
	switch (buttontype)
	{
	case MINI_BUTTON:
		m_pMaxButton->setVisible(false);
		m_pRestoreButton->setVisible(false);
		break;
	case MINI_MAX_BUTTON:
		m_pRestoreButton->setVisible(false);
		break;
	case ONLY_CLOSE_BUTTON:
		m_pMiniButton->setVisible(false);
		m_pMaxButton->setVisible(false);
		m_pRestoreButton->setVisible(false);
		break;
	default:
		break;
	}
}

//使用QSS设置按钮样式,鼠标样式仿照VS2013的最小化、最大化、还原和关闭按钮
void DlgTitle::setButtonStyle()
{
	m_pMiniButton->setStyleSheet("QPushButton{border: transparent; border-radius: none; background-color:none;}"
		"QPushButton{border-image:url(./Resources/Minimize.png) 0 84 0 0;}"
		"QPushButton:hover{border-image:url(./Resources/Minimize.png) 0 42 0 42;}"
		"QPushButton:pressed{border-image:url(./Resources/Minimize.png) 0 0 0 84;}");
	m_pMaxButton->setStyleSheet("QPushButton{border: transparent; border-radius: none; background-color:none;}"
		"QPushButton{border-image:url(./Resources/Maximize.png) 0 84 0 0;}"
		"QPushButton:hover{border-image:url(./Resources/Maximize.png) 0 42 0 42;}"
		"QPushButton:pressed{border-image:url(./Resources/Maximize.png) 0 0 0 84;}");
	m_pRestoreButton->setStyleSheet("QPushButton{border: transparent; border-radius: none; background-color:none;}"
		"QPushButton{border-image:url(./Resources/Restore.png) 0 84 0 0;}"
		"QPushButton:hover{border-image:url(./Resources/Restore.png) 0 42 0 42;}"
		"QPushButton:pressed{border-image:url(./Resources/Restore.png) 0 0 0 84;}");
	m_pCloseButton->setStyleSheet("QPushButton{border: transparent; border-radius: none; background-color:none;}"
		"QPushButton{border-image:url(./Resources/Close.png) 0 84 0 0;}"
		"QPushButton:hover{border-image:url(./Resources/Close.png) 0 42 0 42;}"
		"QPushButton:pressed{border-image:url(./Resources/Close.png) 0 0 0 84;}");
}

void DlgTitle::setDlgIcon(const QString& fileName)
{
	QPixmap pixmap(fileName);
	m_pIconLabel->setPixmap(pixmap.scaled(24, 24));
}

void DlgTitle::setDlgTitle(const QString& title)
{
	m_pTitleLabel->setText(title);
	m_pTitleLabel->setStyleSheet("QLabel{color: black; background-color: none; font-size: 10pt; font-family: Microsoft YaHei;}");
}

void DlgTitle::mousePressEvent(QMouseEvent *event)
{
	if (MINI_MAX_BUTTON == m_buttonType)
	{
		if (m_pMaxButton->isVisible())  //窗口处于非最大化状态时
		{
			m_isPressed = true;
			m_startMovePos = event->globalPos();
		}
	}
	else
	{
		m_isPressed = true;
		m_startMovePos = event->globalPos();
	}

	return QWidget::mousePressEvent(event);
}

void DlgTitle::mouseReleaseEvent(QMouseEvent *event)
{
	m_isPressed = false;

	return QWidget::mouseReleaseEvent(event);
}

void DlgTitle::mouseDoubleClickEvent(QMouseEvent *event)
{
	if (MINI_MAX_BUTTON == m_buttonType)
	{
		if (m_pMaxButton->isVisible())
		{
			maxButtonClicked();
		}
		else
		{
			restoreButtonClicked();
		}
	}

	return QWidget::mouseDoubleClickEvent(event);
}

void DlgTitle::mouseMoveEvent(QMouseEvent *event)
{
	if (m_isPressed)
	{
		QPoint moveOffset = event->globalPos() - m_startMovePos;
		QPoint widgetPos = this->parentWidget()->pos();
		m_startMovePos = event->globalPos();
		this->parentWidget()->move(widgetPos.x() + moveOffset.x(), widgetPos.y() + moveOffset.y());
	}
}

void DlgTitle::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);
	QPainterPath pathBack;
	pathBack.setFillRule(Qt::WindingFill);
	pathBack.addRoundedRect(QRect(0, 0, this->width(), this->height()), 0, 0);
	painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
	painter.fillPath(pathBack, QBrush(QColor(255, 255, 255, 0)));

	if (this->width() != this->parentWidget()->width())
	{
		this->setFixedWidth(this->parentWidget()->width());
	}

	update();

	return QWidget::paintEvent(event);
}

void DlgTitle::miniButtonClicked()
{
	window()->showMinimized();
}

void DlgTitle::restoreButtonClicked()
{
	window()->showNormal();
	m_pRestoreButton->setVisible(false);
	m_pMaxButton->setVisible(true);
}

void DlgTitle::maxButtonClicked()
{
	window()->showMaximized();
	m_pMaxButton->setVisible(false);
	m_pRestoreButton->setVisible(true);
}

void DlgTitle::closeButtonClicked()
{
	window()->close();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210

主窗口使用自定义标题栏类DlgTitle如下:

#include "CustomTitle.h"
#include "DlgTitle.h"

CustomTitle::CustomTitle(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	init();
}

void CustomTitle::init()
{
	setWindowIcon(QIcon("./Resources/logo.png"));
	setWindowFlags(Qt::CustomizeWindowHint | Qt::Window | Qt::FramelessWindowHint);
	
	//实际使用时,需要在.ui文件中给DlgTitle留出TITLE_HEIGHT高度的位置
	DlgTitle *pTitle = new DlgTitle(this);
	pTitle->setDlgIcon("./Resources/logo.png");
	pTitle->setButtonType(MINI_MAX_BUTTON);
	pTitle->setDlgTitle("MainWindow");

	//仿照VS2013,在QSS中使用border-image就可以设置主窗口背景及边界图像
	setStyleSheet("QMainWindow{border: 40 2 2px; border-image: url(./Resources/DlgBkgnd.png);}");
	//需要注意的是DlgBkgnd.png属于标题栏位置的图像高度为TITLE_HEIGHT
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 效果
  • 资源文件
    png格式
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    稍加整理方便大家参考,如有错误请指正,谢谢!
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/234973
推荐阅读
相关标签
  

闽ICP备14008679号