赞
踩
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 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; }
在设置窗口 可伸缩、可移动前,需要线分析以下窗口;
如图,可将窗口分为如下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()<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; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。