功能描述
1.去掉窗口默认边框。
2.自定义窗口标题栏。
3.可拖动、调用窗口大小。
4.实现放大、缩小、还原。
效果图

代码区
MyWidget.h
#pragma once
#include <QtWidgets/QWidget>
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget *parent = Q_NULLPTR);
protected:
//本地事件处理接口,可接收window发生的信号
virtual bool nativeEvent(const QByteArray& eventType, void* message, long* result) Q_DECL_OVERRIDE;
};
MyWidget.cpp
#include "MyWidget.h"
#include "TitleWidget.h"
#include <QVBoxLayout>
#include <qt_windows.h>
#include <Windows.h>
#include <windowsx.h>
#include <QDebug>
#pragma comment(lib,"user32.lib")
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
//布局
QVBoxLayout* root = new QVBoxLayout(this);
TitleWidget* titleBox = new TitleWidget(this);
root->addWidget(titleBox,0,Qt::AlignTop);
root->setContentsMargins(0, 0, 0,0);
setLayout(root);
resize(800, 600);
setWindowFlags(Qt::FramelessWindowHint);
}
//本地事件处理接口,可接收window发生的信号,处理window放大缩小的拖拽
bool MyWidget::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
const int DIFF = 5;
MSG* pMsg = static_cast<MSG*>(message);
switch (pMsg->message)
{
case WM_NCHITTEST: //鼠标发生移动
{
int dx = GET_X_LPARAM(pMsg->lParam) - this->geometry().x();
int dy = GET_Y_LPARAM(pMsg->lParam) - this->geometry().y();
qDebug() << "dx=" << dx << ",dy=" << dy;
if (childAt(dx, dy)!= nullptr) {
return QWidget::nativeEvent(eventType, message, result);
}
if (dx > 0 && dx < DIFF) //左边
*result = HTLEFT;
if (dx > this->width() - DIFF && dx < this->width()) //右边
*result = HTRIGHT;
if (dy > 0 && dy < DIFF) //上边
*result = HTTOP;
if (dy > this->height() - DIFF && dy < this->height()) //下边
*result = HTBOTTOM;
if (dx > 0 && dx < DIFF && dy>0 && dy << DIFF) //左上角
*result = HTTOPLEFT;
if (dx > this->width() - DIFF && dx < this->width() && dy>0 && dy < DIFF) //右上角
*result = HTTOPRIGHT;
if (dx > 0 && dx <DIFF && dy >this->height() - DIFF && dy < this->height()) //左下角
*result = HTBOTTOMLEFT;
if (dx > this->height() - DIFF && dx < this->width() && dy > this->height() - DIFF && dy < this->height()) //右下角
*result = HTBOTTOMRIGHT;
}
return true;
}
return QWidget::nativeEvent(eventType, message, result);
}
TitleWidget.h
#pragma once
#include <QWidget>
#include <QPaintEvent>
#include <QPushButton>
//自定义标题栏
class TitleWidget : public QWidget
{
Q_OBJECT
public:
TitleWidget(QWidget *parent);
~TitleWidget();
private slots:
void OnClickTitle();
private:
QPushButton* maxBtn;
protected:
//绘制背景
virtual void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE;
//双击标题栏放大缩小
virtual void mouseDoubleClickEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
//鼠标按下标题栏拖动窗口
virtual void mousePressEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
};
TitleWidget.cpp
#include "TitleWidget.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QPainter>
#include <QPen>
#include <QDebug>
#include <qt_windows.h>
#include <Windows.h>
#include <WindowsX.h>
#pragma comment(lib,"user32.lib")
static QString styleBtn = "*{border:0px;} :hover{background-color:#3a86e9;}";
//标题栏排版
TitleWidget::TitleWidget(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout* rootBox = new QHBoxLayout(this);
QHBoxLayout *letBox = new QHBoxLayout(this);
QHBoxLayout *rightBox = new QHBoxLayout(this);
QLabel* logo = new QLabel(this);
logo->setFixedSize(60, 40);
logo->setText(tr("LOGO"));
logo->setAlignment(Qt::AlignCenter);
logo->setStyleSheet("color:#fff;font-size:16px;");
logo->setProperty("id", "logo");
QPushButton* minBtn = new QPushButton(this);
minBtn->setFixedSize(QSize(30, 30));
minBtn->setStyleSheet(styleBtn);
minBtn->setIcon(QIcon(":/img/min.png"));
minBtn->setProperty("id", "min");
maxBtn = new QPushButton(this);
maxBtn->setFixedSize(QSize(30, 30));
maxBtn->setStyleSheet(styleBtn);
maxBtn->setIcon(QIcon(":/img/max.png"));
maxBtn->setProperty("id", "max");
QPushButton* closeBtn = new QPushButton(this);
closeBtn->setStyleSheet(styleBtn);
closeBtn->setFixedSize(QSize(30, 30));
closeBtn->setIcon(QIcon(":/img/close.png"));
closeBtn->setProperty("id", "close");
letBox->addWidget(logo,0,Qt::AlignLeft);
rightBox->addWidget(minBtn);
rightBox->addWidget(maxBtn);
rightBox->addWidget(closeBtn);
rightBox->setAlignment(Qt::AlignRight);
rightBox->setContentsMargins(0, 0, 10, 0);
rootBox->addLayout(letBox);
rootBox->addLayout(rightBox);
setFixedHeight(40);
rootBox->setContentsMargins(0, 0, 0, 0);
setLayout(rootBox);
connect(minBtn, SIGNAL(clicked()), this, SLOT(OnClickTitle()));
connect(maxBtn, SIGNAL(clicked()), this, SLOT(OnClickTitle()));
connect(closeBtn, SIGNAL(clicked()), this, SLOT(OnClickTitle()));
}
TitleWidget::~TitleWidget()
{
}
//绘制标题栏背景
void TitleWidget::paintEvent(QPaintEvent* event)
{
QPainter p(this);
QPen pen;
pen.setStyle(Qt::NoPen);
pen.setWidth(0);
p.setPen(pen);
p.setBrush(QBrush(QColor("#4395ff")));
p.drawRect(0, 0, this->width(), this->height());
}
//双击标题栏放大缩小
void TitleWidget::mouseDoubleClickEvent(QMouseEvent* event)
{
emit this->maxBtn->clicked();
}
//鼠标按下标题栏拖动窗口
void TitleWidget::mousePressEvent(QMouseEvent* event)
{
if(ReleaseCapture())
SendMessage((HWND)this->window()->winId(), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
}
//最小最大化关闭槽函数
void TitleWidget::OnClickTitle()
{
QPushButton* pushBtn = qobject_cast<QPushButton*>(this->sender());
QWidget *win= this->window();
if (!win)return;
QString id=pushBtn->property("id").toString();
if (id == "min")
{
win->showMinimized();
}
else if(id=="max")
{
if (win->isMaximized()) {
win->showNormal();
}
else
{
win->showMaximized();
}
}
else if(id=="close")
{
win->close();
}
}
网友评论