当前位置: 首页 > news >正文

济南网站优化推广公司电话广州推动优化防控措施落地

济南网站优化推广公司电话,广州推动优化防控措施落地,西昌市规划建设局网站,自己做挖矿网站目录 事件分发函数 无边框窗口拖动 自定义事件 发送事件的函数 自定义事件 系统定义的事件号 自定义事件号 自定义事件类 发送和处理事件 sendEvent与postEvent的区别 栈区对象 堆区对象 事件传播机制 事件传播的过程 事件传播到父组件 鼠标单击事件与按钮单击信…

目录

事件分发函数

无边框窗口拖动

自定义事件

发送事件的函数

自定义事件

系统定义的事件号

自定义事件号

自定义事件类

发送和处理事件

sendEvent与postEvent的区别

栈区对象

堆区对象

事件传播机制

事件传播的过程

事件传播到父组件

鼠标单击事件与按钮单击信号的关联

事件过滤

无边框窗口拖动(事件过滤器实现)

事件跟信号的区别


事件分发函数

传递事件的通常方式是调用虚函数。例如,QMouseEvent通过调用QWidget::mousePressEvent()来传递。这个虚函数负责进行适当的响应,通常是处理鼠标点击,并发出对应的信号。如果在虚函数的实现中不执行所有必要的工作,则可能需要调用基类的实现。

如果希望替换基类的事件处理函数,则必须自己实现所有内容。但是,如果您只想扩展基类的功能,那么您可以实现您想要的功能,并调用基类来获得您不想处理的任何情况的默认行为。

有时,没有这样一个特定于事件的函数,或者特定于事件的函数是不够的。最常见的例子是按Tab键。通常情况下,QWidget会拦截这些来移动键盘焦点,但也有一些小部件本身需要Tab键。

这些对象可以重新实现QObject::event()(通用事件处理程序),并在通常处理之前或之后执行它们的事件处理,或者它们可以完全替换函数。一个非常不寻常的小部件既解释Tab又具有特定于应用程序的自定义事件,它可能包含以下event()函数:

bool Widget::event(QEvent* ev)override
{//如果是按键按下事件if (ev->type() == QEvent::Type::KeyPress){QKeyEvent* ke = static_cast<QKeyEvent*>(ev);if (ke->key() == Qt::Key::Key_Tab){//对tab键按下进行处理qInfo() << "处理 tab 按键...";return true;    //返回true表示此事件已经处理了,不会继续传播}}// 调用父类实现处理其它的事件return QWidget::event(ev);
}

注意:对于所有未处理的情况,仍然调用QWidget::event(),并且返回值指示是否处理了事件;true值防止事件被发送到其他对象。返回true表示此事件已经处理了,不需要再处理了。

无边框窗口拖动

使用事件分发函数实现无边框窗口的拖动

bool event(QEvent* ev)override
{if (ev->type() == QEvent::MouseButtonPress){auto me = static_cast<QMouseEvent*>(ev);pressPos = me->pos();return true;}else if (ev->type() == QEvent::MouseMove){auto me = static_cast<QMouseEvent*>(ev);//如果鼠标左键是按下的if(me->buttons() & Qt::MouseButton::LeftButton)this->move(me->globalPosition().toPoint() - pressPos);return true;}return QWidget::event(ev);
}

自定义事件

发送事件的函数

许多应用程序都希望创建和发送它们自己的事件。通过构造合适的事件对象并使用QCoreApplication::sendEvent()和QCoreApplication::postEvent()发送事件,您可以以与Qt自己的事件循环完全相同的方式发送事件。

sendEvent()立即处理事件。当它返回时,事件过滤器和/或对象本身已经处理了该事件。对于许多事件类,都有一个名为isAccepted()的函数,它告诉您事件是被最后一个调用的处理程序接受还是拒绝的。

postEvent()将事件发送到队列中,以便稍后进行分派。下次Qt的主事件循环运行时,它会分发所有发布的事件,并进行一些优化。例如,如果有几个调整大小事件,它们将被压缩为一个。同样适用于绘制事件:QWidget::update()调用postEvent(),它通过避免多次重绘来消除闪烁并提高速度。

自定义事件

要创建自定义类型的事件,需要定义一个事件号,该事件号必须大于等于QEvent::User,并且可能需要继承QEvent的子类,以便传递关于自定义事件的特定信息。有关更多详细信息,请参阅QEvent文档。

系统定义的事件号

QEvent::Type 这个枚举类型定义了Qt中有效的事件类型。事件类型和每个类型的专门类如下:

常量值(value)描述
QEvent::None0不是一个事件
QEvent::ActionAdded114一个新 action 被添加(QActionEvent)
QEvent::ActionChanged113一个 action 被改变(QActionEvent)
QEvent::ActionRemoved115一个 action 被移除(QActionEvent)
QEvent::ActivationChange99Widget 的顶层窗口激活状态发生了变化
QEvent::ApplicationActivate121这个枚举已被弃用,使用 ApplicationStateChange 代替
QEvent::ApplicationActivatedApplicationActivate这个枚举已被弃用,使用 ApplicationStateChange 代替
QEvent::ApplicationDeactivate122这个枚举已被弃用,使用 ApplicationStateChange 代替
QEvent::ApplicationFontChange36应用程序的默认字体发生了变化
QEvent::ApplicationLayoutDirectionChange37应用程序的默认布局方向发生了变化
QEvent::ApplicationPaletteChange38应用程序的默认调色板发生了变化
QEvent::ApplicationStateChange214应用程序的状态发生了变化
QEvent::ApplicationWindowIconChange35应用程序的图标发生了变化
QEvent::ChildAdded68一个对象获得孩子(QChildEvent)
QEvent::ChildPolished69一个部件的孩子被抛光(QChildEvent)
QEvent::ChildRemoved71一个对象时区孩子(QChildEvent)
QEvent::Clipboard40剪贴板的内容发生改变
QEvent::Close19Widget 被关闭(QCloseEvent)
QEvent::CloseSoftwareInputPanel200一个部件要关闭软件输入面板(SIP)
QEvent::ContentsRectChange178部件内容区域的外边距发生改变
QEvent::ContextMenu82上下文弹出菜单(QContextMenuEvent)
QEvent::CursorChange183部件的鼠标发生改变
QEvent::DeferredDelete52对象被清除后将被删除(QDeferredDeleteEvent)
QEvent::DragEnter60在拖放操作期间鼠标进入窗口部件(QDragEnterEvent)
QEvent::DragLeave62在拖放操作期间鼠标离开窗口部件(QDragLeaveEvent)
QEvent::DragMove61拖放操作正在进行(QDragMoveEvent)
QEvent::Drop63拖放操作完成(QDropEvent)
QEvent::DynamicPropertyChange170动态属性已添加、更改或从对象中删除
QEvent::EnabledChange98部件的 enabled 状态已更改
QEvent::Enter10鼠标进入部件的边界(QEnterEvent)
QEvent::EnterEditFocus150编辑部件获得焦点进行编辑,必须定义 QT_KEYPAD_NAVIGATION
QEvent::EnterWhatsThisMode124当应用程序进入“What’s This?”模式,发送到 toplevel 顶层部件
QEvent::Expose206当其屏幕上的内容无效,发送到窗口,并需要从后台存储刷新
QEvent::FileOpen116文件打开请求(QFileOpenEvent)
QEvent::FocusIn8部件或窗口获得键盘焦点(QFocusEvent)
QEvent::FocusOut9部件或窗口失去键盘焦点(QFocusEvent)
QEvent::FocusAboutToChange23部件或窗口焦点即将改变(QFocusEvent)
QEvent::FontChange97部件的字体发生改变
QEvent::Gesture198触发了一个手势(QGestureEvent)
QEvent::GestureOverride202触发了手势覆盖(QGestureEvent)
QEvent::GrabKeyboard188Item 获得键盘抓取(仅限 QGraphicsItem)
QEvent::GrabMouse186项目获得鼠标抓取(仅限 QGraphicsItem)
QEvent::GraphicsSceneContextMenu159在图形场景上的上下文弹出菜单(QGraphicsScene ContextMenuEvent)
QEvent::GraphicsSceneDragEnter164在拖放操作期间,鼠标进入图形场景(QGraphicsSceneDragDropEvent)
QEvent::GraphicsSceneDragLeave166在拖放操作期间鼠标离开图形场景(QGraphicsSceneDragDropEvent)
QEvent::GraphicsSceneDragMove165在场景上正在进行拖放操作(QGraphicsSceneDragDropEvent)
QEvent::GraphicsSceneDrop167在场景上完成拖放操作(QGraphicsSceneDragDropEvent)
QEvent::GraphicsSceneHelp163用户请求图形场景的帮助(QHelpEvent)
QEvent::GraphicsSceneHoverEnter160鼠标进入图形场景中的悬停项(QGraphicsSceneHoverEvent)
QEvent::GraphicsSceneHoverLeave162鼠标离开图形场景中一个悬停项(QGraphicsSceneHoverEvent)
QEvent::GraphicsSceneHoverMove161鼠标在图形场景中的悬停项内移动(QGraphicsSceneHoverEvent)
QEvent::GraphicsSceneMouseDoubleClick158鼠标在图形场景中再次按下(双击)(QGraphicsSceneMouseEvent)
QEvent::GraphicsSceneMouseMove155鼠标在图形场景中移动(QGraphicsSceneMouseEvent)
QEvent::GraphicsSceneMousePress156鼠标在图形场景中按下(QGraphicsSceneMouseEvent)
QEvent::GraphicsSceneMouseRelease157鼠标在图形场景中释放(QGraphicsSceneMouseEvent)
QEvent::GraphicsSceneMove182部件被移动(QGraphicsSceneMoveEvent)
QEvent::GraphicsSceneResize181部件已调整大小(QGraphicsSceneResizeEvent)
QEvent::GraphicsSceneWheel168鼠标滚轮在图形场景中滚动(QGraphicsSceneWheelEvent)
QEvent::Hide18部件被隐藏(QHideEvent)
QEvent::HideToParent27子部件被隐藏(QHideEvent)
QEvent::HoverEnter127鼠标进入悬停部件(QHoverEvent)
QEvent::HoverLeave128鼠标留离开悬停部件(QHoverEvent)
QEvent::HoverMove129鼠标在悬停部件内移动(QHoverEvent)
QEvent::IconDrag96窗口的主图标被拖走(QIconDragEvent)
QEvent::IconTextChange101部件的图标文本发生改变(已弃用)
QEvent::InputMethod83正在使用输入法(QInputMethodEvent)
QEvent::InputMethodQuery207输入法查询事件(QInputMethodQueryEvent)
QEvent::KeyboardLayoutChange169键盘布局已更改
QEvent::KeyPress6键盘按下(QKeyEvent)
QEvent::KeyRelease7键盘释放(QKeyEvent)
QEvent::LanguageChange89应用程序翻译发生改变
QEvent::LayoutDirectionChange90布局的方向发生改变
QEvent::LayoutRequest76部件的布局需要重做
QEvent::Leave11鼠标离开部件的边界
QEvent::LeaveEditFocus151编辑部件失去编辑的焦点,必须定义 QT_KEYPAD_NAVIGATION
QEvent::LeaveWhatsThisMode125当应用程序离开“What’s This?”模式,发送到顶层部件
QEvent::LocaleChange88系统区域设置发生改变
QEvent::NonClientAreaMouseButtonDblClick176鼠标双击发生在客户端区域外
QEvent::NonClientAreaMouseButtonPress174鼠标按钮按下发生在客户端区域外
QEvent::NonClientAreaMouseButtonRelease175鼠标按钮释放发生在客户端区域外
QEvent::NonClientAreaMouseMove173鼠标移动发生在客户区域外
QEvent::MacSizeChange177用户更改了部件的大小(仅限 OS X)
QEvent::MetaCall43通过 QMetaObject::invokeMethod() 调用异步方法
QEvent::ModifiedChange102部件修改状态发生改变
QEvent::MouseButtonDblClick4鼠标再次按下(QMouseEvent)
QEvent::MouseButtonPress2鼠标按下(QMouseEvent)
QEvent::MouseButtonRelease3鼠标释放(QMouseEvent)
QEvent::MouseMove5鼠标移动(QMouseEvent)
QEvent::MouseTrackingChange109鼠标跟踪状态发生改变
QEvent::Move13部件的位置发生改变(QMoveEvent)
QEvent::NativeGesture197系统检测到手势(QNativeGestureEvent)
QEvent::OrientationChange208屏幕方向发生改变(QScreenOrientationChangeEvent)
QEvent::Paint12需要屏幕更新(QPaintEvent)
QEvent::PaletteChange39部件的调色板发生改变
QEvent::ParentAboutToChange131部件的 parent 将要更改
QEvent::ParentChange21部件的 parent 发生改变
QEvent::PlatformPanel212请求一个特定于平台的面板
QEvent::PlatformSurface217原生平台表面已创建或即将被销毁(QPlatformSurfaceEvent)
QEvent::Polish75部件被抛光
QEvent::PolishRequest74部件应该被抛光
QEvent::QueryWhatsThis123如果部件有“What’s This?”帮助,应该接受事件
QEvent::ReadOnlyChange106部件的 read-only 状态发生改变
QEvent::RequestSoftwareInputPanel199部件想要打开软件输入面板(SIP)
QEvent::Resize14部件的大小发生改变(QResizeEvent)
QEvent::ScrollPrepare204对象需要填充它的几何信息(QScrollPrepareEvent)
QEvent::Scroll205对象需要滚动到提供的位置(QScrollEvent)
QEvent::Shortcut117快捷键处理(QShortcutEvent)
QEvent::ShortcutOverride51按下按键,用于覆盖快捷键(QKeyEvent)
QEvent::Show17部件显示在屏幕上(QShowEvent)
QEvent::ShowToParent26子部件被显示
QEvent::SockAct50Socket 激活,用于实现 QSocketNotifier
QEvent::StateMachineSignal192信号被传递到状态机(QStateMachine::SignalEvent)
QEvent::StateMachineWrapped193事件是一个包装器,用于包含另一个事件(QStateMachine::WrappedEvent)
QEvent::StatusTip112状态提示请求(QStatusTipEvent)
QEvent::StyleChange100部件的样式发生改变
QEvent::TabletMove87Wacom 写字板移动(QTabletEvent)
QEvent::TabletPress92Wacom 写字板按下(QTabletEvent)
QEvent::TabletRelease93Wacom 写字板释放(QTabletEvent)
QEvent::OkRequest94Ok 按钮在装饰前被按下,仅支持 Windows CE
QEvent::TabletEnterProximity171Wacom 写字板进入接近事件(QTabletEvent),发送到 QApplication
QEvent::TabletLeaveProximity172Wacom 写字板离开接近事件(QTabletEvent),发送到 QApplication
QEvent::ThreadChange22对象被移动到另一个线程。这是发送到此对象的最后一个事件在上一个线程中,参见:QObject::moveToThread()
QEvent::Timer1定时器事件(QTimerEvent)
QEvent::ToolBarChange120工具栏按钮在 OS X 上进行切换
QEvent::ToolTip110一个 tooltip 请求(QHelpEvent)
QEvent::ToolTipChange184部件的 tooltip 发生改变
QEvent::TouchBegin194触摸屏或轨迹板事件序列的开始(QTouchEvent)
QEvent::TouchCancel209取消触摸事件序列(QTouchEvent)
QEvent::TouchEnd196触摸事件序列结束(QTouchEvent)
QEvent::TouchUpdate195触摸屏事件(QTouchEvent)
QEvent::UngrabKeyboard189Item 失去键盘抓取(QGraphicsItem)
QEvent::UngrabMouse187Item 失去鼠标抓取(QGraphicsItem、QQuickItem)
QEvent::UpdateLater78部件应该排队在以后重新绘制
QEvent::UpdateRequest77部件应该被重绘
QEvent::WhatsThis111部件应该显示“What’s This”帮助(QHelpEvent)
QEvent::WhatsThisClicked118部件的“What’s This”帮助链接被点击
QEvent::Wheel31鼠标滚轮滚动(QWheelEvent)
QEvent::WinEventAct132发生了 Windows 特定的激活事件
QEvent::WindowActivate24窗口已激活
QEvent::WindowBlocked103窗口被模态对话框阻塞
QEvent::WindowDeactivate25窗户被停用
QEvent::WindowIconChange34窗口的图标发生改变
QEvent::WindowStateChange105窗口的状态(最小化、最大化或全屏)发生改变(QWindowStateChangeEvent)
QEvent::WindowTitleChange33窗口的标题发生改变
QEvent::WindowUnblocked104一个模态对话框退出后,窗口将不被阻塞
QEvent::WinIdChange203本地窗口的系统标识符发生改变
QEvent::ZOrderChange126部件的 z 值发生了改变,该事件不会发送给顶层窗口

用户事件的值应该介于 QEvent::User 和 QEvent::MaxUser之间。

常量描述
QEvent::User1000用户定义的事件
QEvent::MaxUser65535最后的用户事件 ID

为方便起见,可以使用 [static] int QEvent::registerEventType(int *hint* = -1) 函数来注册和存储一个自定义事件类型,这样做会避免意外地重用一个自定义事件类型。

自定义事件号

enum EventType 
{NumberEvent = QEvent::Type::User
};

自定义事件类

// 自定义事件类
class NumberChangeEvent : public QEvent
{
public:NumberChangeEvent(int number): QEvent(QEvent::Type(NumberEvent)), m_number(number){}~NumberChangeEvent(){qInfo() << __FUNCTION__;}qint32 getNumber(){ return m_number; }
private:int m_number;
};

发送和处理事件

#include <QApplication>
#include <QWidget>
#include <QEvent>
#include <QPushButton>// 自定义事件类型
enum EventType
{NumberEvent = QEvent::Type::User
};// 自定义事件类
class NumberChangeEvent : public QEvent
{
public:NumberChangeEvent(int number): QEvent(QEvent::Type(NumberEvent)), m_number(number){}~NumberChangeEvent(){qInfo() << __FUNCTION__;}qint32 getNumber(){ return m_number; }
private:int m_number;
};// 自定义事件处理
class Widget : public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr):QWidget(parent){resize(640,480);m_btn = new QPushButton("发送自定义事件", this);// 点击按钮发送事件connect(m_btn, &QPushButton::clicked, this, [=](){static int i = 0;NumberChangeEvent ne(i++);//qApp->sendEvent(this, &ne);QApplication::sendEvent(this, &ne);});}~Widget(){}
protected:bool event(QEvent* ev) override{if(ev->type() == QEvent::Type(NumberEvent)){auto nev = static_cast<NumberChangeEvent*>(ev);qInfo() << "Number: " << nev->getNumber();}return QWidget::event(ev);}
private:QPushButton* m_btn;
};int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}
#include "main.moc"

除了使用事件分发函数event处理自定义事件外,也可以使用customEvent处理自定义事件,它是专门用来接收自定义事件。

void customEvent(QEvent* ev) override
{if(ev->type() == EventType::NumberEvent){auto nev = static_cast<NumberChangeEvent*>(ev);qInfo() << "Number: " << nev->getNumber();}
}

sendEvent与postEvent的区别

使用栈区对象与堆区对象分别对两种发送方式进行测试

栈区对象

connect(m_btn, &QPushButton::clicked, this, [=](){NumberChangeEvent ne1(1);QApplication::sendEvent(this, &ne1);NumberChangeEvent ne2(1);QApplication::postEvent(this, &ne2);
});

当使用postEvent发送栈区事件对象时会直接引发中断,因为postEvent是将事件放入事件队列中稍后处理,栈区事件对象出作用域后内存就会被释放,我认为这是引发中断的原因。而使用sendEvent发送栈区事件对象不会中断,内存也会自己释放(出作用域后释放)。

堆区对象

当使用sendEvent发送堆区对象后,内存不会被自动释放,需要手动释放。而使用postEvent发送堆区事件对象内存会自动释放,不必手动释放。

因此,当使用栈区对象时只能使用sendEvent发送事件,使用堆区对象时,使用sendEvent发送事件之后需要手动释放事件对象内存,使用postEvent发送事件会自动释放内存。另外,使用postEvent发送事件时可以设置事件的优先级,让发送的事件被优先处理。

事件传播机制

事件传播的过程

Qt的事件产生之后,不是直接传递给了对象的,需要经过一系列的过程。

  1. 事件首先由Qt的ServerApplication去接收来自于外部或内部的一些行为,鼠标点击,键盘输入,时钟事件等,分析并决定送往对应的对象去处理(内部管理机制),最后会调用[virtual] bool QCoreApplication::notify ( QObject * receiver, QEvent * event ) 去处理,当然这个是虚函数,你可以在子类去重新实现它 。

  2. 在notify(…)中,在发给对应的接收者前,会先把消息送给QApplication。所以如果想在你界面的Widget前先处理那些事 件,那么你可以给QApplication对象installEventFilter,然后在对应的eventFilter()里先把这些事件都给过一 遍,然后你可以过滤一些不必要事件。

  3. 如果QApplication没有处理那些事件,然后就是交给事件接收对象了。在这个对象接收前,也可以为这对象加一个事件过滤器,同样是 installEventFilter。

  4. 如果eventFilter没有过滤某些事件,那么就会将事件交给接收者的event()函数(你可以根据不同类型的事件尽情处理),如果event事件在接受者处理后,也不会上传给父类的event,否则会上传进入父类的event。

  5. 默认event()函数根据事件类型会调用不同的事件处理函数,类似mousePressEvent(),keyPressEvent()去分别处理他们。

事件传播到父组件

当控件忽略事件时,事件会继续往上传播,这里的传播是指传播给父组件

  • QEvent有 accept()函数 和ignore()函数:

    • accept():本组件处理该事件,这个事件就不会被继续传播给其父组件;

    • ignore():本组件不想要处理这个事件,这个事件会被继续传播给其父组件;

    • 值得注意的是所有的事件默认都是接受的(即不会传递到父组件)

  • 忽略和接受案例

 当默认接受事件时,在本组件处理之后,事件不会传递到父组件mousePressEvent处理。 

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>class Button : public QPushButton
{
public:Button(const QString& text,QWidget* parent = nullptr):QPushButton(text,parent){}void mousePressEvent(QMouseEvent* ev)override{qInfo() << __FUNCTION__;//默认是接受事件的,父组件不会收到鼠标点击事件ev->accept();//如果忽略事件,父组件就会收到鼠标点击事件//ev->ignore();}
};class Widget : public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr):QWidget(parent){resize(640,480);Button* btn = new Button("text", this);}~Widget(){}
protected:void mousePressEvent(QMouseEvent* ev)override{qInfo() << __FUNCTION__;}
};int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}
#include "main.moc"

 当忽略事件时,在本组件处理之后,事件会被传递到父组件mousePressEvent处理。

class Button : public QPushButton
{
public:Button(const QString& text,QWidget* parent = nullptr):QPushButton(text,parent){}void mousePressEvent(QMouseEvent* ev)override{qInfo() << __FUNCTION__;//默认是接受事件的,父组件不会收到鼠标点击事件//ev->accept();//如果忽略事件,父组件就会收到鼠标点击事件ev->ignore();}
};

 

  • event事件分发函数返回值的作用
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>class Button : public QPushButton
{
public:Button(const QString& text,QWidget* parent = nullptr):QPushButton(text,parent){}bool event(QEvent* ev)override{if (ev->type() == QEvent::Type::MouseButtonPress){qInfo() << __FUNCTION__;return false;	//返回false,表示我没有处理这个事件,可以传递给父组件//return true;	//返回true,表示我处理了这个事件,不再继续传递了}return QPushButton::event(ev);}
};class Widget : public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr):QWidget(parent){resize(640,480);Button* btn = new Button("text", this);Q_UNUSED(btn)}~Widget(){}
protected:bool event(QEvent* ev)override{if (ev->type() == QEvent::Type::MouseButtonPress){qInfo() << __FUNCTION__;}return QWidget::event(ev);}
};int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}
#include "main.moc"

事件分发函数event返回false,表示本组件没有处理这个事件,事件会被传递到父组件处理,返回true则表示本组件处理了这个事件,不需要再让父组件处理了。

鼠标单击事件与按钮单击信号的关联

class Button : public QPushButton
{
public:Button(const QString& text,QWidget* parent = nullptr):QPushButton(text,parent){}void mousePressEvent(QMouseEvent* ev) override{//return QPushButton::mousePressEvent(ev);}
};Button* btn = new Button("text", this);
connect(btn, &Button::clicked, this, [](){qInfo() << "鼠标单击";
});

 要想触发鼠标点击的信号与槽就必须处理鼠标按下事件

void mousePressEvent(QMouseEvent* ev) override
{return QPushButton::mousePressEvent(ev);
}

事件过滤

有的时候,对象需要查看(可能还需要拦截)传递给另一个对象的事件。例如,对话框通常想要过滤一些小部件的按键;例如,修改返回键处理。

QObject::installEventFilter()函数通过设置一个事件过滤器来实现这一点,使指定的过滤器对象在其QObject::eventFilter()函数中接收目标对象的事件。事件过滤器在目标对象处理事件之前处理事件,允许它根据需要检查和丢弃事件。可以使用QObject::removeEventFilter()函数删除现有的事件过滤器。

当调用过滤器对象的eventFilter()实现时,它可以接受或拒绝事件,并允许或拒绝对事件的进一步处理。如果所有事件过滤器都允许对事件进行进一步处理(每个返回false),则将事件发送到目标对象本身。如果其中一个停止处理(通过返回true),目标和任何后面的事件过滤器都不会看到事件。

无边框窗口拖动(事件过滤器实现)

class Widget : public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr):QWidget(parent){resize(640, 480);setWindowFlag(Qt::WindowType::FramelessWindowHint);setMouseTracking(true);// 安装事件过滤器this->installEventFilter(this);}bool eventFilter(QObject* object, QEvent* ev)override{auto w = qobject_cast<QWidget*>(object);if (!w)return false;if (ev->type() == QEvent::MouseButtonPress){auto me = static_cast<QMouseEvent*>(ev);pressPos = me->pos();return true;}else if (ev->type() == QEvent::MouseMove){auto me = static_cast<QMouseEvent*>(ev);if (me->buttons() & Qt::MouseButton::LeftButton)w->move(me->globalPosition().toPoint() - pressPos);// 已经处理了,不需要再处理MouseMoveEvent事件了return true;}return QObject::eventFilter(object, ev);}
private:QPoint pressPos;
};

在自己类里面重写eventFilter来过滤事件,但是如果我有很多个无边框窗口,都要实现移动,这个方法就不太方便了。可以先写一个拖拽控件的过滤器对象,然后哪儿需要使用,就直接加载事件过滤器对象即可。

// 无边框窗口拖拽的事件过滤器对象
class DragWidgetFilter :public QObject
{
public:DragWidgetFilter(QObject* parent = nullptr):QObject(parent){}bool eventFilter(QObject* object,QEvent*ev)override{auto w = qobject_cast<QWidget*>(object);if (!w)return false;if (ev->type() == QEvent::MouseButtonPress){auto me = static_cast<QMouseEvent*>(ev);pressPos = me->pos();}else if (ev->type() == QEvent::MouseMove){auto me = static_cast<QMouseEvent*>(ev);if (me->buttons() & Qt::MouseButton::LeftButton)w->move(me->globalPosition().toPoint() - pressPos);}return QObject::eventFilter(object,ev);}
private:QPoint pressPos;
};class Widget : public QWidget
{Q_OBJECT
public:Widget(QWidget* parent = nullptr):QWidget(parent){resize(640, 480);setWindowFlag(Qt::WindowType::FramelessWindowHint);setMouseTracking(true);// 使用事件过滤器对象加载事件过滤器this->installEventFilter(new DragWidgetFilter(this));}
}

事件跟信号的区别

事件(QEvent)信号(SIGNAL)
与QObject的关系由具体对象进行处理由具体对象主动产生
对程序的影响改写事件处理函数可能导致程序行为发生改变信号是否存在对应的槽函数不会改变程序行为
两者的联系一般而言,信号在具体的事件处理函数中产生

文章转载自:
http://wanjiafuror.nLcw.cn
http://wanjiamigod.nLcw.cn
http://wanjiachivalric.nLcw.cn
http://wanjiaprewriting.nLcw.cn
http://wanjiatractor.nLcw.cn
http://wanjiacardplayer.nLcw.cn
http://wanjiaquerimonious.nLcw.cn
http://wanjiapoisonwood.nLcw.cn
http://wanjiaagronomy.nLcw.cn
http://wanjiatidewater.nLcw.cn
http://wanjiasaltant.nLcw.cn
http://wanjiaisopentyl.nLcw.cn
http://wanjiaseeable.nLcw.cn
http://wanjiapippip.nLcw.cn
http://wanjiawaterworn.nLcw.cn
http://wanjiadumbwaiter.nLcw.cn
http://wanjiapseudoclassic.nLcw.cn
http://wanjiagagger.nLcw.cn
http://wanjiaunquestioned.nLcw.cn
http://wanjiasoroban.nLcw.cn
http://wanjiafin.nLcw.cn
http://wanjiachiasmatypy.nLcw.cn
http://wanjiasubah.nLcw.cn
http://wanjiaasunder.nLcw.cn
http://wanjiapygmyism.nLcw.cn
http://wanjiaaviva.nLcw.cn
http://wanjiaomnipresence.nLcw.cn
http://wanjiatit.nLcw.cn
http://wanjiasmoothness.nLcw.cn
http://wanjiabeautify.nLcw.cn
http://wanjiaexpressly.nLcw.cn
http://wanjiaactinomycotic.nLcw.cn
http://wanjiabagasse.nLcw.cn
http://wanjiamattins.nLcw.cn
http://wanjiafucoid.nLcw.cn
http://wanjiasiphonophore.nLcw.cn
http://wanjiaspeedboat.nLcw.cn
http://wanjiaserological.nLcw.cn
http://wanjiacuboid.nLcw.cn
http://wanjiaaureate.nLcw.cn
http://wanjiahotliner.nLcw.cn
http://wanjiadas.nLcw.cn
http://wanjiasupertransuranic.nLcw.cn
http://wanjiabulwark.nLcw.cn
http://wanjiajejunely.nLcw.cn
http://wanjiainseparability.nLcw.cn
http://wanjiaslantingwise.nLcw.cn
http://wanjiamicrovascular.nLcw.cn
http://wanjiaregality.nLcw.cn
http://wanjiaragpicker.nLcw.cn
http://wanjiarasp.nLcw.cn
http://wanjiadolorology.nLcw.cn
http://wanjiahomeplace.nLcw.cn
http://wanjiatramontana.nLcw.cn
http://wanjiainfantile.nLcw.cn
http://wanjiaschvartze.nLcw.cn
http://wanjiamow.nLcw.cn
http://wanjiadogtooth.nLcw.cn
http://wanjiameetly.nLcw.cn
http://wanjiabreeks.nLcw.cn
http://wanjiaeloquence.nLcw.cn
http://wanjiatashkend.nLcw.cn
http://wanjiavaporizer.nLcw.cn
http://wanjiaexcursion.nLcw.cn
http://wanjiajammer.nLcw.cn
http://wanjiaenormous.nLcw.cn
http://wanjiauntransferable.nLcw.cn
http://wanjiaseparably.nLcw.cn
http://wanjiashirk.nLcw.cn
http://wanjiafold.nLcw.cn
http://wanjiaoutlay.nLcw.cn
http://wanjiaaep.nLcw.cn
http://wanjiamutarotation.nLcw.cn
http://wanjiaraob.nLcw.cn
http://wanjiathrottle.nLcw.cn
http://wanjiaafterclap.nLcw.cn
http://wanjiaautocross.nLcw.cn
http://wanjiacoeducational.nLcw.cn
http://wanjiasputa.nLcw.cn
http://wanjiafunabout.nLcw.cn
http://www.15wanjia.com/news/127354.html

相关文章:

  • 做外贸开店用哪个网站定制网站建设推广服务
  • 免费网站设计培训班新网站快速收录
  • 孟村做网站嘉兴网站建设
  • 化妆品商城网站建设51外链代发网
  • 做网页兼职网站排名优化关键词公司
  • 北京保安公司seo的工具有哪些
  • 100个最佳市场营销案例北京seo
  • 朝阳区网站开发公司产品经理培训哪个机构好
  • 英文购物网站模板下载游戏推广怎么快速拉人
  • 做网站常用的cssseo站长优化工具
  • 手机网站打开速度网址搜索引擎入口
  • 私人彩票网站做几年牢湖南中高风险地区
  • 网站需要网监备案美工培训
  • 怎样设计自己的网站短视频seo排名系统
  • wordpress 环境搭建关键词优化包含
  • 做网站运营有趣吗怎样做网站推广啊
  • 企业门户网站功能商品推广
  • 专业网站制作技术永久域名查询
  • 网站打开空白 重启iis就好了网络营销服务商有哪些
  • 湖南网站建设公司 尖端磐石网络在哪里找专业推广团队
  • 黄山网站建设方案2022年十大流行语
  • 上海网站建设微信开发深圳seo优化排名
  • html语言做的网站和asp的区别水果店推广营销方案
  • 商城网站建设开发公司网站推广优化教程
  • 本地上海集团网站建设seo搜索引擎优化师
  • 罗岗网站建设公司谷歌google官方网站
  • 湛江做网站哪家好百度提问登陆入口
  • 网站显示乱码怎么办啊关键词优化案例
  • 一条龙平台seo兼职接单平台
  • 上海公司注册查名官网郑州seo技术服务