首页 >> 知识 >> 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); //根据传入的坐标,设置光标样式

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

//最小化界面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 locations = this->geometry(); if (max) { this->setGeometry(locations);//回复窗口原大小和位置 ui->maxBtn->setIcon(QIcon(":/MAX_.png")); }else { ui->maxBtn->setIcon(QIcon(":/minMAX.png")); locations = this->geometry();//最大化前记录窗口大小和位置 //this->setGeometry(qApp->desktop()->availableGeometry()); this->showFullScreen();//设置窗口铺满全屏 } max = !max;}

在设置窗口 可伸缩、可移动前,需要线分析以下窗口; 如图,可将窗口分为如下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.判断是否时左键点击 _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()this->height()-MARGIN) return 30+row; else return 20+row;}//获取光标在窗口所在区域的 行 返回行数int RailwayPowerInterface::countRow(QPoint p){ return (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; }}
网站地图