美文网首页
QT实现自定义窗口

QT实现自定义窗口

作者: 何亮hook_8285 | 来源:发表于2022-05-09 23:06 被阅读0次

功能描述

1.去掉窗口默认边框。

2.自定义窗口标题栏。

3.可拖动、调用窗口大小。

4.实现放大、缩小、还原。

效果图

image-20220510225604088.png

代码区

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();
    }
    
}

相关文章

网友评论

      本文标题:QT实现自定义窗口

      本文链接:https://www.haomeiwen.com/subject/xkbrurtx.html