赞
踩
#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
自定义标题栏类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(); }
主窗口使用自定义标题栏类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 }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。