介绍QT Event以及Event Filter事件处理的内容
1.手动发送事件流程:
(1)构造自己的事件对象:
QEvent *evt = new QEvent(QEvent::Close);
(2)发送给指定的对象
QApplication::sendEvent(this,evt);
2.定制某个控件的事件处理:
(1)确定需要对哪些控件的哪些事件,通常的close以及Key和keyboard事件;
(2)重写该对象的event()函数;
3.事件过滤流程:
(1)确定自己需要过滤处理哪些对象的那些事件;
(2)构造自己的事件过滤类:重写该类的eventFilter函数;
(3)在主程序中实例化一个过滤类对象;
(4)调用该过滤类对象的installEventFilter(receiver,QEvent *event)
QT中鼠标事件:
继承于QWidget
void mouseDoubleClickEvent(QMouseEvent* event)
void mouseMoveEvent(QMouseEvent *event)
void mousePressEvent(QMouseEvent* event)
void mouseReleaseEvent(QMouseEvent* event)
重写这四个函数就能够自定义控件支持鼠标操作。
QT中用QMouseEvent类来表达一个鼠标事件
x,y:坐标
globalX,globalY:全局坐标(相对于整个屏幕)
button:鼠标左键、右键、中键
QT 中 bool mouseTracking:
这个属性保存的是窗口部件跟踪鼠标是否生效。
如果鼠标跟踪失效(默认),当鼠标被移动的时候只有在至少一个鼠标按键被按下时,这个窗口部件才会接受鼠标移动时间;
如果鼠标跟踪生效,如果没有按键被按下,这个窗口部件也会接受鼠标移动事件。
ui.label->setMouseTracking(true);
QT中void QObject::installEventFilter(const QObject *obj):
安装事件过滤器obj到这个对象;
事件过滤器就是接收所有被发送到这个对象的事件的对象。这个过滤器可以停止事件或者把它再转给这个对象;
事件过滤器obj通过它的eventFilter()函数来接收事件。如果事件被过滤了(比如,停止了),eventFilter()函数必须返回真,否则它必须返回假;
如果有多个事件过滤器被安装到同一个对象上,最后一个被安装的事件过滤器将先被激活。
class test_201901035 : public QMainWindow
{
Q_OBJECT
public:
test_201901035(QWidget *parent = 0);
~test_201901035();
protected:
bool eventFilter(QObject* obj, QEvent* evt);
private:
Ui::test_201901035Class ui;
};
test_201901035::test_201901035(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
ui.label->setMouseTracking(true);
//为label窗体安装一个过滤器
ui.label->installEventFilter(this);
}
bool test_201901035::eventFilter(QObject* obj, QEvent* evt)
{
if (qobject_cast<QLabel*>(obj) == ui.label)//或者obj == ui.lbImg
{
//QT QEvent转换未QMouseEvent等子类
QMouseEvent *msEvent = static_cast<QMouseEvent*>(evt);
//看鼠标有没有Move消息
if (msEvent->type() == QEvent::MouseMove)
{
//globalPos()获取的鼠标位置是鼠标偏离电脑屏幕左上角(x=0,y=0)的位置
QPoint pt = msEvent->globalPos();
//将绝对位置对应到控件的相对位置
pt = ui.label->mapFromGlobal(pt);
//int变量转QString变量的一个方法是用QString::number函数来转换
QString strXY = "move(x,y)=(" + QString::number(pt.x()) + "," + QString::number(pt.y()) + ")" + "event(x,y)=(" + QString::number(msEvent->pos().x()) + "," + QString::number(msEvent->pos().y()) + ")";
ui.statusBar->showMessage(strXY);
return true;
}
else if (msEvent->type() == QEvent::MouseButtonPress)
{
if (msEvent->buttons() == Qt::LeftButton)
{
//由pos()获取的位置是主窗口(widget窗口)左上角(边框的左上角,外左上角)相对于电脑屏幕的左上角(x=0,y=0)偏移位置
QPoint pt = msEvent->pos();
QSize lbSize = ui.label->size();
QString strRate;
int inBubble = 0;
const QString strXY = "(" + QString::number(pt.x()) + "," + QString::number(pt.y()) + ")";
// 窗口坐标转换图片坐标
Point2f srcPt;
srcPt = Point2f(pt.x()*srcSize.width()*1.0 / lbSize.width(), pt.y()*srcSize.height()*1.0 / lbSize.height());
for (int i = 0; i < solderjointcontours.size(); i++)
{
if (pointPolygonTest(solderjointcontours[i], srcPt, false) == 1)
{
strRate = QString::number(contourArea(solderjointcontours[i]));
inBubble = 1;
break;
}
}
if (inBubble == 0)
{
strRate = "";
}
QLabel* posLabel = new QLabel(this);
posLabel->setStyleSheet("color:blue");
posLabel->setGeometry(pt.x(), pt.y() + 10, 55, 10);
posLabel->setText(strRate);
posLabel->show();
ui.statusBar->showMessage(strRate);
return true;
}
else if (msEvent->buttons() == Qt::RightButton)
{
QList<QLabel*> lbs = this->findChildren<QLabel*>();
foreach(QLabel* lbTmp, lbs)
{
if (lbTmp != ui.label)
delete lbTmp;
}
}
}
}
return QMainWindow::eventFilter(obj, evt);
}