在qt中,如果设置的了窗口无边框的话(即setWindowFlag(Qt::FramelessWindowHint);)那么窗口就没法直接被鼠标拖动了,也没法按住窗口的边界进行缩放。
如果要实现缩放和拖动,一般来说就需要的重写窗口类的mousePressEvent和mouseMoveEvent事件。
但是有些时候,比如在界面上放了一个QgraphicsView,主界面就没法响应mousePressEvent和mouseMoveEvent事件。因为该事件被QgraphicsView截取了。这个时候我们就不能简单得通过的重写主窗口的鼠标事件来实现窗口的拖动和缩放了。
我是这样实现的:
如下图所示,我在界面上放了4个qlabel,通过qlabel的raise()方法将他们置顶,这样,这些label就能获取到鼠标移动和点击事件了。
但是,我们是不能直接重写qlabel中的鼠标事件响应函数的,因为在qlabel中,鼠标事件的级别是protected,如下图:
所以这时候就需要我们自己写一个类,继承qlabel,代码如下:
Mylabel.h
1 #ifndef MYLABEL_H 2 #define MYLABEL_H
3
4 #include <QObject>
5 #include <QLabel>
6 #include <QDebug>
7 #include <QMouseEvent>
8 #include <qnamespace.h>
9 class myLabel:public QLabel 10 { 11 Q_OBJECT 12 public: 13 myLabel(QWidget *parent=nullptr); 14 void setScaleCursor(int nshape = 0); 15 void mousePressEvent(QMouseEvent *ev); 16 void mouseMoveEvent(QMouseEvent *ev); 17 void mouseReleaseEvent(QMouseEvent *ev); 18 QPoint m_mousePointOld; 19 bool m_bKeepDrag; 20 signals: 21 void moveEventSig(QPoint point); 22 void mouseReleasedSig(); 23 }; 24
25 #endif // MYLABEL_H
Mylabel.cpp
1 #include "mylabel.h"
2
3 myLabel::myLabel(QWidget *parent):m_bKeepDrag(false) 4 { 5 this->setParent(parent); 6 } 7
8 void myLabel::setScaleCursor(int nshape) 9 { 10 if(nshape == 1)//左右拉伸
11 { 12 setCursor(Qt::SizeHorCursor); //改变光标形状
13 } 14 else if(nshape == 2)//上下拉伸
15 { 16 setCursor(Qt::SizeVerCursor); 17 } 18 else if(nshape == 3)//右下拉伸
19 { 20 setCursor(Qt::SizeFDiagCursor); 21 } 22 else //正常显示
23 { 24 setCursor(Qt::ArrowCursor); 25 } 26
27 } 28
29 void myLabel::mousePressEvent(QMouseEvent *ev) 30 { 31 if(ev->button() == Qt::LeftButton) 32 { 33 m_bKeepDrag = true; 34 m_mousePointOld = ev->globalPos(); 35 } 36 } 37
38 void myLabel::mouseMoveEvent(QMouseEvent *ev) 39 { 40 if(m_bKeepDrag) 41 { 42 const QPoint position = ev->globalPos() - m_mousePointOld; //the position of mainfrmae + (current_mouse_position - last_mouse_position) 43 //move(position.x(), position.y());
44 emit moveEventSig(position); 45 m_mousePointOld = ev->globalPos(); 46 } 47 } 48
49 void myLabel::mouseReleaseEvent(QMouseEvent *ev) 50 { 51 m_bKeepDrag = false; 52 emit mouseReleasedSig(); 53 }
在主界面的类中主要代码如下:
头文件里面定义这4个label
1 myLabel *labelLft; 2 myLabel *labelRit; 3 myLabel *labelBot; 4 myLabel *labelTop;
在cpp文件的构造函数中初始化这4个label,同时通过connect的方式建立信号槽,将label中的鼠标移动事件传给主窗口,从而控制主窗口边界的缩放
1 //上下左右的label,为了控制界面能够拖动拉伸
2 labelLft = new myLabel(this); 3 labelLft->setStyleSheet("QLabel {background-color: transparent;}");//设置背景透明
4 labelLft->raise(); 5 labelLft->setScaleCursor(1); 6 connect(labelLft,&myLabel::moveEventSig,this,&MaxPicShowForm::getLeftScaleEvent); 7 labelRit = new myLabel(this); 8 labelRit->setStyleSheet("QLabel {background-color: transparent;}");//设置背景透明
9 labelRit->raise(); 10 labelRit->setScaleCursor(1);//设置为左右拉升光标
11 connect(labelRit,&myLabel::moveEventSig,this,&MaxPicShowForm::getRightScaleEvent); 12 labelBot = new myLabel(this); 13 labelBot->setStyleSheet("QLabel {background-color: transparent;}");//设置背景透明
14 labelBot->raise(); 15 labelBot->setScaleCursor(2);//设置为上下拉升光标
16 connect(labelBot,&myLabel::moveEventSig,this,&MaxPicShowForm::getBottomScaleEvent); 17 labelTop = new myLabel(this); 18 labelTop->setStyleSheet("QLabel {background-color: transparent;}");//设置背景透明
19 labelTop->setScaleCursor(2);//设置为上下拉升光标
20 connect(labelTop,&myLabel::moveEventSig,this,&MaxPicShowForm::getTopScaleEvent); 21 labelRB = new myLabel(this); 22 labelRB->setStyleSheet("QLabel {background-color: transparent;}");//设置背景透明
23 labelRB->setScaleCursor(3);//设置为右下拉升光标
24 connect(labelRB,&myLabel::moveEventSig,this,&MaxPicShowForm::getRBScaleEvent); 25 //设置4个label的位置:
26 labelLft->setGeometry(0,0,5,this->height()); 27 labelRit->setGeometry(this->width()-5,0,5,this->height()); 28 labelBot->setGeometry(0,this->height()-5,this->width(),5); 29 labelTop->setGeometry(0,0,this->width(),5);
响应鼠标拖动事件:
1 void MaxPicShowForm::getLeftScaleEvent(QPoint movPoint) 2 { 3 if((pos().x()+movPoint.x())>(pos().x()+this->width()-200)) 4 { 5 return;//保证拖动窗口左边界的时候,控件宽度至少有200
6 } 7 this->setGeometry(pos().x()+movPoint.x(),pos().y(),this->width()-movPoint.x(),this->height()); 8 } 9
10 void MaxPicShowForm::getRightScaleEvent(QPoint movPoint) 11 { 12 if((pos().x()+this->width()+movPoint.x())<(pos().x()+200)) 13 { 14 return;//保证拖动窗口右边界的时候,控件宽度至少有200
15 } 16 this->setGeometry(pos().x(),pos().y(),this->width()+movPoint.x(),this->height()); 17 } 18
19 void MaxPicShowForm::getBottomScaleEvent(QPoint movPoint) 20 { 21 if((pos().y()+this->height()+movPoint.y())<(pos().y()+200)) 22 { 23 return;//保证拖动窗口下边界的时候,控件高度至少有200
24 } 25 this->setGeometry(pos().x(),pos().y(),this->width(),this->height()+movPoint.y()); 26 } 27
28 void MaxPicShowForm::getTopScaleEvent(QPoint movPoint) 29 { 30 if((pos().y()+movPoint.y())>(pos().y()+this->height()-200)) 31 { 32 return;//保证拖动窗口上边界的时候,控件高度至少有200
33 } 34 this->setGeometry(pos().x(),pos().y()+movPoint.y(),this->width(),this->height()-movPoint.y()); 35 q}