VS+QT鼠标事件的一些补充

一:基础知识

1. 鼠标事件分为四种对应不同的函数(该四个函数均继承于QWidget):

(1) 按下Press -> void mouseDoubleClickEvent ( QMouseEvent * event )
(2) 抬起Release -> void mouseMoveEvent ( QMouseEvent * event )
(3) 移动Move -> void mousePressEvent ( QMouseEvent * event )
(4) 双击Double Click -> void mouseReleaseEvent ( QMouseEvent * event )
重写这四个函数,就能够让自定义控件支持鼠标操作。

2. Qt中用QMouseEvent类来表达一个鼠标事件

   event->pos()  当前的鼠标坐标
    x, y : 坐标
   globalX, globalY: 全局坐标(相对于整个屏幕)
  button: 鼠标左键、右键、中键

3. 鼠标的自定义发射事件

class ...
{
    signals:
    void iAmClicked(QPoint pos); // QPoint pos可以是其他数据类型,char、int等,该数据可连同信号一起被传送出去。 

};
当事件发生时,
emit iAmClicked ( pos );
通过emit操作将信号发射出去了。

例:
.h文件中

signals:
	void selected(int Axis);  //发射行列分析坐标信号

.cpp文件中

void ShowP::mousePressEvent(QMouseEvent * event)        //按下
{
	int Axis;
	emit selected(Axis);  //发射事件
}

信号与槽.

// ui.FrameShowP这个一个QWidget窗口
connect(ui.FrameShowP, SIGNAL(selected(int)),this, SLOT(OnSelected(int)));

响应函数.(函数要在.h文件中private slots:先声明)

int mytest::OnSelected(int Axis)  //
{
	qDebug() << Axis;  //把分析坐标点传入
	return 0;
}

二:QMainWindow/QWidget内追踪鼠标事件事件(mousePressEvent移动事件补充)

在Qt中要捕捉鼠标移动事件需要重写MouseMoveEvent,但是MouseMoveEvent为了不太耗资源在默认状态下是要鼠标按下才能捕捉到移动。

如果要想鼠标不按下时的移动也能捕捉到,需要setMouseTracking(true)(激活整个窗体的鼠标追踪)。

bool mouseTracking; 这个属性保存的是窗口部件跟踪鼠标是否生效。

*如果鼠标跟踪失效(默认),当鼠标被移动的时候只有在至少一个鼠标按键被按下时,这个窗口部件才会接收鼠标移动事件。

*如果鼠标跟踪生效,如果没有按键被按下,这个窗口部件也会接收鼠标移动事件。

QWidget: 在QWidget窗口中这样使用是没有问题的。
QMainWindow: 即使使用了setMouseTracking(true),在QMainWindow依然无法捕捉到鼠标没有按下的移动,只有在鼠标按下才能捕捉到移动。
QMainWindow中解决办法:要先把QMainWindow的CentrolWidget使用setMouseTracking(true)开启移动监视。然后在把QMainWindow的setMouseTracking(true)开启监视。之后就一切正常了。
原因:CentrolWIdget是QMainWindow的子类,你如果在子类上响应鼠标事件,只会触发子类的mouseMoveEvent,根据C++继承和重载的原理,所以子类也要setMouseTracking(true); 所以如果你想响应鼠标事件的控件被某个父控件包含,则该控件及其父控件或容器也需setMouseTracking(true);

三:Qt QWidget右键菜单实例

.h文件中

  1. 添加对于头文件*);
  2. 在widget.h中声明右键事件处理函数void contextMenuEvent(QContextMenuEvent
  3. 声明右键菜单信号
  4. 按下菜单响应函数声明
#include 
#include 
#include 

private:
	void contextMenuEvent(QContextMenuEvent *);//右键菜单支持
	
private:
   QAction* Act_Maxsize;
   QAction* Act_Normal;
private slots:
	void ADDChange();
	void XMLChange()

.cpp文件中
1.新建菜单动作信号
2. 建信号与槽(.h文件中先声明响应函数)
3. 右键菜单函数
4. 按下菜单响应函数

Act_Maxsize = new QAction(tr("XML"), this);  //新建信号
Act_Normal = new QAction(tr("SHOW"), this);
connect(Act_Maxsize, SIGNAL(triggered()), this, SLOT(ADDChange())); //信号与槽
connect(Act_Normal, SIGNAL(triggered()), this, SLOT(XMLChange()));

 void Widget::contextMenuEvent(QContextMenuEvent *) //右键菜单项编辑
{
	QCursor cur=this->cursor();
	QMenu *menu=new QMenu(this);
	menu->addAction(Act_Maxsize); //添加菜单项1
	menu->addAction(Act_Normal); //添加菜单项2
	menu->exec(cur.pos()); //关联到光标
}
void Widget::ADDChange()
{
 	qDebug()<<"XML Item Pressed.";
}
void Widget::XMLChange()
{
 	qDebug()<<"SHOW Item Pressed.";
}

参考:http://blog.sina.com.cn/s/blog_98a4dde701013dzh.html

四:Qt 判断鼠标按键(左键和右键区分)

当操作鼠标按键会发现,鼠标按下、抬起、双击信号对于鼠标的左键和右键都能触发,怎么才能更好的区分动作的是左键还是右键。

Qt::MouseButton QMouseEvent::button() const
返回引发事件的按钮。
注意,对于鼠标移动事件,返回的值总是Qt::NoButton。

代表按键类型的枚举变量 enum Qt::MouseButton
Qt::NoButton 0x00000000----------------移动或者未按下 返回 NoButton
Qt::AllButtons 0x07ffffff--------------------左右键全按下 返回 AllButtons
Qt::LeftButton 0x00000001 ------------- 左键全按下 返回 LeftButton
Qt::RightButton 0x00000002 ----------- 右键全按下 返回 RightButton

故可以通过以下方法判断左键操作还是右键操作:

void myWidget::mousePressEvent(QMouseEvent * event) //按下
{
	if (ev->button() & Qt::LeftButton)  //左键按下
		{
			;
		}
	if (ev->button() & Qt::RightButton)  //右键按下
		{
			;
		}
}

void myWidget::mouseReleaseEvent(QMouseEvent * event) //释放
{
	if (ev->button() & Qt::LeftButton)  //左键释放
		{
			;
		}
	if (ev->buttons() & Qt::RightButton)  //右键释放
		{
			;
		}
}
void myWidget::mouseDoubleClickEvent(QMouseEvent * event)  //双击
{
	if (ev->button() & Qt::LeftButton)  //左键双击
		{
			;
		}
	if (ev->buttons() & Qt::RightButton)  //右键双击
		{
			;
		}
}

你可能感兴趣的:(VS+QT鼠标事件的一些补充)