当前位置:   article > 正文

Qt 无边框窗口之 最大化/最小化/可伸缩/可移动_qt 设置最大化,最小化,关闭槽函数

qt 设置最大化,最小化,关闭槽函数

1.实现的功能

窗口的 最大化和最大化前大小切换、最小化、关闭窗口、移动、拉伸、缩小。

很多时候,为了界面的美观,需要将界面设置为无边框窗口,这就需要重写上述功能来完善窗口。

2.具体步骤

最大化、最小化、关闭 为三个按钮,按钮设置好布局位置,设置QIcon,将按钮添加入槽,具体步骤不在此叙述。

以下三个槽函数即为最大化、最小化、关闭三个按钮的槽函数;
私有变量中的变量和函数看注释和具体代码。

private slots:
    void on_minBtn_clicked();
    void on_closeBtn_clicked();
    void on_maxBtn_clicked();
    
private:
    Ui::RailwayPowerInterface  *ui;
    bool _isleftpressed = false; //判断是否是左键点击
    int _curpos = 0;    //鼠标左键按下时光标所在区域
    QPoint _plast;      //获取鼠标左键按下时光标在全局(屏幕而非窗口)的位置
    void mousePressEvent(QMouseEvent* event);//鼠标按下事件
    void mouseReleaseEvent(QMouseEvent* event);//鼠标释放事件
    void mouseMoveEvent(QMouseEvent* event);//鼠标移动事件  
    int countRow(QPoint p);            //获取光标在窗口所在区域的 行   返回行数
    int countFlag(QPoint p,int row);    //获取光标在窗口所在区域的 列  返回行列坐标
    void setCursorType(int flag);          //根据传入的坐标,设置光标样式
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

窗口最大化、最小化、关闭的具体实现代码,比较简单

//最小化界面
void RailwayPowerInterface::on_minBtn_clicked()
{
    this->showMinimized();
}

//关闭界面
void RailwayPowerInterface::on_closeBtn_clicked()
{
    this->close();
}

//放大,缩小界面
void RailwayPowerInterface::on_maxBtn_clicked()
{
    static bool max = false;
    static QRect location = this->geometry();
    if (max) {
        this->setGeometry(location);//回复窗口原大小和位置
        ui->maxBtn->setIcon(QIcon(":/MAX_.png"));
    }else {
        ui->maxBtn->setIcon(QIcon(":/minMAX.png"));
        location = this->geometry();	//最大化前记录窗口大小和位置
        //this->setGeometry(qApp->desktop()->availableGeometry());
        this->showFullScreen();	//设置窗口铺满全屏
    }
    max = !max;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在设置窗口 可伸缩、可移动前,需要线分析以下窗口;
如图,可将窗口分为如下9部分,光标在不同区域将呈现不同样式,而根据光标样式又可以将以下9个区域分为五类:

(1,1) (3,3) :

(1,2) (3,2) :

(1,3) (3,3) :

(2,1) (2,3) :

(2,2) :以上区域用来伸缩窗口,此区域用来移动窗口

注: 在代码中,将坐标(1,1) 以数字 11代替,(1,2)以数字12代替,其他坐标依次类推。

通过宏定义来设定边框区域的大小(即绿色区域)

#define MARGIN 2 
  • 1
//鼠标按下事件
/*
 *作用:
 *1.判断是否时左键点击 _isleftpressed
 *2.获取光标在屏幕中的位置 _plast
 *3.左键按下时光标所在区域 _curpos
 */
void RailwayPowerInterface::mousePressEvent(QMouseEvent *event)
{
	Q_UNUSED(event);
    if (event->button() == Qt::LeftButton)
    {
        this->_isleftpressed = true;
        QPoint temp = event->globalPos();
        _plast = temp;
        _curpos = countFlag(event->pos(), countRow(event->pos()));
    }
}

//鼠标释放事件
/*
 *作用:
 *1.将_isleftpressed 设为false
 *2.将光标样式恢复原样式  setCursor(Qt::ArrowCursor);
 */
void RailwayPowerInterface::mouseReleaseEvent(QMouseEvent *event)
{
    Q_UNUSED(event);
    if (_isleftpressed)
        _isleftpressed = false;
    setCursor(Qt::ArrowCursor);
}

//鼠标移动事件 
void RailwayPowerInterface::mouseMoveEvent(QMouseEvent *event)
{
    Q_UNUSED(event);
    if(this->isFullScreen()) return;	//窗口铺满全屏,直接返回,不做任何操作
    int poss = countFlag(event->pos(), countRow(event->pos()));
    setCursorType(poss);
    if (_isleftpressed)//是否左击
    {
        QPoint ptemp = event->globalPos();
        ptemp = ptemp - _plast;
        if (_curpos == 22)//移动窗口
        {
            ptemp = ptemp + pos();
            move(ptemp);
        }
        else
        {
            QRect wid = geometry();
            switch (_curpos)//改变窗口的大小
            {
            case 11:wid.setTopLeft(wid.topLeft() + ptemp); break;//左上角
            case 13:wid.setTopRight(wid.topRight() + ptemp); break;//右上角
            case 31:wid.setBottomLeft(wid.bottomLeft() + ptemp); break;//左下角
            case 33:wid.setBottomRight(wid.bottomRight() + ptemp); break;//右下角
            case 12:wid.setTop(wid.top() + ptemp.y()); break;//中上角
            case 21:wid.setLeft(wid.left() + ptemp.x()); break;//中左角
            case 23:wid.setRight(wid.right() + ptemp.x()); break;//中右角
            case 32:wid.setBottom(wid.bottom() + ptemp.y()); break;//中下角
            }
            setGeometry(wid);
        }
        _plast = event->globalPos();//更新位置
    }
}

//获取光标在窗口所在区域的 列  返回行列坐标
int RailwayPowerInterface::countFlag(QPoint p,int row)//计算鼠标在哪一列和哪一行
{
    if(p.y()<MARGIN)
        return 10+row;
    else if(p.y()>this->height()-MARGIN)
        return 30+row;
    else
        return 20+row;
}

//获取光标在窗口所在区域的 行   返回行数
int RailwayPowerInterface::countRow(QPoint p)
{
    return (p.x()<MARGIN) ? 1 : (p.x()>(this->width() - MARGIN) ? 3 : 2);
}

//根据鼠标所在位置改变鼠标指针形状
void RailwayPowerInterface::setCursorType(int flag)
{
    switch(flag)
    {
    case 11:
    case 33:
        setCursor(Qt::SizeFDiagCursor);
        break;
    case 13:
    case 31:
        setCursor(Qt::SizeBDiagCursor);break;
    case 21:
    case 23:
        setCursor(Qt::SizeHorCursor);break;
    case 12:
    case 32:
        setCursor(Qt::SizeVerCursor);break;
    case 22:
        setCursor(Qt::ArrowCursor);
        QApplication::restoreOverrideCursor();//恢复鼠标指针性状
        break;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/94983
推荐阅读
相关标签
  

闽ICP备14008679号