逆枫゛

Qt学习群:1149411109 群文件提供博客源码,定期答疑、更新学习资料。

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1,简介

 

之前介绍过实现无边框窗口的简单方法,包含了标题的拖拽、最大最小关闭按钮,双击最大化恢复等功能。

如图:

 

但是这个方案有一个缺陷,那就是不能自由缩放窗口尺寸

如果默认尺寸不是很适合内容,那么只能选择最大化。

 

在网上找了一些方案,不是太理想。

要么是有细节处理不完美,要么是实现方式太过复杂,有一群类需要自己认真剥离出来。

而我直观感觉,应该是很简单就可以解决的,不就是拖拽时改变窗口大小嘛,于是试了试果然很简单。

效果个人感觉还OK,其中缩放图标依旧是自己PS画的

网上找了些带缩放的窗口,了解了大致样式,然后按照自己需要的图标大小画,这样比较清晰

 

 

2,效果

 

 

3,原理

 

原理很简单

就是底部做了一个水平布局的widget,最右侧放一个图片label,该label设置鼠标样式为缩放型。

给label过滤鼠标消息,按下、移动、弹起

在按下时记录按下位置;在移动时,计算相对按下时的鼠标偏移;在松开时设置窗口尺寸。

 

4,主要代码

 

MainWindow.h:

 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMouseEvent>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    bool eventFilter(QObject *obj, QEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

private slots:
    void on_btnMin_clicked();
    void on_btnMax_clicked();
    void on_btnExit_clicked();

private:
    Ui::MainWindow *ui;

    //标题拖动、双击最大化
    bool mDrag;
    QPoint mDragPos;
    bool mIsMax;
    QRect mLocation;
    QFont mIconFont;

    //与缩放相关的变量
    int mZoom;
    QRect mZoomLocation;
    QPoint mZoomPos;

};

#endif // MAINWINDOW_H


MainWindow.cpp:

 

 

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDesktopWidget>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    setWindowFlags(Qt::FramelessWindowHint);

    mLocation = this->geometry();
    mIsMax = false;
    mDrag = false;

    mZoom = false;

    ui->widgetTitle->installEventFilter(this);
    ui->btnMin->setIcon(QIcon(":/image/min.png"));
    ui->btnMax->setIcon(QIcon(":/image/max1.png"));
    ui->btnExit->setIcon(QIcon(":/image/exit.png"));

    //给缩放的图片label处理鼠标的按下、移动、弹起消息,进行缩放窗口功能
    ui->labelZoom->installEventFilter(this);
    ui->labelZoom->setCursor(Qt::SizeFDiagCursor);

    setStyleSheet("QMainWindow{color:#E8E8E8;background:#43CD80;}");

    //另外在设计器内查看widgetTitle样式,内有标题栏各个子控件的样式设置
}

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

bool MainWindow::eventFilter(QObject *obj, QEvent *e)
{
    if (obj == ui->widgetTitle)
    {
        if(e->type() == QEvent::MouseButtonDblClick)
        {
            on_btnMax_clicked();
            return true;
        }
    }
    else if (obj == ui->labelZoom)
    {
        //实现拖动右下角缩放窗口
        if(e->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent *event = (QMouseEvent *)e;
            if (event->buttons() & Qt::LeftButton)
            {
                if(mIsMax)
                {
                    //已最大化,就不让再拖动
                    return true;
                }
                mZoom = true;
                mZoomLocation = geometry();
                mZoomPos = event->globalPos();
                return true;
            }
        }
        else if(e->type() == QEvent::MouseMove)
        {
            QMouseEvent *event = (QMouseEvent *)e;
            if (mZoom && (event->buttons() & Qt::LeftButton))
            {
                int dx = event->globalPos().x() - mZoomPos.x();
                int dy = event->globalPos().y() - mZoomPos.y();
                QRect rc = mZoomLocation;
                rc.setRight(rc.right() + dx);
                rc.setBottom(rc.bottom() + dy);
                setGeometry(rc);
                update();
                return true;
            }
        }
        else if(e->type() == QEvent::MouseButtonRelease)
        {
            mZoom = false;
            return true;
        }
    }
    return QObject::eventFilter(obj, e);
}

void MainWindow::mousePressEvent(QMouseEvent *e)//鼠标按下事件
{
    if (e->button() == Qt::LeftButton)
    {
        mDrag = true;
        mDragPos = e->globalPos() - pos();
        e->accept();
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent *e)//鼠标移动事件
{
    if (mDrag && (e->buttons() && Qt::LeftButton))
    {
        move(e->globalPos() - mDragPos);
        e->accept();
    }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *e)//鼠标释放事件
{
    mDrag = false;
}

void MainWindow::on_btnMin_clicked()
{
    showMinimized();
}

void MainWindow::on_btnMax_clicked()
{
    if (mIsMax)
    {
        setGeometry(mLocation);
        ui->btnMax->setIcon(QIcon(":/image/max1.png"));
        ui->btnMax->setToolTip(QStringLiteral("最大化"));
    }
    else
    {
        mLocation = geometry();
        setGeometry(qApp->desktop()->availableGeometry());
        ui->btnMax->setIcon(QIcon(":/image/max2.png"));
        ui->btnMax->setToolTip(QStringLiteral("还原"));
    }
    mIsMax = !mIsMax;
}

void MainWindow::on_btnExit_clicked()
{
    qApp->exit();
}

 

 

 

 

 

5,源码

 

Qt无边框窗口2 右下角缩放.rar:

链接:https://pan.baidu.com/s/1tLDEF5IDBg9wIG7zvCxdmA 
提取码:0y6b

 

 

 

 

posted on 2017-09-26 01:47  逆枫゛  阅读(337)  评论(0编辑  收藏  举报