设计师网站都有哪些,wordpress远程图片,电商网站开发设计方案有哪些,东莞市设计公司目录 事件分发函数
无边框窗口拖动
自定义事件
发送事件的函数
自定义事件
系统定义的事件号
自定义事件号
自定义事件类
发送和处理事件
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_castQKeyEvent*(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_castQMouseEvent*(ev);pressPos me-pos();return true;}else if (ev-type() QEvent::MouseMove){auto me static_castQMouseEvent*(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 被添加QActionEventQEvent::ActionChanged113一个 action 被改变QActionEventQEvent::ActionRemoved115一个 action 被移除QActionEventQEvent::ActivationChange99Widget 的顶层窗口激活状态发生了变化QEvent::ApplicationActivate121这个枚举已被弃用使用 ApplicationStateChange 代替QEvent::ApplicationActivatedApplicationActivate这个枚举已被弃用使用 ApplicationStateChange 代替QEvent::ApplicationDeactivate122这个枚举已被弃用使用 ApplicationStateChange 代替QEvent::ApplicationFontChange36应用程序的默认字体发生了变化QEvent::ApplicationLayoutDirectionChange37应用程序的默认布局方向发生了变化QEvent::ApplicationPaletteChange38应用程序的默认调色板发生了变化QEvent::ApplicationStateChange214应用程序的状态发生了变化QEvent::ApplicationWindowIconChange35应用程序的图标发生了变化QEvent::ChildAdded68一个对象获得孩子QChildEventQEvent::ChildPolished69一个部件的孩子被抛光QChildEventQEvent::ChildRemoved71一个对象时区孩子QChildEventQEvent::Clipboard40剪贴板的内容发生改变QEvent::Close19Widget 被关闭QCloseEventQEvent::CloseSoftwareInputPanel200一个部件要关闭软件输入面板SIPQEvent::ContentsRectChange178部件内容区域的外边距发生改变QEvent::ContextMenu82上下文弹出菜单QContextMenuEventQEvent::CursorChange183部件的鼠标发生改变QEvent::DeferredDelete52对象被清除后将被删除QDeferredDeleteEventQEvent::DragEnter60在拖放操作期间鼠标进入窗口部件QDragEnterEventQEvent::DragLeave62在拖放操作期间鼠标离开窗口部件QDragLeaveEventQEvent::DragMove61拖放操作正在进行QDragMoveEventQEvent::Drop63拖放操作完成QDropEventQEvent::DynamicPropertyChange170动态属性已添加、更改或从对象中删除QEvent::EnabledChange98部件的 enabled 状态已更改QEvent::Enter10鼠标进入部件的边界QEnterEventQEvent::EnterEditFocus150编辑部件获得焦点进行编辑必须定义 QT_KEYPAD_NAVIGATIONQEvent::EnterWhatsThisMode124当应用程序进入“What’s This?”模式发送到 toplevel 顶层部件QEvent::Expose206当其屏幕上的内容无效发送到窗口并需要从后台存储刷新QEvent::FileOpen116文件打开请求QFileOpenEventQEvent::FocusIn8部件或窗口获得键盘焦点QFocusEventQEvent::FocusOut9部件或窗口失去键盘焦点QFocusEventQEvent::FocusAboutToChange23部件或窗口焦点即将改变QFocusEventQEvent::FontChange97部件的字体发生改变QEvent::Gesture198触发了一个手势QGestureEventQEvent::GestureOverride202触发了手势覆盖QGestureEventQEvent::GrabKeyboard188Item 获得键盘抓取仅限 QGraphicsItemQEvent::GrabMouse186项目获得鼠标抓取仅限 QGraphicsItemQEvent::GraphicsSceneContextMenu159在图形场景上的上下文弹出菜单QGraphicsScene ContextMenuEventQEvent::GraphicsSceneDragEnter164在拖放操作期间鼠标进入图形场景QGraphicsSceneDragDropEventQEvent::GraphicsSceneDragLeave166在拖放操作期间鼠标离开图形场景QGraphicsSceneDragDropEventQEvent::GraphicsSceneDragMove165在场景上正在进行拖放操作QGraphicsSceneDragDropEventQEvent::GraphicsSceneDrop167在场景上完成拖放操作QGraphicsSceneDragDropEventQEvent::GraphicsSceneHelp163用户请求图形场景的帮助QHelpEventQEvent::GraphicsSceneHoverEnter160鼠标进入图形场景中的悬停项QGraphicsSceneHoverEventQEvent::GraphicsSceneHoverLeave162鼠标离开图形场景中一个悬停项QGraphicsSceneHoverEventQEvent::GraphicsSceneHoverMove161鼠标在图形场景中的悬停项内移动QGraphicsSceneHoverEventQEvent::GraphicsSceneMouseDoubleClick158鼠标在图形场景中再次按下双击QGraphicsSceneMouseEventQEvent::GraphicsSceneMouseMove155鼠标在图形场景中移动QGraphicsSceneMouseEventQEvent::GraphicsSceneMousePress156鼠标在图形场景中按下QGraphicsSceneMouseEventQEvent::GraphicsSceneMouseRelease157鼠标在图形场景中释放QGraphicsSceneMouseEventQEvent::GraphicsSceneMove182部件被移动QGraphicsSceneMoveEventQEvent::GraphicsSceneResize181部件已调整大小QGraphicsSceneResizeEventQEvent::GraphicsSceneWheel168鼠标滚轮在图形场景中滚动QGraphicsSceneWheelEventQEvent::Hide18部件被隐藏QHideEventQEvent::HideToParent27子部件被隐藏QHideEventQEvent::HoverEnter127鼠标进入悬停部件QHoverEventQEvent::HoverLeave128鼠标留离开悬停部件QHoverEventQEvent::HoverMove129鼠标在悬停部件内移动QHoverEventQEvent::IconDrag96窗口的主图标被拖走QIconDragEventQEvent::IconTextChange101部件的图标文本发生改变已弃用QEvent::InputMethod83正在使用输入法QInputMethodEventQEvent::InputMethodQuery207输入法查询事件QInputMethodQueryEventQEvent::KeyboardLayoutChange169键盘布局已更改QEvent::KeyPress6键盘按下QKeyEventQEvent::KeyRelease7键盘释放QKeyEventQEvent::LanguageChange89应用程序翻译发生改变QEvent::LayoutDirectionChange90布局的方向发生改变QEvent::LayoutRequest76部件的布局需要重做QEvent::Leave11鼠标离开部件的边界QEvent::LeaveEditFocus151编辑部件失去编辑的焦点必须定义 QT_KEYPAD_NAVIGATIONQEvent::LeaveWhatsThisMode125当应用程序离开“What’s This?”模式发送到顶层部件QEvent::LocaleChange88系统区域设置发生改变QEvent::NonClientAreaMouseButtonDblClick176鼠标双击发生在客户端区域外QEvent::NonClientAreaMouseButtonPress174鼠标按钮按下发生在客户端区域外QEvent::NonClientAreaMouseButtonRelease175鼠标按钮释放发生在客户端区域外QEvent::NonClientAreaMouseMove173鼠标移动发生在客户区域外QEvent::MacSizeChange177用户更改了部件的大小仅限 OS XQEvent::MetaCall43通过 QMetaObject::invokeMethod() 调用异步方法QEvent::ModifiedChange102部件修改状态发生改变QEvent::MouseButtonDblClick4鼠标再次按下QMouseEventQEvent::MouseButtonPress2鼠标按下QMouseEventQEvent::MouseButtonRelease3鼠标释放QMouseEventQEvent::MouseMove5鼠标移动QMouseEventQEvent::MouseTrackingChange109鼠标跟踪状态发生改变QEvent::Move13部件的位置发生改变QMoveEventQEvent::NativeGesture197系统检测到手势QNativeGestureEventQEvent::OrientationChange208屏幕方向发生改变QScreenOrientationChangeEventQEvent::Paint12需要屏幕更新QPaintEventQEvent::PaletteChange39部件的调色板发生改变QEvent::ParentAboutToChange131部件的 parent 将要更改QEvent::ParentChange21部件的 parent 发生改变QEvent::PlatformPanel212请求一个特定于平台的面板QEvent::PlatformSurface217原生平台表面已创建或即将被销毁QPlatformSurfaceEventQEvent::Polish75部件被抛光QEvent::PolishRequest74部件应该被抛光QEvent::QueryWhatsThis123如果部件有“What’s This?”帮助应该接受事件QEvent::ReadOnlyChange106部件的 read-only 状态发生改变QEvent::RequestSoftwareInputPanel199部件想要打开软件输入面板SIPQEvent::Resize14部件的大小发生改变QResizeEventQEvent::ScrollPrepare204对象需要填充它的几何信息QScrollPrepareEventQEvent::Scroll205对象需要滚动到提供的位置QScrollEventQEvent::Shortcut117快捷键处理QShortcutEventQEvent::ShortcutOverride51按下按键用于覆盖快捷键QKeyEventQEvent::Show17部件显示在屏幕上QShowEventQEvent::ShowToParent26子部件被显示QEvent::SockAct50Socket 激活用于实现 QSocketNotifierQEvent::StateMachineSignal192信号被传递到状态机QStateMachine::SignalEventQEvent::StateMachineWrapped193事件是一个包装器用于包含另一个事件QStateMachine::WrappedEventQEvent::StatusTip112状态提示请求QStatusTipEventQEvent::StyleChange100部件的样式发生改变QEvent::TabletMove87Wacom 写字板移动QTabletEventQEvent::TabletPress92Wacom 写字板按下QTabletEventQEvent::TabletRelease93Wacom 写字板释放QTabletEventQEvent::OkRequest94Ok 按钮在装饰前被按下仅支持 Windows CEQEvent::TabletEnterProximity171Wacom 写字板进入接近事件QTabletEvent发送到 QApplicationQEvent::TabletLeaveProximity172Wacom 写字板离开接近事件QTabletEvent发送到 QApplicationQEvent::ThreadChange22对象被移动到另一个线程。这是发送到此对象的最后一个事件在上一个线程中参见QObject::moveToThread()QEvent::Timer1定时器事件QTimerEventQEvent::ToolBarChange120工具栏按钮在 OS X 上进行切换QEvent::ToolTip110一个 tooltip 请求QHelpEventQEvent::ToolTipChange184部件的 tooltip 发生改变QEvent::TouchBegin194触摸屏或轨迹板事件序列的开始QTouchEventQEvent::TouchCancel209取消触摸事件序列QTouchEventQEvent::TouchEnd196触摸事件序列结束QTouchEventQEvent::TouchUpdate195触摸屏事件QTouchEventQEvent::UngrabKeyboard189Item 失去键盘抓取QGraphicsItemQEvent::UngrabMouse187Item 失去鼠标抓取QGraphicsItem、QQuickItemQEvent::UpdateLater78部件应该排队在以后重新绘制QEvent::UpdateRequest77部件应该被重绘QEvent::WhatsThis111部件应该显示“What’s This”帮助QHelpEventQEvent::WhatsThisClicked118部件的“What’s This”帮助链接被点击QEvent::Wheel31鼠标滚轮滚动QWheelEventQEvent::WinEventAct132发生了 Windows 特定的激活事件QEvent::WindowActivate24窗口已激活QEvent::WindowBlocked103窗口被模态对话框阻塞QEvent::WindowDeactivate25窗户被停用QEvent::WindowIconChange34窗口的图标发生改变QEvent::WindowStateChange105窗口的状态最小化、最大化或全屏发生改变QWindowStateChangeEventQEvent::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_castNumberChangeEvent*(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_castNumberChangeEvent*(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的事件产生之后不是直接传递给了对象的需要经过一系列的过程。 事件首先由Qt的ServerApplication去接收来自于外部或内部的一些行为鼠标点击键盘输入时钟事件等分析并决定送往对应的对象去处理(内部管理机制)最后会调用[virtual] bool QCoreApplication::notify ( QObject * receiver, QEvent * event ) 去处理当然这个是虚函数你可以在子类去重新实现它 。 在notify(…)中在发给对应的接收者前会先把消息送给QApplication。所以如果想在你界面的Widget前先处理那些事 件那么你可以给QApplication对象installEventFilter,然后在对应的eventFilter()里先把这些事件都给过一 遍然后你可以过滤一些不必要事件。 如果QApplication没有处理那些事件然后就是交给事件接收对象了。在这个对象接收前也可以为这对象加一个事件过滤器同样是 installEventFilter。 如果eventFilter没有过滤某些事件那么就会将事件交给接收者的event()函数你可以根据不同类型的事件尽情处理如果event事件在接受者处理后也不会上传给父类的event否则会上传进入父类的event。 默认event()函数根据事件类型会调用不同的事件处理函数,类似mousePressEvent(),keyPressEvent()去分别处理他们。
事件传播到父组件
当控件忽略事件时事件会继续往上传播这里的传播是指传播给父组件。 QEvent有 accept()函数 和ignore()函数 accept()本组件处理该事件这个事件就不会被继续传播给其父组件 ignore()本组件不想要处理这个事件这个事件会被继续传播给其父组件 值得注意的是所有的事件默认都是接受的即不会传递到父组件 忽略和接受案例 当默认接受事件时在本组件处理之后事件不会传递到父组件mousePressEvent处理。
#include QApplication
#include QWidget
#include QPushButton
#include QMouseEventclass 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 QMouseEventclass 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_castQWidget*(object);if (!w)return false;if (ev-type() QEvent::MouseButtonPress){auto me static_castQMouseEvent*(ev);pressPos me-pos();return true;}else if (ev-type() QEvent::MouseMove){auto me static_castQMouseEvent*(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_castQWidget*(object);if (!w)return false;if (ev-type() QEvent::MouseButtonPress){auto me static_castQMouseEvent*(ev);pressPos me-pos();}else if (ev-type() QEvent::MouseMove){auto me static_castQMouseEvent*(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的关系由具体对象进行处理由具体对象主动产生对程序的影响改写事件处理函数可能导致程序行为发生改变信号是否存在对应的槽函数不会改变程序行为两者的联系一般而言信号在具体的事件处理函数中产生