无边框窗口实现

本文档介绍了如何在Qt中创建一个无边框窗口,通过处理鼠标事件实现窗口的自适应移动和大小调整,包括不同方向的边界处理和颜色随机填充的视觉效果。
摘要由CSDN通过智能技术生成

无边框窗口实现

记录一下

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

//方向
enum DirType{
    TOP,BOTTOM,LEFT,RIGHT,LEFTTOP,RIGHTTOP,LEFTBOTTOM,RIGHTBOTTOM,NORMAL
};

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
protected:
    void mousePressEvent(QMouseEvent* ev)override;
    void mouseMoveEvent(QMouseEvent* ev)override;
    void mouseReleaseEvent(QMouseEvent* ev)override;
    void paintEvent(QPaintEvent* ev)override;
private:
    Ui::Widget *ui;
    //方向类型
    DirType m_type = NORMAL;
    //四个方向的矩形
    QRectF topleftRect;
    QRectF topRightRect;
    QRectF bottomLeftRect;
    QRectF bottomRightRect;
    //矩形大小
    int rectsize = 15;
    //鼠标按下位置记录
    QPointF m_pressPos;
    //改变大小标记
    bool m_isChangeSize = false;
    bool m_isMove = false;
};
#endif // WIDGET_H

cpp实现

#include "widget.h"
#include "ui_widget.h"

#include <QPainter>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setMouseTracking(true);
    setWindowFlags(Qt::FramelessWindowHint | Qt::SubWindow | Qt::WindowStaysOnTopHint);
    qsrand(time(0));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::mousePressEvent(QMouseEvent *ev)
{
    m_pressPos = ev->globalPos();
    if(m_type!=NORMAL){
        m_isChangeSize = true;
    }else{
        m_isMove = true;
    }
    QWidget::mousePressEvent(ev);
}

void Widget::mouseMoveEvent(QMouseEvent *ev)
{
    QPointF deltaPos = ev->globalPos() - m_pressPos;
    if(m_isChangeSize){

        QRectF curRect = geometry();
        qDebug()<<__func__<<"before"<<curRect;
        switch (m_type) {
        case TOP:
            curRect = curRect.adjusted(0,deltaPos.y(),0,0);
            break;
        case BOTTOM:
            curRect = curRect.adjusted(0,0,0,deltaPos.y());
            break;
        case LEFT:
            curRect = curRect.adjusted(deltaPos.x(),0,0,0);
            break;
        case RIGHT:
            curRect = curRect.adjusted(0,0,deltaPos.x(),0);
            break;
        case LEFTTOP:
            curRect = curRect.adjusted(deltaPos.x(),deltaPos.y(),0,0);
            break;
        case RIGHTTOP:
            curRect = curRect.adjusted(0,deltaPos.y(),deltaPos.x(),0);
            break;
        case LEFTBOTTOM:
            curRect = curRect.adjusted(deltaPos.x(),0,0,deltaPos.y());
            break;
        case RIGHTBOTTOM:
            curRect = curRect.adjusted(0,0,deltaPos.x(),deltaPos.y());
            break;
        default:
            break;
        }
        qDebug()<<__func__<<"after"<<curRect;
        setGeometry(curRect.toRect());

    }else if(m_isMove) {
        move(pos()+deltaPos.toPoint());
    }
    else{
        if(topleftRect.contains(ev->pos()) || bottomRightRect.contains(ev->pos()))
        {
            setCursor(Qt::SizeFDiagCursor);
            topleftRect.contains(ev->pos()) ? m_type = LEFTTOP : m_type = RIGHTBOTTOM;
        }else if(topRightRect.contains(ev->pos()) || bottomLeftRect.contains(ev->pos())){
            setCursor(Qt::SizeBDiagCursor);
            topRightRect.contains(ev->pos()) ? m_type = RIGHTTOP : m_type = LEFTBOTTOM;
        }else if(ev->pos().x() == 0 || ev->pos().x() == geometry().width()-1){
            setCursor(Qt::SizeHorCursor);
            ev->pos().x()==0 ? m_type = LEFT : m_type = RIGHT;
        }else if(ev->pos().y() == 0 || ev->pos().y() == geometry().height()-1){
            setCursor(Qt::SizeVerCursor);
            ev->pos().y()==0 ? m_type = TOP : m_type = BOTTOM;
        }else{
            setCursor(Qt::ArrowCursor);
            m_type = NORMAL;
        }
    }
    m_pressPos = ev->globalPos();
    QWidget::mouseMoveEvent(ev);
}

void Widget::mouseReleaseEvent(QMouseEvent *ev)
{
    m_isChangeSize = false;
    m_isMove = false;
    QWidget::mouseReleaseEvent(ev);
}

void Widget::paintEvent(QPaintEvent *ev)
{
    QWidget::paintEvent(ev);
    topleftRect = QRectF(-rectsize/2,-rectsize/2,rectsize,rectsize);
    topRightRect = QRectF(geometry().width()-rectsize/2,-rectsize/2,rectsize,rectsize);
    bottomLeftRect = QRectF(-rectsize/2,geometry().height()-rectsize/2,rectsize,rectsize);
    bottomRightRect = QRectF(geometry().width()-rectsize/2,geometry().height()-rectsize/2,rectsize,rectsize);
    QPainter painter(this);
    painter.setPen(Qt::NoPen);
    painter.setBrush(QColor(rand()%255,rand()%255,rand()%255));
    QRectF newRect(topleftRect.center(),bottomRightRect.center());
    painter.drawRect(newRect);
    painter.setBrush(QColor(rand()%255,rand()%255,rand()%255));
    painter.drawRect(topleftRect);
    painter.setBrush(QColor(rand()%255,rand()%255,rand()%255));
    painter.drawRect(topRightRect);
    painter.setBrush(QColor(rand()%255,rand()%255,rand()%255));
    painter.drawRect(bottomLeftRect);
    painter.setBrush(QColor(rand()%255,rand()%255,rand()%255));
    painter.drawRect(bottomRightRect);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值