本博文源于笔者在学习C++ qt制作的标题栏组件,主要包含了,最小化,最大化,关闭。读者在看到这篇博文的时候,可以直接查看如何使用的,会使用了,然后进行复制粘贴源码部分即可。
问题来源
想要制作一个qt标题栏组件
源码
一个.h文件
#ifndef CTITLEBAR_H
#define CTITLEBAR_H
#include<QWidget>
#include<QPushButton>
#include<QLabel>
#include<QHBoxLayout>
class CTitleBar :public QWidget {
Q_OBJECT;
public:
CTitleBar(QWidget *parent,QString title,bool showMinimizeButton = true,bool showMaximizeButton = true);
void setTitle(const QString& title);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
signals:
void minimizeClicked();
void maximizeClicked();
void closeClicked();
private:
QLabel* m_titleLabel;
QPoint dragPosition;
bool dragging;
private slots:
void onMinimizeClicked();
void onMaximizeClicked();
void onCloseClicked();
};
#endif
#include "CTitleBar.h"
#include<QHBoxLayout>
#include<QApplication>
#include <QMouseEvent>
CTitleBar::CTitleBar(QWidget *parent, QString title,bool showMinimizeButton, bool showMaximizeButton) :QWidget(parent) {
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setContentsMargins(1, 0, 0, 0);
layout->setSpacing(0);
QString strSkinDir = QApplication::applicationDirPath() + "/skin/images/"; //添加资源图片
QLabel* iconLabel = new QLabel(this);
iconLabel->setPixmap(QIcon(strSkinDir + "/logo.png").pixmap(60, 60)); // 设置图标大小
iconLabel->setFixedSize(20, 30);
// 标题标签
m_titleLabel = new QLabel(title, this);
m_titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_titleLabel->setContentsMargins(0, 0, 0, 0);
layout->addWidget(iconLabel);
layout->addWidget(m_titleLabel);
QPushButton* minimizeButton = nullptr;
QPushButton* maximizeButton = nullptr;
if (showMinimizeButton) {
minimizeButton = new QPushButton(this);
minimizeButton->setIcon(QIcon(strSkinDir + "/min.png"));
minimizeButton->setObjectName("minButton");
minimizeButton->setStyleSheet("QPushButton:hover{background-color:rgb(184,184,184)}");
connect(minimizeButton, &QPushButton::clicked, this, &CTitleBar::onMinimizeClicked);
layout->addWidget(minimizeButton);
}
if (showMaximizeButton) {
maximizeButton = new QPushButton(this);
maximizeButton->setIcon(QIcon(strSkinDir + "/max.png"));
maximizeButton->setObjectName("maxButton");
maximizeButton->setStyleSheet("QPushButton:hover{background-color:rgb(184,184,184)}");
connect(maximizeButton, &QPushButton::clicked, this, &CTitleBar::onMaximizeClicked);
layout->addWidget(maximizeButton);
}
QPushButton* closeButton = new QPushButton( this);
closeButton->setIcon(QIcon(strSkinDir + "/close.png"));
closeButton->setObjectName("closeButton");
closeButton->setStyleSheet("QPushButton:hover{background-color:rgb(232,17,35)}");
connect(closeButton, &QPushButton::clicked, this, &CTitleBar::onCloseClicked);
layout->addWidget(closeButton);
this->setLayout(layout);
this->setFixedHeight(30); // 设置标题栏高度
}
void CTitleBar::setTitle(const QString& title) {
m_titleLabel->setText(title);
}
void CTitleBar::mousePressEvent(QMouseEvent * event)
{
if (event->button() == Qt::LeftButton) {
dragging = true;
dragPosition = event->pos();
event->accept();
}
}
void CTitleBar::mouseMoveEvent(QMouseEvent * event)
{
if (dragging && (event->buttons() & Qt::LeftButton)) {
parentWidget()->move(event->globalPos() - mapToParent(dragPosition));
event->accept();
}
}
void CTitleBar::mouseReleaseEvent(QMouseEvent * event)
{
dragging = false;
}
void CTitleBar::onMinimizeClicked() {
emit minimizeClicked();
}
void CTitleBar::onMaximizeClicked() {
emit maximizeClicked();
}
void CTitleBar::onCloseClicked() {
emit closeClicked();
}
如何使用
创建一个垂直栏,将标题栏包起来就行。
#ifndef CDIALOG_H
#define CDIALOG_H
#include <QDialog>
#include "CTitleBar.h"
class CDialog : public QDialog {
Q_OBJECT
public:
explicit CDialog(QString title, QWidget *parent = nullptr,bool showmin = false,bool showmax = false, int width = 400, int height = 400);
virtual ~CDialog();
void setSubDialog(QLayout* subLayout);
protected:
void initUI(QString title,int width,int height,bool showmin,bool showmax);
private:
CTitleBar* m_titleBar;
QVBoxLayout* m_layout;
QLayout* m_subLayout;
};
#endif // CDIALOG_H
#include "CDialog.h"
#include <QVBoxLayout>
CDialog::CDialog(QString title, QWidget *parent ,bool showmin, bool showmax, int width, int height) : QDialog(parent), m_subLayout(nullptr) {
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
initUI(title,width,height,showmin,showmax);
}
CDialog::~CDialog() {
}
void CDialog::initUI(QString title,int width,int height, bool showmin, bool showmax) {
m_titleBar = new CTitleBar(this,title, showmin, showmax);
connect(m_titleBar, &CTitleBar::closeClicked, this, &CDialog::close);
m_layout = new QVBoxLayout(this);
m_layout->addWidget(m_titleBar,0,Qt::AlignTop);
m_layout->setContentsMargins(0, 0, 0, 0);
m_layout->setSpacing(0);
if (m_subLayout) {
m_layout->addLayout(m_subLayout);
}
setLayout(m_layout);
this->resize(width,height);
setStyleSheet("QDialog{background-color:white}");
m_titleBar->setStyleSheet("background-color:rgb(240,240,240)");
}
void CDialog::setSubDialog(QLayout* subLayout) {
if (subLayout != nullptr && m_layout != nullptr) {
m_subLayout = subLayout;
m_layout->addLayout(m_subLayout);
}
}
当你继承了这个CDialog的时候,就会直接出现一个标题栏和一个窗体了。