地产网站建设案例,网页设计与制作课程标准中职,温州网站建设wmwl,网页设计模板素材简单本章要实现的整体效果如下#xff1a; QEvent::MouseButtonPress
鼠标按下时#xff0c;触发该事件#xff0c;它对应的子类是 QMouseEvent
QEvent::MouseMove
鼠标移动时#xff0c;触发该事件#xff0c;它对应的子类是 QMouseEvent
QEvent::MouseButtonRel…本章要实现的整体效果如下 QEvent::MouseButtonPress
鼠标按下时触发该事件它对应的子类是 QMouseEvent
QEvent::MouseMove
鼠标移动时触发该事件它对应的子类是 QMouseEvent
QEvent::MouseButtonRelease
鼠标释放时触发该事件它对应的子类是 QMouseEvent 本节通过两个案例来讲解这 3 个事件
按下、移动、释放事件的基本使用拖动一个标签使之移动位置 1. 按下、移动、释放事件的基本使用
同样使用上一节自定义的标签 LabelX来进行讲解
1.1 鼠标按下、释放事件
首先来到 labelx.h声明这 3 个函数
class LabelX : public QLabel
{
protected:void mousePressEvent(QMouseEvent* ev);void mouseReleaseEvent(QMouseEvent* ev);void mouseMoveEvent(QMouseEvent* ev);
};然后来到 labelx.cpp 实现这 3 个函数
void LabelX::mousePressEvent(QMouseEvent* ev)
{// qDebug() mousePressEvent: ev-button() ev-pos() ev-globalPos();if ( ev-button() Qt::LeftButton ) {qDebug() 左键按下: x ev-x() , y ev-y();}
}void LabelX::mouseReleaseEvent(QMouseEvent* ev)
{// qDebug() mouseReleaseEvent: ev-button() ev-pos() ev-globalPos();if ( ev-button() Qt::LeftButton ) {qDebug() 左键释放: x ev-x() , y ev-y();}
}void LabelX::mouseMoveEvent(QMouseEvent* ev)
{
}最后来到 press_move_release_widget.cpp在构造函数中添加 LabelX 控件如下
#include labelx.hPressMoveReleaseWidget::PressMoveReleaseWidget(QWidget* parent) : QWidget{parent}
{QVBoxLayout* verticalLayout new QVBoxLayout(this);verticalLayout-setSpacing(0);verticalLayout-setContentsMargins(0, 0, 0, 0);// 1. 添加一个自定义的标签 LabelXLabelX* lblX new LabelX(this);lblX-setText();lblX-setFrameShape(QFrame::Box);lblX-setFixedHeight(50);lblX-setAlignment(Qt::AlignCenter);lblX-setStyleSheet(background-color: blue;color: white;font-size: 25px);verticalLayout-addWidget(lblX);
}此时运行程序在标签上点击时就会在控制台打印按下还是释放并显示点击的位置 1.2 鼠标移动事件
鼠标移动与鼠标按下和释放在判断按键时有些许不同
如果 mouseMoveEvent 实现如下
void LabelX::mouseMoveEvent(QMouseEvent* ev)
{qDebug() mouseMoveEvent: ev-button() ev-pos() ev-globalPos();
}运行结果如下 我明明按下的是左键但是打印的却是没有按键按下
因为此时不能使用 ev-button()而是要使用 ev-buttons()如下
void LabelX::mouseMoveEvent(QMouseEvent* ev)
{// 而是要用buttons()方法qDebug() mouseMoveEvent: ev-buttons() ev-pos() ev-globalPos();
}此时就可以正确打印了如下 可见刚开始移动只按左键移动过程中又按下了右键也是可以识别到的。
在移动过程中判断有左键按下的代码如下
void LabelX::mouseMoveEvent(QMouseEvent* ev)
{if ( ev-buttons() Qt::LeftButton ) {qDebug() 左键移动中: x ev-x() , y ev-y();}
}这样鼠标按下、移动、释放的整体效果如下 1.3 鼠标跟踪
以上需要鼠标保持按下的状态下系统才会调用 mouseMoveEvent实际工作中往往有这么一种需求
鼠标悬浮在控件上而不是按下就触发 mouseMoveEvent 事件这怎么实现呢
答案设置鼠标跟踪默认情况下鼠标跟踪是关闭的需要开启 首先来到 labelx.cpp 中设置标签使能鼠标跟踪如下
LabelX::LabelX(QWidget* parent) : QLabel{parent}
{this-setMouseTracking(true);
}然后在 mouseMoveEvent 中添加打印如下
void LabelX::mouseMoveEvent(QMouseEvent* ev)
{qDebug() mouseMoveEvent: ev-buttons() ev-pos() ev-globalPos();if ( ev-buttons() Qt::LeftButton ) {qDebug() 左键移动中: x ev-x() , y ev-y();}
}此时在标签上悬浮移动时也可以跟踪到鼠标如下 2. 鼠标事件移动标签
接下来实现一个小案例拖动标签来移动标签的位置
2.1 界面上添加标签
首先在 press_move_release_widget.h 中添加成员变量
#include QLabelclass PressMoveReleaseWidget : public QWidget
{
private:QLabel* lbl;QWidget* widget;
};在 QLable 外边套一层 QWidget是为了让标签在这个 widget 范围内移动 然后在 press_move_release_widget.cpp 的构造中添加一个标签
PressMoveReleaseWidget::PressMoveReleaseWidget(QWidget* parent) : QWidget{parent}
{// ...// 2. 添加一个 QLabelwidget new QWidget(this);lbl new QLabel(widget);lbl-setText();lbl-setFrameShape(QFrame::Box);lbl-setFixedSize(100, 100);lbl-setStyleSheet(background-color: red;);verticalLayout-addWidget(widget);
}此时运行效果如下 2.2 为 QLabel 安装事件过滤器
PressMoveReleaseWidget::PressMoveReleaseWidget(QWidget* parent) : QWidget{parent}
{// ...lbl-installEventFilter(this);
}2.3 重写 eventFilter() 函数
重写当前窗口的 eventFilter() 函数
首先在 press_move_release_widget.h 文件中声明该函数
同时声明记录窗口位置和鼠标按下位置的变量如下
class PressMoveReleaseWidget : public QWidget
{
protected:bool eventFilter(QObject* watched, QEvent* event);private:QPoint pressPos;QPoint wndPos;
};然后在 press_move_release_widget.cpp 文件中实现该函数如下
#include QEvent
#include QMouseEvent
#include QDebug
bool PressMoveReleaseWidget::eventFilter(QObject* watched, QEvent* event)
{if ( watched ! lbl ) {return QWidget::eventFilter(watched, event);}if ( event-type() QEvent::MouseButtonPress ) {qDebug() MouseButtonPress;QMouseEvent* mouseEvent static_castQMouseEvent*(event);pressPos mouseEvent-globalPos();wndPos lbl-pos();qDebug() wndPos;} else if ( event-type() QEvent::MouseMove ) {qDebug() MouseMove;QMouseEvent* mouseEvent static_castQMouseEvent*(event);QPoint dstPos wndPos (mouseEvent-globalPos() - pressPos);lbl-move(dstPos);// 超出了最左边if ( lbl-pos().x() 0 ) {lbl-move(0, dstPos.y());}// 超出了最右边if ( lbl-pos().x() widget-width() - lbl-width() ) {lbl-move(widget-width() - lbl-width(), dstPos.y());}// 超出了最上边if ( lbl-pos().y() 0 ) {lbl-move(dstPos.x(), 0);}// 超出了最下边if ( lbl-pos().y() widget-height() - lbl-height() ) {lbl-move(dstPos.x(), widget-height() - lbl-height());}} else if ( event-type() QEvent::MouseButtonRelease ) {qDebug() MouseButtonRelease;}
}这里有些实现细节说明如下
如果不是 lbl 的事件直接调用父类处理 return QWidget::eventFilter(watched, event)在鼠标按下时记录 lbl 的位置和鼠标按下位置作为窗口移动时的参考当 lbl 超出 widget 边界时让它等于边界值 此时就可以通过鼠标拖动标签在 widget 范围内移动了如下