博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt 自定义标题栏
阅读量:5123 次
发布时间:2019-06-13

本文共 8684 字,大约阅读时间需要 28 分钟。

1 头文件

#ifndef TITLEBAR_H#define TITLEBAR_H#include 
#include
#include "ui_TitleBar.h"class TitleBar : public QWidget{ Q_OBJECTpublic: explicit TitleBar(QWidget *parent = nullptr); ~TitleBar(); void setMiniBtnIcon(const QIcon& icon); void setMaxiBtnIcon(const QIcon& icon); void setCloseBtnIcon(const QIcon& icon);protected: //鼠标双击事件 virtual void mouseDoubleClickEvent(QMouseEvent *event); //鼠标按下事件 virtual void mousePressEvent(QMouseEvent *event); //鼠标释放事件 virtual void mouseReleaseEvent(QMouseEvent *event); //鼠标移动事件 virtual void mouseMoveEvent(QMouseEvent *event); //设置界面标题与图标 virtual bool eventFilter(QObject *obj, QEvent *event);private slots: //进行最小化、最大化/还原、关闭操作 void onClicked();private: //最大化/还原 void updateMaximize();private: Ui::TitleBar ui; QPoint pos; //鼠标当前点击坐标 bool mouse_press; //鼠标按下 };#endif // TitleBar_H

2 cpp文件

#include 
#include
#include
#include
#include
#include
#include "TitleBar.h"//调用WIN API#ifdef Q_OS_WIN#include
#endifTitleBar::TitleBar(QWidget *parent) : QWidget(parent) { ui.setupUi(this); mouse_press = false; //setFixedHeight(30); // 设置窗口背景透明; //setAttribute(Qt::WA_TranslucentBackground); //给按钮设置静态tooltip,当鼠标移上去时显示tooltip ui.btnMinimize->setToolTip(tr("Minimize")); ui.btnMaximize->setToolTip(tr("Maximize")); ui.btnClose->setToolTip(tr("Close")); QPalette pal(palette()); pal.setColor(QPalette::Background, QColor(150, 150, 150)); setAutoFillBackground(true); setPalette(pal); connect(ui.btnMinimize, SIGNAL(clicked(bool)), this, SLOT(onClicked())); connect(ui.btnMaximize, SIGNAL(clicked(bool)), this, SLOT(onClicked())); connect(ui.btnClose, SIGNAL(clicked(bool)), this, SLOT(onClicked())); //隐藏更换皮肤按钮 ui.btnSkin->setVisible(false); setAttribute(Qt::WA_StyledBackground);}TitleBar::~TitleBar() {}//双击标题栏进行界面的最大化/还原void TitleBar::mouseDoubleClickEvent(QMouseEvent *event) { Q_UNUSED(event); emit ui.btnMaximize->clicked();}void TitleBar::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { mouse_press = true; pos = event->globalPos(); } event->ignore();}void TitleBar::mouseMoveEvent(QMouseEvent *event) { //若鼠标左键被按下 if (mouse_press) { QPoint move_pos = event->globalPos()-pos; //鼠标现在位置-原来位置 //移动主窗体 window()->move(window()->pos() + move_pos);//窗口位置+鼠标移动距离 pos = event->globalPos(); //更新位置 } event->ignore();}void TitleBar::mouseReleaseEvent(QMouseEvent *event) { //设置鼠标为未被按下 mouse_press = false; event->ignore();}//使用事件过滤器监听标题栏所在的窗体,所以当窗体标题、图标等信息发生改变时,标题栏也应该随之改变bool TitleBar::eventFilter(QObject *obj, QEvent *event) { switch (event->type()) { //判断发生事件的类型 case QEvent::WindowTitleChange: { //窗口标题改变事件 QWidget *pWidget = qobject_cast
(obj); //获得发生事件的窗口对象 if (pWidget) { //窗体标题改变,则标题栏标题也随之改变 ui.labelTitle->setText(pWidget->windowTitle()); return true; } } break; case QEvent::WindowIconChange: { //窗口图标改变事件 QWidget *pWidget = qobject_cast
(obj); if (pWidget) { //窗体图标改变,则标题栏图标也随之改变 QIcon icon = pWidget->windowIcon();// ui.labelIcon->setPixmap(icon.pixmap(ui.labelIcon->size())); return true; } } break; case QEvent::Resize: updateMaximize(); //最大化/还原 return true; default: return QWidget::eventFilter(obj, event); } return QWidget::eventFilter(obj, event);}//进行最小化、最大化/还原、关闭操作void TitleBar::onClicked() { QPushButton *pButton = qobject_cast
(sender()); QWidget *pWindow = this->window(); //获得标题栏所在的窗口 if (pWindow->isTopLevel()) { if (pButton == ui.btnMinimize) { pWindow->showMinimized(); //窗口最小化显示 } else if (pButton == ui.btnMaximize) { pWindow->isMaximized() ? pWindow->showNormal() : pWindow->showMaximized(); //窗口最大化/还原显示 } else if (pButton == ui.btnClose) { pWindow->close(); //窗口关闭 } }}//最大化/还原void TitleBar::updateMaximize() { QWidget *pWindow = this->window(); //获得标题栏所在的窗口 if (pWindow->isTopLevel()) { bool bMaximize = pWindow->isMaximized(); //判断窗口是不是最大化状态,是则返回true,否则返回false if (bMaximize) { //目前窗口是最大化状态,则最大化/还原的toolTip设置为"Restore" ui.btnMaximize->setToolTip(tr("Restore")); //设置按钮的属性名为"maximizeProperty" ui.btnMaximize->setProperty("maximizeProperty", "restore"); } else { //目前窗口是还原状态,则最大化/还原的toolTip设置为"Maximize" ui.btnMaximize->setToolTip(tr("Maximize")); //设置按钮的属性名为"maximizeProperty" ui.btnMaximize->setProperty("maximizeProperty", "maximize"); } ui.btnMaximize->setStyle(QApplication::style()); }}void TitleBar::setMiniBtnIcon(const QIcon& icon) { ui.btnMinimize->setIcon(icon.pixmap(ui.btnMinimize->size()));}void TitleBar::setMaxiBtnIcon(const QIcon& icon) { ui.btnMaximize->setIcon(icon.pixmap(ui.btnMaximize->size()));}void TitleBar::setCloseBtnIcon(const QIcon& icon) { ui.btnClose->setIcon(icon.pixmap(ui.btnClose->size()));}

3 使用说明

自定义标题栏使用说明(包含TitleBar.h,TitleBar.cpp,TitleBar.ui三个文件):1主窗体类中添加头文件://调用WIN API需要用到的头文件 [实现缩放]#ifdef Q_OS_WIN#include 
#include
#endif2主窗体类中 添加成员变量: int m_nBorderWidth;//表示鼠标位于边框缩放范围的宽度 添加成员函数://nativeEvent主要用于进程间通信-消息传递,使用这种方式后来实现窗体的缩放 bool xxx::nativeEvent(const QByteArray &eventType, void *message, long *result){ Q_UNUSED(eventType) MSG *param = static_cast
(message); switch (param->message) { case WM_NCHITTEST: { int nX = GET_X_LPARAM(param->lParam) - this->geometry().x(); int nY = GET_Y_LPARAM(param->lParam) - this->geometry().y(); // 如果鼠标位于子控件上,则不进行处理 if (childAt(nX, nY) != nullptr) return QWidget::nativeEvent(eventType, message, result); *result = HTCAPTION; // 鼠标区域位于窗体边框,进行缩放 if ((nX > 0) && (nX < m_nBorderWidth)) *result = HTLEFT; if ((nX > this->width() - m_nBorderWidth) && (nX < this->width())) *result = HTRIGHT; if ((nY > 0) && (nY < m_nBorderWidth)) *result = HTTOP; if ((nY > this->height() - m_nBorderWidth) && (nY < this->height())) *result = HTBOTTOM; if ((nX > 0) && (nX < m_nBorderWidth) && (nY > 0) && (nY < m_nBorderWidth)) *result = HTTOPLEFT; if ((nX > this->width() - m_nBorderWidth) && (nX < this->width()) && (nY > 0) && (nY < m_nBorderWidth)) *result = HTTOPRIGHT; if ((nX > 0) && (nX < m_nBorderWidth) && (nY > this->height() - m_nBorderWidth) && (nY < this->height())) *result = HTBOTTOMLEFT; if ((nX > this->width() - m_nBorderWidth) && (nX < this->width()) && (nY > this->height() - m_nBorderWidth) && (nY < this->height())) *result = HTBOTTOMRIGHT; return true; } } return QWidget::nativeEvent(eventType, message, result);}3 在widget中应用自定义标题栏(1)在需要添加自定义标题栏的widget的ui文件中,拖动一个widget加入到当前widget布局的最上方,然后提升控件类为TitleBar(2)主窗体类的构造函数中添加如下代码://Qt::FramelessWindowHint设置窗口标志为无边框,而Qt::WindowStaysOnTopHint使窗口位于所有界面之上setWindowFlags(Qt::FramelessWindowHint);//ui中提升控件installEventFilter(ui.widget);//ui.widget 为布局中提升的自定义标题控件 //设置标题栏标题 图标 按钮图标,可在ui文件中直接修改,也可在代码中修改setWindowTitle("Custom Window");setWindowIcon(QIcon(""));ui.widget->setMiniBtnIcon(QIcon(""));ui.widget->setMaxiBtnIcon(QIcon(""));ui.widget->setCloseBtnIcon(QIcon(""));m_nBorderWidth= 5;4 在mainwindow中应用自定义标题栏(1)新建一个widget,拖动一个子widget到当前widget布局的最上放,提升控件为TitleBar(2) 在当前widget的类中添加头文件,成员变量和成员函数,同上(3)在当前widget的构造函数中添加如下代码//Qt::FramelessWindowHint设置窗口标志为无边框,而Qt::WindowStaysOnTopHint使窗口位于所有界面之上setWindowFlags(Qt::FramelessWindowHint);//ui中提升控件installEventFilter(ui.widget);//ui.widget 为布局中提升的自定义标题控件 //设置标题栏标题 图标 按钮图标,可在ui文件中直接修改,也可在代码中修改/*setWindowTitle("Custom Window");setWindowIcon(QIcon(""));ui.widget->setMiniBtnIcon(QIcon(""));ui.widget->setMaxiBtnIcon(QIcon(""));ui.widget->setCloseBtnIcon(QIcon(""));*/m_nBorderWidth= 5;//MainWindow为需要添加自定义标题栏的主界面类MainWindow *maindow = new MainWindow(this);maindow->setWindowFlags(Qt::FramelessWindowHint);/*QVBoxLayout *vlayout = new QVBoxLayout;vlayout->addWidget(ui.titlebar_widget_);QString path = QStringLiteral(":/png/最小化.png");QIcon minicon(path);ui.titlebar_widget_->setMiniBtnIcon(minicon);path = QStringLiteral(":/png/窗口.png");QIcon maxicon(path);ui.titlebar_widget_->setMaxiBtnIcon(maxicon);path = QStringLiteral(":/png/关 闭.png");QIcon closeicon(path);ui.titlebar_widget_->setCloseBtnIcon(closeicon);QString filestyle = QStringLiteral("background-image: url(:/png/标题栏-背景.png);");ui.titlebar_widget_->setStyleSheet(filestyle);*/QVBoxLayout *vlayout = new QVBoxLayout;vlayout->addWidget(ui.titlebar_widget_);vlayout->addWidget(maindow);//设置布局距离上下左右的距离,根据需要设置,也可在ui中修改vlayout->setContentsMargins(2,1,2,1);setLayout(vlayout);(4)在显示主界面的时候,在main函数中将MainWindow类换为新加的widget,即可显示自定义标题栏

 4 ui文件见上传文件

转载于:https://www.cnblogs.com/LuckCoder/p/11195704.html

你可能感兴趣的文章
除去内容中的空格与换行
查看>>
jQuery on(),live(),trigger()
查看>>
Python2.7 urlparse
查看>>
sencha touch在华为emotion ui 2.0自带浏览器中圆角溢出的bug
查看>>
【架构】Linux的架构(architecture)
查看>>
ASM 图解
查看>>
Date Picker控件:
查看>>
svn在linux下的使用(svn命令行)ubuntu 删除 新增 添加 提交 状态查询 恢复
查看>>
java处理url中的特殊字符%等
查看>>
你的第一个Django程序
查看>>
Tomcat免安装版的环境变量配置以及Eclipse下的Tomcat配置和测试
查看>>
Unity3D性能优化之Draw Call Batching
查看>>
grafana授权公司内部邮箱登录 ldap配置
查看>>
treegrid.bootstrap使用说明
查看>>
[Docker]Docker拉取,上传镜像到Harbor仓库
查看>>
javascript 浏览器类型检测
查看>>
基于easyX的<颜色侵略>小游戏
查看>>
nginx 不带www到www域名的重定向
查看>>
CruiseControl.NET ----- mail 配置
查看>>
查找工具locate和find
查看>>