赞
踩
源码文末已给出
// 去掉标题栏,去掉工具栏,窗口置顶
setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);
this->setWindowOpacity(0.7);
隐藏标题栏后窗体是无法拖动的,这个时候就需要重写mousePressEvent、mouseMoveEvent和mouseReleaseEvent。在对应的mainwindow.h头文件中添加一个成员变量QPoint。同时重定义三个鼠标事件函数
设置窗口无标题
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint);
//在头文件中重写鼠标事件
private slots:
//由于去掉显示界面的菜单栏和标题栏,无法拖动窗口,重写关于窗口拖动用的几个函数
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
private:
QPoint last;//窗口拖动用变量
重写mousePressEvent、mouseMoveEvent和mouseReleaseEvent函数。在cpp中
//三个鼠标事件的重写 //鼠标释放 void pre_canshuwidget::mousePressEvent(QMouseEvent *e) { if(e->button()== Qt::LeftButton) //鼠标左键释放 last = e->globalPos(); } //鼠标移动 void pre_canshuwidget::mouseMoveEvent(QMouseEvent *e) { if(e->buttons()==Qt::LeftButton) //坐标左键按下并移动 { int dx = e->globalX() - last.x(); int dy = e->globalY() - last.y(); last = e->globalPos(); move(x()+dx, y()+dy); } } //鼠标按下 void pre_canshuwidget::mouseReleaseEvent(QMouseEvent *e) { if(e->button()==Qt::LeftButton) //鼠标左键按下 { int dx = e->globalX() - last.x(); int dy = e->globalY() - last.y(); move(x()+dx, y()+dy); } }
参考:https://blog.csdn.net/qq_27085429/article/details/90735485
2020.6.30更新
经过上面的处理,我们已经能够实现将窗口标题隐藏后可以拖动窗口,但还不是一个完美的无边框窗口,不能改变窗口大小,不能拖拽还原。
要实现上面的功能,我们要继续改造重写鼠标事件。首先在头文件中定义一个枚举,来判别鼠标当前所在的位置,改变鼠标形状。
先看效果
Mainwindow.h
public:
enum MousePoss{LeftUp=0,Up,RightUp,Right,RightDown,Down,LeftDown,Left,Middle};
private:
MainWindow::MousePoss mp_curPos; //记录鼠标当前所在区域的变量
思路:
//计算鼠标位置 MainWindow::MousePoss MainWindow::calcmouseposs(QPoint p) { MainWindow::MousePoss mp; if(p.x()<MOUSE_MARGIN && p.y() < MOUSE_MARGIN) mp=MainWindow::MousePoss::LeftUp; //左上 else if(p.x()>MOUSE_MARGIN && p.y()< MOUSE_MARGIN && p.x()<this->width()-MOUSE_MARGIN) mp = MainWindow::MousePoss::Up; //上 else if(p.x() > this->width()-MOUSE_MARGIN && p.y() < MOUSE_MARGIN) mp = MainWindow::MousePoss::RightUp; //右上 else if(p.x() > this->width()-MOUSE_MARGIN && p.y() > MOUSE_MARGIN && p.y()<this->height()-MOUSE_MARGIN) mp = MainWindow::MousePoss::Right; //右 else if(p.x() > this->width()-MOUSE_MARGIN && p.y() > this->height()-MOUSE_MARGIN) mp = MainWindow::MousePoss::RightDown; //右下 else if(p.x()>MOUSE_MARGIN && p.x() < this->width()-MOUSE_MARGIN && p.y() > this->height()-MOUSE_MARGIN) mp = MainWindow::MousePoss::Down; //下 else if(p.x() < MOUSE_MARGIN && p.y() > this->height()-MOUSE_MARGIN) mp = MainWindow::MousePoss::LeftDown; //左下 else if(p.x() < MOUSE_MARGIN && p.y() < this->height()-MOUSE_MARGIN && p.y()>MOUSE_MARGIN) mp = MainWindow::MousePoss::Left; //左 else mp=MainWindow::MousePoss::Middle; //中间 return mp; } //修改鼠标样式 void MainWindow::setCursorType(MainWindow::MousePoss type) { Qt::CursorShape cursor; switch(type) { case MainWindow::MousePoss::LeftUp: case MainWindow::MousePoss::RightDown: cursor=Qt::SizeFDiagCursor; break; case MainWindow::MousePoss::Up: case MainWindow::MousePoss::Down: cursor=Qt::SizeVerCursor; break; case MainWindow::MousePoss::RightUp: case MainWindow::MousePoss::LeftDown: cursor=Qt::SizeBDiagCursor; break; case MainWindow::MousePoss::Right: case MainWindow::MousePoss::Left: cursor=Qt::SizeHorCursor; break; default: cursor=Qt::ArrowCursor; break; } setCursor(cursor); } //改变窗口的大小 void MainWindow::changeWindowSize(MainWindow::MousePoss type, QRect &wid,QPoint ptemp,int minWidth, int minHeight) { switch(type)//改变窗口的大小 { case MainWindow::MousePoss::LeftUp: { QPoint pos = wid.topLeft(); if(wid.width() > minWidth || ptemp.x() < 0) pos.rx() = pos.rx() + ptemp.x(); if(wid.height() > minHeight || ptemp.y() < 0) pos.ry() = pos.ry() + ptemp.y(); wid.setTopLeft(pos); break;//左上角 } case MainWindow::MousePoss::RightUp: { QPoint pos = wid.topRight(); if(wid.width() > minWidth || ptemp.x() > 0) pos.rx() = pos.rx() + ptemp.x(); if(wid.height() > minHeight || ptemp.y() < 0) pos.ry() = pos.ry() + ptemp.y(); wid.setTopRight(pos); break;//右上角 } case MainWindow::MousePoss::LeftDown: { QPoint pos = wid.bottomLeft(); if(wid.width() > minWidth || ptemp.x() < 0) pos.rx() = pos.rx() + ptemp.x(); if(wid.height() > minHeight || ptemp.y() > 0) pos.ry() = pos.ry() + ptemp.y(); wid.setBottomLeft(pos); break;//左下角 } case MainWindow::MousePoss::RightDown: { QPoint pos = wid.bottomRight(); if(wid.width() > minWidth || ptemp.x() > 0) pos.rx() = pos.rx() + ptemp.x(); if(wid.height() > minHeight || ptemp.y() > 0) pos.ry() = pos.ry() + ptemp.y(); wid.setBottomRight(pos); break;//右下角 } case MainWindow::MousePoss::Up: { int topY = wid.top(); if(wid.height() > minHeight || ptemp.y() < 0) topY = topY + ptemp.y(); wid.setTop(topY); break;//上 } case MainWindow::MousePoss::Left: { int leftX = wid.left(); if(wid.width() > minWidth || ptemp.x() < 0) leftX = leftX + ptemp.x(); wid.setLeft(leftX); break;//左 } case MainWindow::MousePoss::Right: { int rightX = wid.right(); if(wid.width() > minWidth || ptemp.x() > 0) rightX = rightX + ptemp.x(); wid.setRight(rightX); break;//右 } case MainWindow::MousePoss::Down: { int botY = wid.bottom(); if(wid.height() > minHeight || ptemp.y() > 0) botY = botY + ptemp.y(); wid.setBottom(botY); break;//下 } default: break; } } //三个鼠标事件的重写 void MainWindow::mousePressEvent(QMouseEvent *e) { if(e->button()== Qt::LeftButton) //鼠标左键按下 { last = e->globalPos(); e->ignore(); } } //鼠标移动 void MainWindow::mouseMoveEvent(QMouseEvent *e) { //最大化状态,鼠标是否在标题栏,拖拽还原 if(this->isMaximized()) { if(ui->fram_title->geometry().contains(this->mapFromGlobal(QCursor::pos())) && e->buttons()==Qt::LeftButton) { QPoint ptemp=e->globalPos(); if(ptemp!=last) { this->showNormal(); } } } MainWindow::MousePoss curPos=calcmouseposs(e->pos()); if(!e->buttons()) { setCursorType(curPos); mp_curPos=curPos; } if(e->buttons()==Qt::LeftButton) //坐标左键按下并移动 { QPoint ptemp=e->globalPos(); ptemp=ptemp-last; //鼠标移动的偏移量 if(mp_curPos==MainWindow::MousePoss::Middle && ui->fram_title->geometry().contains(this->mapFromGlobal(QCursor::pos()))) { move(ptemp+pos()); } else { QRect wid=geometry(); int minWidth = this->minimumWidth(); int minHeight = this->minimumHeight(); changeWindowSize(mp_curPos,wid,ptemp,minWidth,minHeight); //更新大小 setGeometry(wid); } last = e->globalPos(); } e->ignore(); } //鼠标释放 void MainWindow::mouseReleaseEvent(QMouseEvent *e) { if(e->button()==Qt::LeftButton && ui->fram_title->geometry().contains(this->mapFromGlobal(QCursor::pos()))) //鼠标左键释放 { int dx = e->globalX() - last.x(); int dy = e->globalY() - last.y(); move(x()+dx, y()+dy); } QApplication::restoreOverrideCursor();//恢复鼠标指针性状 e->ignore(); }
注意注意注意:qt的鼠标事件默认情况是只有当按键按下才会被qt监控,想要不发生按下事件时也接收鼠标信号,我们就需要手动设置部件追踪鼠标。
//追踪鼠标,写在构造函数中
this->setMouseTracking(true);
ui->centralWidget->setMouseTracking(true);
ui->fram_title->setMouseTracking(true);
这里有一个坑,当你设置的鼠标追踪事件部件是父部件,而窗口里面有一个子部件占用父部件较大面积时,在子部件中就接收不到鼠标信号了。
再次更新:双击标题栏最大化(还原)
这个也很简单,只需要重写鼠标双击事件就可以达到目的了。
//在头文件中添加
protected:
//窗口双击事件
void mouseDoubleClickEvent(QMouseEvent *e);
实现:
void MainWindow::mouseDoubleClickEvent(QMouseEvent *e) { if(ui->fram_title->geometry().contains(this->mapFromGlobal(QCursor::pos()))) { if(this->isMaximized()) { this->showNormal(); /*TODO一些其他需要处理的事情*/ } else { this->showMaximized(); /*TODO一些其他需要处理的事情*/ } } else { QMainWindow::mouseDoubleClickEvent(e); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。