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

QEvent和它的涉及类继承体系和设计思想

目录

1.QEvent

1.1.简介

1.2.QEvent 核心接口与状态

1.3.事件类型(QEvent::Type)

1.4.事件处理流程

1.5.自定义事件

1.6.关键注意事项

2.QEvent 类继承体系

3.QEvent 设计思想

4.总结


1.QEvent

1.1.简介

        QEvent 是 Qt 事件驱动模型的核心类,封装了所有与事件相关的信息(如用户交互、系统通知、自定义行为等),并提供了事件识别、传递和处理的基础接口。

        QEvent 是 Qt 中所有事件的抽象基类,任何事件(如鼠标点击、窗口刷新、定时器超时)都必须继承自它。

        它的特征有:

  • 每个事件有唯一的类型标识(QEvent::Type);
  • 支持事件的 “接受 / 忽略” 状态(控制事件是否继续传递);
  • 兼容 Qt 元对象系统,支持跨线程事件传递。

QT 中的元对象系统(二):元对象实现原理QMetaObject

1.2.QEvent 核心接口与状态

QEvent 提供了基础接口用于事件识别和状态管理,类定义如下:

class QEventPrivate;
class Q_CORE_EXPORT QEvent           // event base class
{Q_GADGETQDOC_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
public:enum Type {/*If you get a strange compiler error on the line with None,it's probably because you're also including X11 headers,which #define the symbol None. Put the X11 includes afterthe Qt includes to solve this problem.*/None = 0,                               // invalid eventTimer = 1,                              // timer eventMouseButtonPress = 2,                   // mouse button pressedMouseButtonRelease = 3,                 // mouse button releasedMouseButtonDblClick = 4,                // mouse button double clickMouseMove = 5,                          // mouse moveKeyPress = 6,                           // key pressedKeyRelease = 7,                         // key releasedFocusIn = 8,                            // keyboard focus receivedFocusOut = 9,                           // keyboard focus lostFocusAboutToChange = 23,                // keyboard focus is about to be lostEnter = 10,                             // mouse enters widgetLeave = 11,                             // mouse leaves widgetPaint = 12,                             // paint widgetMove = 13,                              // move widgetResize = 14,                            // resize widgetCreate = 15,                            // after widget creationDestroy = 16,                           // during widget destructionShow = 17,                              // widget is shownHide = 18,                              // widget is hiddenClose = 19,                             // request to close widgetQuit = 20,                              // request to quit applicationParentChange = 21,                      // widget has been reparentedParentAboutToChange = 131,              // sent just before the parent change is doneThreadChange = 22,                      // object has changed threadsWindowActivate = 24,                    // window was activatedWindowDeactivate = 25,                  // window was deactivatedShowToParent = 26,                      // widget is shown to parentHideToParent = 27,                      // widget is hidden to parentWheel = 31,                             // wheel eventWindowTitleChange = 33,                 // window title changedWindowIconChange = 34,                  // icon changedApplicationWindowIconChange = 35,       // application icon changedApplicationFontChange = 36,             // application font changedApplicationLayoutDirectionChange = 37,  // application layout direction changedApplicationPaletteChange = 38,          // application palette changedPaletteChange = 39,                     // widget palette changedClipboard = 40,                         // internal clipboard eventSpeech = 42,                            // reserved for speech inputMetaCall =  43,                         // meta call eventSockAct = 50,                           // socket activationWinEventAct = 132,                      // win event activationDeferredDelete = 52,                    // deferred delete eventDragEnter = 60,                         // drag moves into widgetDragMove = 61,                          // drag moves in widgetDragLeave = 62,                         // drag leaves or is cancelledDrop = 63,                              // actual dropDragResponse = 64,                      // drag accepted/rejectedChildAdded = 68,                        // new child widgetChildPolished = 69,                     // polished child widgetChildRemoved = 71,                      // deleted child widgetShowWindowRequest = 73,                 // widget's window should be mappedPolishRequest = 74,                     // widget should be polishedPolish = 75,                            // widget is polishedLayoutRequest = 76,                     // widget should be relayoutedUpdateRequest = 77,                     // widget should be repaintedUpdateLater = 78,                       // request update() laterEmbeddingControl = 79,                  // ActiveX embeddingActivateControl = 80,                   // ActiveX activationDeactivateControl = 81,                 // ActiveX deactivationContextMenu = 82,                       // context popup menuInputMethod = 83,                       // input methodTabletMove = 87,                        // Wacom tablet eventLocaleChange = 88,                      // the system locale changedLanguageChange = 89,                    // the application language changedLayoutDirectionChange = 90,             // the layout direction changedStyle = 91,                             // internal style eventTabletPress = 92,                       // tablet pressTabletRelease = 93,                     // tablet releaseOkRequest = 94,                         // CE (Ok) button pressedHelpRequest = 95,                       // CE (?)  button pressedIconDrag = 96,                          // proxy icon draggedFontChange = 97,                        // font has changedEnabledChange = 98,                     // enabled state has changedActivationChange = 99,                  // window activation has changedStyleChange = 100,                      // style has changedIconTextChange = 101,                   // icon text has changed.  Deprecated.ModifiedChange = 102,                   // modified state has changedMouseTrackingChange = 109,              // mouse tracking state has changedWindowBlocked = 103,                    // window is about to be blocked modallyWindowUnblocked = 104,                  // windows modal blocking has endedWindowStateChange = 105,ReadOnlyChange = 106,                   // readonly state has changedToolTip = 110,WhatsThis = 111,StatusTip = 112,ActionChanged = 113,ActionAdded = 114,ActionRemoved = 115,FileOpen = 116,                         // file open requestShortcut = 117,                         // shortcut triggeredShortcutOverride = 51,                  // shortcut override requestWhatsThisClicked = 118,ToolBarChange = 120,                    // toolbar visibility toggledApplicationActivate = 121,              // deprecated. Use ApplicationStateChange instead.ApplicationActivated = ApplicationActivate, // deprecatedApplicationDeactivate = 122,            // deprecated. Use ApplicationStateChange instead.ApplicationDeactivated = ApplicationDeactivate, // deprecatedQueryWhatsThis = 123,                   // query what's this widget helpEnterWhatsThisMode = 124,LeaveWhatsThisMode = 125,ZOrderChange = 126,                     // child widget has had its z-order changedHoverEnter = 127,                       // mouse cursor enters a hover widgetHoverLeave = 128,                       // mouse cursor leaves a hover widgetHoverMove = 129,                        // mouse cursor move inside a hover widget// last event id used = 132#ifdef QT_KEYPAD_NAVIGATIONEnterEditFocus = 150,                   // enter edit mode in keypad navigationLeaveEditFocus = 151,                   // enter edit mode in keypad navigation
#endifAcceptDropsChange = 152,ZeroTimerEvent = 154,                   // Used for Windows Zero timer eventsGraphicsSceneMouseMove = 155,           // GraphicsViewGraphicsSceneMousePress = 156,GraphicsSceneMouseRelease = 157,GraphicsSceneMouseDoubleClick = 158,GraphicsSceneContextMenu = 159,GraphicsSceneHoverEnter = 160,GraphicsSceneHoverMove = 161,GraphicsSceneHoverLeave = 162,GraphicsSceneHelp = 163,GraphicsSceneDragEnter = 164,GraphicsSceneDragMove = 165,GraphicsSceneDragLeave = 166,GraphicsSceneDrop = 167,GraphicsSceneWheel = 168,KeyboardLayoutChange = 169,             // keyboard layout changedDynamicPropertyChange = 170,            // A dynamic property was changed through setProperty/propertyTabletEnterProximity = 171,TabletLeaveProximity = 172,NonClientAreaMouseMove = 173,NonClientAreaMouseButtonPress = 174,NonClientAreaMouseButtonRelease = 175,NonClientAreaMouseButtonDblClick = 176,MacSizeChange = 177,                    // when the Qt::WA_Mac{Normal,Small,Mini}Size changesContentsRectChange = 178,               // sent by QWidget::setContentsMargins (internal)MacGLWindowChange = 179,                // Internal! the window of the GLWidget has changedFutureCallOut = 180,GraphicsSceneResize  = 181,GraphicsSceneMove  = 182,CursorChange = 183,ToolTipChange = 184,NetworkReplyUpdated = 185,              // Internal for QNetworkReplyGrabMouse = 186,UngrabMouse = 187,GrabKeyboard = 188,UngrabKeyboard = 189,MacGLClearDrawable = 191,               // Internal Cocoa, the window has changed, so we must clearStateMachineSignal = 192,StateMachineWrapped = 193,TouchBegin = 194,TouchUpdate = 195,TouchEnd = 196,#ifndef QT_NO_GESTURESNativeGesture = 197,                    // QtGui native gesture
#endifRequestSoftwareInputPanel = 199,CloseSoftwareInputPanel = 200,WinIdChange = 203,
#ifndef QT_NO_GESTURESGesture = 198,GestureOverride = 202,
#endifScrollPrepare = 204,Scroll = 205,Expose = 206,InputMethodQuery = 207,OrientationChange = 208,                // Screen orientation has changedTouchCancel = 209,ThemeChange = 210,SockClose = 211,                        // socket closedPlatformPanel = 212,StyleAnimationUpdate = 213,             // style animation target should be updatedApplicationStateChange = 214,WindowChangeInternal = 215,             // internal for QQuickWidgetScreenChangeInternal = 216,PlatformSurface = 217,                  // Platform surface created or about to be destroyedPointer = 218,                          // QQuickPointerEvent; ### Qt 6: QPointerEventTabletTrackingChange = 219,             // tablet tracking state has changed// 512 reserved for Qt Jambi's MetaCall event// 513 reserved for Qt Jambi's DeleteOnMainThread eventUser = 1000,                            // first user event idMaxUser = 65535                         // last user event id};Q_ENUM(Type)explicit QEvent(Type type);QEvent(const QEvent &other);virtual ~QEvent();QEvent &operator=(const QEvent &other);inline Type type() const { return static_cast<Type>(t); }inline bool spontaneous() const { return spont; }inline void setAccepted(bool accepted) { m_accept = accepted; }inline bool isAccepted() const { return m_accept; }inline void accept() { m_accept = true; }inline void ignore() { m_accept = false; }static int registerEventType(int hint = -1) Q_DECL_NOTHROW;protected:QEventPrivate *d;ushort t;private:ushort posted : 1;ushort spont : 1;ushort m_accept : 1;ushort reserved : 13;friend class QCoreApplication;friend class QCoreApplicationPrivate;friend class QThreadData;friend class QApplication;friend class QShortcutMap;friend class QGraphicsView;friend class QGraphicsScene;friend class QGraphicsScenePrivate;// from QtTest:friend class QSpontaneKeyEvent;// needs this:Q_ALWAYS_INLINEvoid setSpontaneous() { spont = true; }
};

核心成员如下:

接口 / 成员功能描述
QEvent::Type type()返回事件类型(枚举值),用于识别事件(如 QEvent::MouseButtonPress 表示鼠标按下)。
void accept()标记事件为 “已处理”,事件将停止向上传递(父对象不再接收该事件)。
void ignore()标记事件为 “未处理”,事件将继续向上传递给父对象(父对象可能处理该事件)。
bool isAccepted()判断事件是否被接受(accept() 后返回 trueignore() 后返回 false)。
bool spontaneous()判断事件是否为 “自发事件”:true 表示由系统 / 用户触发(如鼠标点击),false 表示由程序手动发送(如 postEvent)。

1.3.事件类型(QEvent::Type)

Qt 预定义了数百种事件类型(QEvent::Type 枚举),覆盖各类场景,按功能可分为以下几类(常用类型示例):

1.输入事件(用户交互)

  • QEvent::MouseButtonPress:鼠标按键按下(左键 / 右键等);
  • QEvent::MouseButtonRelease:鼠标按键释放;
  • QEvent::MouseMove:鼠标移动;
  • QEvent::Wheel:鼠标滚轮滚动;
  • QEvent::KeyPress:键盘按键按下;
  • QEvent::KeyRelease:键盘按键释放;
  • QEvent::TouchBegin/TouchUpdate/TouchEnd:触摸事件(移动设备)。

2.窗口与控件事件

  • QEvent::Show:窗口 / 控件显示;
  • QEvent::Hide:窗口 / 控件隐藏;
  • QEvent::Resize:窗口 / 控件大小改变;
  • QEvent::Move:窗口 / 控件位置移动;
  • QEvent::Close:窗口关闭请求;
  • QFocusIn/QFocusOut:控件获得 / 失去焦点;
  • QEvent::Enter/QEvent::Leave:鼠标进入 / 离开控件区域。

3.绘制与刷新事件

  • QEvent::Paint:控件需要重绘(触发 paintEvent());
  • QEvent::UpdateRequest:请求更新控件(通常由 update() 触发,用于延迟重绘)。

4.定时器与网络事件

  • QEvent::Timer:定时器超时(触发 timerEvent());
  • QEvent::NetworkReplyFinished:网络请求完成(QtNetwork 模块);
  • QEvent::SocketActivated:套接字活动(如收到数据)。

5.自定义事件范围

Qt 预留了 QEvent::User1000)到 QEvent::MaxUser65535)的范围用于自定义事件,避免与系统事件冲突。需通过 QEvent::registerEventType() 注册(见后文)。

1.4.事件处理流程

Qt 事件从产生到处理需经过事件产生→事件分发→事件过滤→事件处理→事件传递五个阶段,流程如下:

1.事件产生

  • 系统事件:由操作系统或硬件触发(如用户点击鼠标→系统生成鼠标事件→Qt 捕获并封装为 QMouseEvent);
  • 程序事件:由 Qt 或用户代码生成(如 QTimer 超时生成 QTimerEvent,用户调用 postEvent 发送自定义事件)。

2.事件分发(QApplication::notify ())

事件产生后,由 QApplication(或 QCoreApplication)的 notify() 函数统一分发:

bool QApplication::notify(QObject *receiver, QEvent *e) {// 1. 检查是否有事件过滤器拦截该事件if (filterEvent(receiver, e)) return true;// 2. 调用接收者的 event() 函数处理事件return receiver->event(e);
}
  • notify() 是事件分发的入口,确保每个事件被正确传递到目标对象(receiver)。

3.事件过滤(installEventFilter ())

在事件到达目标对象前,可被 “事件过滤器” 拦截处理:

  • 过滤器通过 QObject::installEventFilter(QObject *filter) 安装到目标对象;
  • 过滤器需重写 eventFilter(QObject *watched, QEvent *e),返回 true 表示拦截事件(不再传递),false 表示放行。

示例:拦截按钮的鼠标点击事件

class Filter : public QObject {
protected:bool eventFilter(QObject *watched, QEvent *e) override {// 若目标是按钮且事件是鼠标按下,则拦截if (watched == ui->pushButton && e->type() == QEvent::MouseButtonPress) {qDebug() << "拦截按钮点击";return true; // 拦截事件}return false; // 放行其他事件}
};// 使用:为按钮安装过滤器
Filter *filter = new Filter;
ui->pushButton->installEventFilter(filter);

4.事件处理(event () 与特定事件函数)

事件到达目标对象后,通过以下两种方式处理:

1) 方式 1:重写 event() 函数(通用事件处理入口):

目标对象(如 QWidget)的 event() 函数根据事件类型,分发到具体的事件处理函数(如 mousePressEvent)。用户可重写 event() 实现自定义分发逻辑:

bool MyWidget::event(QEvent *e) override {if (e->type() == QEvent::MouseButtonPress) {qDebug() << "处理鼠标按下事件(event())";return true; // 处理完成}// 未处理的事件交给父类return QWidget::event(e);
}

2) 方式 2:重写特定事件函数(便捷处理):

Qt 控件已将常见事件封装为虚函数(如 mousePressEventkeyPressEventpaintEvent),直接重写即可:

void MyWidget::mousePressEvent(QMouseEvent *e) override {qDebug() << "鼠标按下位置:" << e->pos();// 若需让父类继续处理(如保持默认行为),调用父类实现QWidget::mousePressEvent(e);
}

5.事件传递(接受 / 忽略机制)

若事件未被处理(或调用了 ignore()),会向上传递给父对象,直到被处理或到达顶级窗口:

  • 调用 e->accept():事件停止传递(默认行为,多数事件处理函数会自动接受);
  • 调用 e->ignore():事件继续传递给父对象。

示例:子控件忽略事件,让父控件处理

void ChildWidget::mousePressEvent(QMouseEvent *e) {e->ignore(); // 忽略事件,让父控件处理
}void ParentWidget::mousePressEvent(QMouseEvent *e) {qDebug() << "父控件处理子控件未处理的鼠标事件";
}

1.5.自定义事件

当预定义事件满足不了需求(如业务逻辑事件),可通过以下步骤实现自定义事件

1.注册自定义事件类型

使用 QEvent::registerEventType() 分配唯一类型值(避免冲突):

// 注册自定义事件类型(通常在程序初始化时)
const QEvent::Type MyEventType = static_cast<QEvent::Type>(QEvent::registerEventType());

2.定义自定义事件类

继承 QEvent,封装业务数据:

class MyEvent : public QEvent {
public:MyEvent(int data) : QEvent(MyEventType), m_data(data) {}int data() const { return m_data; } // 自定义数据访问接口
private:int m_data; // 业务数据
};

3.发送自定义事件

通过 sendEvent(同步)或 postEvent(异步)发送:

// 同步发送:事件立即处理,阻塞当前线程
MyEvent event(123);
QCoreApplication::sendEvent(targetObject, &event);// 异步发送:事件加入队列,由事件循环处理(非阻塞)
// 注意:postEvent 需动态分配事件对象(Qt 会自动释放)
QCoreApplication::postEvent(targetObject, new MyEvent(123));

4.处理自定义事件

在目标对象中重写 event() 或使用事件过滤器:

bool MyObject::event(QEvent *e) override {if (e->type() == MyEventType) {MyEvent *myEvent = static_cast<MyEvent*>(e);qDebug() << "收到自定义事件,数据:" << myEvent->data();return true;}return QObject::event(e);
}

1.6.关键注意事项

1.线程安全性

  • 事件可跨线程传递(通过 postEvent),Qt 会自动将事件放入目标线程的事件队列;
  • 自定义事件的 data 若包含指针,需确保线程安全(如使用 QSharedPointer)。

2.事件与信号槽的区别

  • 事件是 “被动通知”(由系统或框架触发),信号槽是 “主动通信”(由对象主动发射);
  • 事件支持传递和过滤,信号槽一旦连接直接触发。

3.性能考量

  • 高频事件(如鼠标移动)需轻量化处理,避免阻塞事件循环;
  • 大量自定义事件建议批量发送,减少事件队列压力。

4.事件处理函数的默认行为

重写事件函数时,若需保留控件默认行为(如按钮点击的视觉反馈),需调用父类实现(如 QPushButton::mousePressEvent(e))。

2.QEvent 类继承体系

QEvent 是 Qt 事件系统的根类,所有具体事件(如鼠标点击、窗口刷新)均派生自它。其继承体系按 “事件类型” 分层,核心子类可分为输入事件、窗口事件、绘制事件、定时器事件、自定义事件等,形成清晰的分类结构。

1.输入事件(用户交互相关)

基类为 QInputEvent,封装输入设备(鼠标、键盘、触摸等)的事件信息:

  • QInputEvent:输入事件基类,包含事件发生的时间戳(timestamp())和修饰键状态(modifiers(),如 Ctrl、Shift 键是否按下)。
    • QMouseEvent:鼠标事件(点击、移动、释放等),提供坐标(x()/y())、鼠标按钮(button())、点击次数(clickCount())等信息,子类包括 QMousePressEvent(按下)、QMouseReleaseEvent(释放)、QMouseMoveEvent(移动)等。
    • QWheelEvent:鼠标滚轮事件,提供滚轮滚动方向和角度(delta())、滚轮坐标等。
    • QKeyEvent:键盘事件(按键按下 / 释放),提供键值(key(),如 Qt::Key_A)、字符(text(),如按下 Shift+A 时为 A)等。
    • QTouchEvent:触摸事件(多点触摸),包含触摸点列表(touchPoints()),支持移动设备交互。

2.窗口与控件事件(UI 状态变化)

处理窗口或控件的状态变化(如大小、显示 / 隐藏、焦点等):

  • QWindowEvent:窗口状态事件,如窗口关闭(QEvent::Close)、显示(QEvent::Show)、隐藏(QEvent::Hide)、移动(QEvent::Move)、大小变化(QEvent::Resize)等。
  • QFocusEvent:焦点事件(控件获得 / 失去焦点),包含焦点原因(reason(),如用户点击、Tab 键切换)。
  • QEnterEvent/QLeaveEvent:鼠标进入 / 离开控件区域的事件(用于悬停效果)。

3.绘制与刷新事件

触发控件重绘的事件:

  • QPaintEvent:绘制事件,当控件需要重绘(如首次显示、被遮挡后恢复)时触发,包含需要重绘的区域(rect()),控件通过重写 paintEvent() 实现自定义绘制。

4.定时器与网络事件

  • QTimerEvent:定时器事件,当 QTimer 超时或调用 startTimer() 后,定时触发,包含定时器 ID(timerId())用于区分多个定时器。
  • QNetworkEvent(Qt Network 模块):网络事件(如数据接收、连接状态变化),基类为 QEvent,具体子类如 QNetworkReply::finished 相关事件(封装在 Qt 网络框架内部)。

5.自定义事件

用户可通过继承 QEvent 实现自定义事件,需使用 QEvent::User 到 QEvent::MaxUser 范围内的类型(避免与系统事件冲突)。

3.QEvent 设计思想

Qt 事件系统的设计围绕 “灵活的事件分发与处理” 展开,核心思想包括:

1.事件封装:面向对象的事件表示

  • 每个事件(如鼠标点击、窗口关闭)被封装为一个 QEvent 子类对象,包含该事件的所有相关信息(如鼠标事件的坐标、键盘事件的键值)。
  • 这种封装使得事件的传递、存储、处理可以统一通过对象接口完成,符合面向对象的 “信息隐藏” 原则(事件的具体细节由子类内部实现,外部通过接口访问)。

2.事件类型识别:多态与类型判断

  • 所有事件通过 QEvent::type() 标识类型,配合 dynamic_cast 可将基类 QEvent* 转换为具体子类(如 QMouseEvent*),实现多态处理:
bool MyWidget::event(QEvent *e) {if (e->type() == QEvent::MouseButtonPress) {// 转换为具体事件类型,获取详细信息QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(e);qDebug() << "鼠标按下位置:" << mouseEvent->pos();return true; // 标记事件已处理}return QWidget::event(e); // 未处理的事件交给父类
}
  • 这种设计允许一个统一的接口(event())处理所有类型的事件,具体逻辑由事件类型动态决定,体现 “开闭原则”(新增事件类型无需修改现有处理框架)。

3.事件传递:层次化分发与冒泡机制

  • 事件产生后,Qt 会通过 QApplication::notify() 按 “层次化路径” 分发:从底层窗口(如子控件)向上传递到父窗口,直至顶级窗口或被处理。
  • 例如,点击一个按钮时,事件先传递给按钮,若按钮未处理(ignore()),则传递给按钮的父控件(如 QWidget),以此类推。这种 “冒泡机制” 允许父组件拦截子组件未处理的事件,增加处理灵活性。

4.事件过滤:拦截与监控机制

Qt 提供 installEventFilter() 允许一个对象(过滤器)监控另一个对象的事件,在事件到达目标对象前先由过滤器处理:

// 过滤器对象
class MyFilter : public QObject {
protected:bool eventFilter(QObject *watched, QEvent *e) override {if (watched == targetWidget && e->type() == QEvent::MouseButtonPress) {qDebug() << "拦截到目标控件的鼠标点击";return true; // 拦截事件,不再传递}return false; // 不拦截,继续传递}
};// 使用:为目标控件安装过滤器
MyFilter *filter = new MyFilter;
targetWidget->installEventFilter(filter);
  • 这种设计允许在不修改目标对象代码的前提下,扩展或监控其事件处理,体现 “组合优于继承” 的设计原则。

5.同步与异步事件:灵活的触发方式

  • Qt 支持两种事件发送方式:
    • 同步发送QCoreApplication::sendEvent()):事件直接传递给目标对象的 event() 函数,立即处理,阻塞当前线程直至完成;
    • 异步发送QCoreApplication::postEvent()):事件被加入事件队列,由 Qt 的事件循环(QEventLoop)异步处理,不阻塞当前线程。
  • 这种区分满足了不同场景需求:同步事件用于需要立即响应的场景(如关键输入),异步事件用于非紧急任务(如批量数据更新),避免阻塞主线程。

6.扩展性:支持自定义事件

  • 通过继承 QEvent 并使用 User 范围内的类型,用户可定义业务相关的事件(如 “数据处理完成事件”“状态变更事件”),并通过 sendEvent()/postEvent() 发送,与系统事件统一处理。
  • 这种设计使事件系统不仅能处理内置事件,还能无缝集成业务逻辑,体现 “可扩展” 特性。

4.总结

        Qt 的 QEvent 继承体系通过 “基类抽象 + 子类具体实现” 的分层设计,清晰分类了各类事件(输入、窗口、绘制等),为事件识别和处理提供了统一接口。其设计思想围绕灵活的事件分发(层次化传递、过滤机制)、面向对象的封装(事件即对象)、可扩展性(自定义事件)展开,使得 Qt 能够高效处理复杂的用户交互和系统通知,同时为开发者提供了丰富的扩展点(如重写 event()、事件过滤、自定义事件)。        

        这种设计是 Qt 事件驱动模型的核心,也是其界面响应灵活、可定制性强的关键原因。

http://www.dtcms.com/a/417007.html

相关文章:

  • 上海的加盟网站建设wordpress表单生成
  • 网站开发 业务流程图国外做家装的网站有哪些
  • 上海知名的网站建设公司网站开发商怎么关闭图片显示
  • 晋中市科技馆网站建设平阳县住房和城乡规划建设局网站
  • 营销型网站方案书阿里云 win wordpress 伪静态
  • 做网站要先买域名吗淘宝网首页电脑登陆入口
  • 找人做网站昆明建设门户网站发展前景2018
  • 营销者网站wordpress表白源码
  • 建湖营销型网站建设工作室益阳市网站建设
  • 网站开发模块化开发如何在网上建设一个公司网站
  • 网站建设的上市公司海淀网站建设哪家公司好
  • 网站开发月薪多少钱建设网站的优势
  • 开发网站网页归档建立网站的流程多少钱
  • 做外贸一般上什么网站wordpress 短链接插件
  • 成都网站维护多少钱网站建设工资多少
  • apache搭建多个网站卫生院网站建设
  • 个人怎么建立网站老站改版与新建网站
  • 百度网盟推广合作网站安徽移动互联网开发
  • 上海有名的网站建设公司学网络推广培训
  • 成交型网站制作设计品牌logo
  • 赤峰网站开发red企业管理专业就业方向
  • 有做软件的网站有哪些一个网站项目几个人做
  • 建设班级网站 沟通无限安卓手机app
  • 秀山网站建设端午节手抄报获奖wordpress要收钱吗
  • 微信公众号怎么做微网站吗国外建设网站
  • 网站seo外链如何做服装的微商城网站
  • wordpress设置站点地址网络上做广告最好怎么做
  • 还有用asp做网站的吗巴中市建设厅官方网站
  • 有做国际网站生意吗湖北网站建设营销qq
  • 做餐饮网站网站空间如何搬家