目录
在很多项目里,客户不满意qt自带标题栏的外观,要求开发者自定义一个窗体样式。新的窗体标题栏的背景色可以通过qss定义,且最大化、最小化、关闭三个按钮的位置外观乃至功能都可以定制。本文介绍如何定制这样的标题栏,标题栏只有关闭窗口,且用户可以通过标题栏实现窗体的移动。示例代码见我的资源定制QWidget标题栏的示例,并含有qss配置QTabWidget样式的示例-QT文档类资源-CSDN下载。
1 主要代码:
#include "WgtWrapper.h"
#include "ui_WgtWrapper.h"
#include <QDebug>
#include <QMouseEvent>
#include <QEvent>//这个必须要有,否则event转换失败
#include <QApplication>
#include <QDesktopWidget>
WgtWrapper::WgtWrapper(QWidget *parent) :
QWidget(parent),
ui(new Ui::WgtWrapper)
{
ui->setupUi(this);
ui->BtnClose->setFixedSize(15,15);
setObjectName("DevMonitorWGT");
initStyleSheet();
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);//选项Qt::Tool导致关窗口不停止程序
m_pTab = new QTabWidget;
ui->verticalLayout->addWidget(m_pTab);
m_pTab->setAttribute(Qt::WA_StyledBackground);/*与qss中的QTabWidget一起起作用,让qtabwidget表头右侧的空白区域也呈现与QTabWidget::pane一样的风格*/
m_pWgt1 = new QWidget;
m_pWgt2 = new QWidget;
m_pTab->addTab(m_pWgt1, QString("1"));
m_pTab->addTab(m_pWgt2, QString("2"));
connect(ui->BtnClose, SIGNAL(clicked()), this, SLOT(hide()));
ui->WgtTitle->installEventFilter(this);
}
WgtWrapper::~WgtWrapper()
{
delete m_pWgt1;
delete m_pWgt2;
delete ui;
}
void WgtWrapper::initStyleSheet()
{
QString appDirPath = QApplication::applicationDirPath();
///界面字体
QFile fontFile (appDirPath+"/MonitorConfig/stylesheet.qss");
QString fontStr;
if (fontFile.open(QIODevice::ReadOnly|QIODevice::Text))
{
fontStr = fontFile.readAll();
fontFile.close();
}
this->setStyleSheet(fontStr);
}
bool WgtWrapper::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress)
{
if ((static_cast<QMouseEvent *>(event))->button() == Qt::LeftButton)//必须是static cast
{
m_pntPrev = QApplication::desktop()->cursor().pos();
}
return true;
}
else if (event->type() == QEvent::MouseButtonRelease)
{
return true;
}
else if (event->type() == QEvent::MouseMove)
{
if (QApplication::mouseButtons() == Qt::LeftButton)
{
QPoint pnt = QApplication::desktop()->cursor().pos();
move(pos() + pnt - m_pntPrev);
m_pntPrev = pnt;
}
return true;
}
else
{
return QObject::eventFilter(watched, event);
}
}
2 隐藏标题栏
下面的代码将qwidget原有的标题栏隐藏了:
setWindowFlags(Qt::FramelessWindowHint);//选项Qt::Tool导致关窗口不停止程序
而ui界面中添加了一个自定义的标题栏WgtTitle
WgtTitle的内部又包含一个label,一个弹簧和一个QPushButton(名为BtnClose)
3 如何实现窗体拖动
利用eventFilter,当鼠标拖动WgtTitle时,WgtWrapper的eventFilter截获了这个事件,并获取了鼠标当前位置。随之将当前位置与上一次事件发生时的位置做减法,得出现在移动了多少距离。最后利用move函数实现WgtWrapper的移动。
ui->WgtTitle->installEventFilter(this);
4 关闭按钮的外观和功能
4.1 外观
高亮部分
4.2 功能
通过信号槽实现点击后隐藏窗体的功能:
connect(ui->BtnClose, SIGNAL(clicked()), this, SLOT(hide()));
如果你想点击按钮后直接退出,考虑类似如下的代码:
connect(ui->BtnClose, SIGNAL(clicked()), QApplication::instance(), SLOT(quit()));
5 其他
下面这句代码的作用是让窗体不在桌面的状态栏显示。
setWindowFlags(Qt::Tool);
6 效果
样式通过qss文件配置,这里不再赘述。