QT6 源,六章,事件系统(4):QInputEvent 及其子类 QPointerEvent,孙类 QSinglePointEvent,由此引出鼠标事件 QMouseEvent

(1) QInputEvent ,与输入相关的事件的总基类

/*
enum Qt::KeyboardModifier {
    NoModifier           = 0x00000000, //No modifier key is pressed.
    ShiftModifier        = 0x02000000, //A Shift key on the keyboard is pressed.
    ControlModifier      = 0x04000000, //A Ctrl  key on the keyboard is pressed.
    AltModifier          = 0x08000000, //An Alt  key on the keyboard is pressed.
    MetaModifier         = 0x10000000, //A Meta  key on the keyboard is pressed.
    KeypadModifier       = 0x20000000, //A keypad button is pressed.
    GroupSwitchModifier  = 0x40000000, //X11 only (unless activated on Windows by a
            //command line argument). A Mode_switch key on the keyboard is pressed.

    // Do not extend the mask to include 0x01000000
    KeyboardModifierMask = 0xfe000000
};
Q_DECLARE_FLAGS(KeyboardModifiers, KeyboardModifier)
Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardModifiers)
*/

//The QInputEvent class is the base class for events that describe user input.
class Q_GUI_EXPORT QInputEvent : public QEvent
{
    Q_EVENT_DISABLE_COPY(QInputEvent);

protected:
    const   QInputDevice  *  m_dev       = nullptr;//定义在下
            quint64          m_timeStamp =       0;
    Qt::KeyboardModifiers    m_modState  = Qt::NoModifier;

            quint32          m_reserved  = 0;
    // fill up to the closest 8-byte aligned size: 48

    QInputEvent(Type type,     PointerEventTag, const QInputDevice * dev,
                Qt::KeyboardModifiers modifiers = Qt::NoModifier);

    QInputEvent(Type type, SinglePointEventTag, const QInputDevice * dev,
                Qt::KeyboardModifiers modifiers = Qt::NoModifier);

public:
    explicit    QInputEvent(Type type, const QInputDevice * m_dev,
                            Qt::KeyboardModifiers modifiers = Qt::NoModifier);

    ~QInputEvent();

    QInputEvent  * clone () const override { return new QInputEvent(* this); }

    const
    QInputDevice             * device    () const { return     m_dev; }

    QInputDevice::DeviceType   deviceType() const
    {
        return
                m_dev
                ? m_dev->type()
                : QInputDevice::DeviceType::Unknown;
    }
/*
enum class QInputDevice::DeviceType {
    Unknown = 0x0000,
    Mouse = 0x0001,
    TouchScreen = 0x0002,
    TouchPad = 0x0004,
    Puck = 0x0008,
    Stylus = 0x0010,
    Airbrush = 0x0020,
    Keyboard = 0x1000,
    AllDevices = 0x7FFFFFFF
};
Q_DECLARE_FLAGS(DeviceTypes, DeviceType)
Q_FLAG(DeviceTypes)
*/


    inline  quint64    timestamp() const            { return        m_timeStamp; }
    virtual void    setTimestamp(quint64 timestamp) { m_timeStamp =   timestamp; }

    inline Qt::KeyboardModifiers     modifiers() const { return m_modState; }
    inline void                   setModifiers(Qt::KeyboardModifiers modifiers)
    {   m_modState = modifiers;   }

}; //完结 class QInputEvent : public QEvent

(2) QPointerEvent ,点击事件的总基类,因为输入事件还包括弹出菜单与键盘事件

class Q_GUI_EXPORT QPointerEvent : public QInputEvent
{
    Q_EVENT_DISABLE_COPY(QPointerEvent);

protected:
    QPointerEvent(  Type type, SinglePointEventTag,
                    const QInputDevice    *  dev,
                    Qt::KeyboardModifiers    modifiers = Qt::NoModifier);

    QList<QEventPoint> m_points;

public:
    //构造函数里描述了本事件的类型,触发设备,修饰符,点击信息
    explicit QPointerEvent(Type type, const QPointingDevice * dev,  //构造函数
                                    Qt::KeyboardModifiers     modifiers = Qt::NoModifier,
                            const   QList<QEventPoint>      & points    = {});

    ~QPointerEvent();

    QPointerEvent * clone() const override { return new QPointerEvent(*this); }

    void setTimestamp(quint64 timestamp) override; //无注释

    //返回此事件的源设备。这与QInputEvent::device()相同,但为了方便进行了类型转换。
    const QPointingDevice *      pointingDevice() const;

    //Returns the type of point that generated the event.
    QPointingDevice::PointerType pointerType() const
    {
        return  pointingDevice()
                ? pointingDevice()->pointerType()
                : QPointingDevice::PointerType::Unknown;
    }
    /*
    enum class QPointingDevice::PointerType {
        Unknown = 0,
        Generic = 0x0001,    // mouse or similar
        Finger  = 0x0002,    // touchscreen or pad
        Pen     = 0x0004,    // stylus on a tablet
        Eraser  = 0x0008,    // eraser end of a stylus
        Cursor  = 0x0010,    // digitizer with crosshairs
        AllPointerTypes = 0x7FFF
    };
    Q_DECLARE_FLAGS(PointerTypes, PointerType)
    Q_FLAG(PointerTypes)

    */


    //Returns the number of points in this pointer event.
    qsizetype                    pointCount() const //QList<QEventPoint> m_points;
    { return m_points.count(); }  // 返回链表中的元素数量

    //Returns a QEventPoint reference for the point at index i.
    QEventPoint       &          point(qsizetype i) { return m_points[i]; }
    QEventPoint       *          pointById(int id);
    //返回与给定id匹配的点,如果未找到则返回nulptr。
    const QList<QEventPoint> &   points()   const   { return m_points   ; }
    //Returns a list of points in this pointer event.

    bool                      allPoints1Grabbed() const;  //无注释

    //Returns true if isPointAccepted() is true for every point in points();
    //  otherwise false.
    bool                      allPointsAccepted() const;
    virtual void                    setAccepted(bool accepted) override; //无注释

    virtual bool  isBeginEvent() const { return false; }  //无注释
    virtual bool isUpdateEvent() const { return false; }
    virtual bool    isEndEvent() const { return false; }

    //返回已设置为接收所有未来更新事件和包含给定点的发布事件的对象。 前主要用于Ot Quick。
    QObject         *         exclusiveGrabber (const   QEventPoint & point) const;

    void                   setExclusiveGrabber (const   QEventPoint & point,
                                                        QObject     * exclusiveGrabber);
    //通知传递逻辑,即指定的独占抓取器将接收所有未来的更新事件以及包含指定点的释放事件,
    //而其他项目的传递可以跳过。

    //返回已请求接收所有未来更新事件和包含给定点的发布事件的对象列表。
    //它仅用于Qt Quick输入处理程序。
    QList<QPointer <QObject>>   passiveGrabbers(const   QEventPoint & point) const;
    void                   clearPassiveGrabbers(const   QEventPoint & point);
    //从指定位置移除所有被动抓取器。

    //通知传递逻辑,即指定的抓取器将接收所有未来的更新事件以及包含指定点的释放事件,
    //而无论这些事件可能从其他位置传递而来。
    //它仅用于Qt Quick输入处理程序。 如果抓取器已添加,则返回false,否则返回true。
    bool                     addPassiveGrabber (const   QEventPoint & point,
                                                        QObject     * grabber);

    bool                  removePassiveGrabber (const   QEventPoint & point,
                                                        QObject     * grabber);
    //如果之前已添加,则从给定点移除被动抓取器。如果之前是被动抓取器,返回true;否则,返回false。

}; //完结 class QPointerEvent : public QInputEvent

(3) QSinglePointEvent ,单点事件,因为触摸屏里才有同时多点事件

//A base class for pointer events containing a single point, such as mouse events.
class Q_GUI_EXPORT QSinglePointEvent : public QPointerEvent //单点事件
{
    Q_GADGET

    //此属性持有将接收未来更新的对象。
    //专属抓取器是一种对象,它已选择接收所有未来的更新事件以及包含与该事件携带的相同点的释放事件。
    Q_PROPERTY(QObject *    exclusivePointGrabber
                READ        exclusivePointGrabber
                WRITE    setExclusivePointGrabber)

    Q_EVENT_DISABLE_COPY(QSinglePointEvent);

protected:
    //enum Qt::MouseButton { NoButton, LeftButton, RightButton, MiddleButton, ... };
    //Q_DECLARE_FLAGS(MouseButtons, MouseButton) 即 MouseButtons = QFlags<MouseButton>
    QSinglePointEvent(Type type, const QPointingDevice * dev, const QEventPoint & point,
                        Qt::MouseButton  button , //QEventPoint 里包含了点击的丰富的坐标信息
                        Qt::MouseButtons buttons,
                        Qt::KeyboardModifiers modifiers, //修饰符比如 ctrl
                        Qt::MouseEventSource source);

    QSinglePointEvent(Type type, const QPointingDevice * dev,
                        const QPointF &  localPos,
                        const QPointF &  scenePos,
                        const QPointF & globalPos,
                        Qt::MouseButton  button  ,
                        Qt::MouseButtons buttons ,
                        Qt::KeyboardModifiers modifiers,
                        Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);

    /*
    //这个枚举描述了鼠标事件的来源,对于判断该事件是否源自另一设备(如触摸屏)的人工鼠标事件可能很有用。
    //This enum describes the source of a mouse event and
    //  can be useful to determine if the event is an
    //  artificial mouse event originating from another device such as a touchscreen.
    enum Qt::MouseEventSource {        //合成的 Synthesized  ['sɪnθɪsaɪzd]
        MouseEventNotSynthesized,      //最常用的值。
                        //在有此信息可用的平台上,该值表示该事件是由系统中的真实鼠标事件触发的。
        MouseEventSynthesizedBySystem, //表示鼠标事件是由平台从       触摸事件合成的。
        MouseEventSynthesizedByQt,     //表示鼠标事件是由Qt  从未处理的触摸事件合成的。
        MouseEventSynthesizedByApplication //表示鼠标事件是由应用程序合成的。
                        //这使得能够区分由应用程序生成的鼠标事件与来自系统或由Qt合成的鼠标事件。
    };
    */

    Qt::MouseButton      m_button     = Qt::NoButton;
    Qt::MouseButtons     m_mouseState = Qt::NoButton;
    Qt::MouseEventSource m_source;
    quint16 m_reserved;
    quint16 m_reserved2         : 11;                  // for QMouseEvent
    quint16 m_doubleClick       :  1;                  // for QWheelEvent
    quint16 m_phase             :  3;
    quint16 m_invertedScrolling :  1;
    /*
        Fill up to the next 8-byte aligned size: 88
        We have 32bits left, use some for QSinglePointEvent subclasses so that
        we don't end up with gaps.
    */
    // split this in two quint16; with a quint32, MSVC would 32-bit align it

public:
    QSinglePointEvent * clone() const override
    { return new QSinglePointEvent(* this); }

    //返回引发事件的按钮。
    //在鼠标移动事件以及TabletMove、TabletEnterProximity和TabletLeaveProximity事件中,
    //返回的值始终为Qt:NoButton --按钮状态不指任何按钮
    inline Qt::MouseButton  button () const { return m_button    ; }
    inline Qt::MouseButtons buttons() const { return m_mouseState; }
    //返回事件生成时的按钮状态。
    //按钮状态是使用或运算符组合Qt::左键、Qt::右键和Qt::中键。
    //对于鼠标移动或平板移动事件,         这是所有按下按钮的组合。
    //对于鼠标按下、双击或TabletPress事件,这包括导致该事件的按钮。
    //对于鼠标释放或平板释放事件,         这排除了导致该事件的按钮。

    //class QPointerEvent { protected : QList<QEventPoint> m_points; };故可被继承
    inline QPointF       position() const
    { Q_ASSERT(!m_points.isEmpty()); return m_points.first().position(); }
    //返回此事件中点的位置,相对于接收该事件的控件或项目。
    //如果你根据鼠标事件移动小部件,请使用globalPosition()。

    //返回该事件中点的位置,相对于窗口或场景。
    inline QPointF  scenePosition() const
    { Q_ASSERT(!m_points.isEmpty()); return m_points.first().scenePosition(); }

    inline QPointF globalPosition() const
    { Q_ASSERT(!m_points.isEmpty()); return m_points.first().globalPosition(); }
    //返回此事件中点在屏幕或虚拟桌面上的位置。
    //注意:鼠标指针的全局位置是在事件发生时记录的。这在异步窗口系统(如X11)中非常重要;
    //每当您响应鼠标事件移动小部件时,
    //  globalPosition()与QCursor:pos()返回的当前光标位置可能会有很大差异。


    bool  isBeginEvent() const override; //如果此事件表示按钮被按下,则返回true。
    bool isUpdateEvent() const override; //如果此事件不包含按钮状态的变化,则返回true。
    bool    isEndEvent() const override; //如果此事件表示按钮被释放,则返回true。

    //此属性持有将接收未来更新的对象。
    //专属抓取器是一种对象,它已选择接收所有未来的更新事件以及包含与该事件携带的相同点的释放事件。
    QObject *    exclusivePointGrabber() const
    { return QPointerEvent::exclusiveGrabber(points().first()); }

    void      setExclusivePointGrabber(QObject * exclusiveGrabber)
    { QPointerEvent::setExclusiveGrabber(points().first(), exclusiveGrabber); }

}; //完结 class QSinglePointEvent : public QPointerEvent

(4)鼠标事件 QMouseEvent ,描述鼠标的按下,弹起,移动这三种情形

/*
The QMouseEvent class contains parameters that describe a mouse event.

Detailed Description :
当鼠标按钮在小部件内按下或释放,或者当鼠标光标移动时,会发生鼠标事件。

鼠标移动事件仅在按下鼠标按钮时发生,除非已使用QWidget::setMouseTracking()启用鼠标跟踪。

当在某个小部件内按下鼠标按钮时,Qt会自动捕捉鼠标;
该小部件将持续接收鼠标事件,直到最后一个鼠标按钮被释放为止。

鼠标事件包含一个特殊的接受标志,用于指示接收方是否想要该事件。
如果鼠标事件未被您的控件处理,应调用ignore ()'方法。
标事件会沿着父控件链向上传播,直到有控件通过`accept ()'方法接受它,或者被事件过滤器消耗掉。

注:如果鼠标事件被传递到一个已设置 Qt::WA_NoMousePropagation 的小部件,
那么这个鼠标事件将不会在父小部件链中进一步传递。

可以通过调用继承自QInputEvent的modifiers()函数来查找键盘修饰键的状态。

position()、函数提供的是相对于接收鼠标事件的控件或项的游标位置。
如果因鼠标事件而移动了控件应使用`globalPosition()、函数返回的全局位置,以避免出现抖动效果。

OWidget::setEnabled()函数可用于启用或禁用对某个窗口的鼠标和键盘事件。

重新实现QWidget的事件处理函数:QWidget::mousePressEvent()、QWidget::mouseReleaseEvent()、
Qwidget::mouseDoubleClickEvent ()和QWidget:mouseMoveEvent(),
以便在您的自定义窗口部件中接收鼠标事件。

*/
class Q_GUI_EXPORT QMouseEvent : public QSinglePointEvent
{
    Q_EVENT_DISABLE_COPY(QMouseEvent);

public:  //总之一句话,鼠标移动事件时对应的鼠标状态是 Qt:NoButton。
    //构造一个鼠标事件对象。类型参数必须是QEvent:.MouseButtonPress、QEvent:.MouseButtonRelease、
    //  QEvent::MouseButtonDblclick或QEvent::MouseMove.
    //localPos、scenePos和 globalPos分别指定鼠标光标相对于接收的控件或项、窗口以及屏幕或桌面的位置。
    //引发该事件的按钮被赋值为来自 Qt:MouseButton 枚举的值。
    //如果事件类型为 MouseMove,那么该事件的对应按钮为 Qt:NoButton。
    //buttons 变量表示事件发生时所有按钮的状态,modifiers 变量表示所有键盘修饰符的状态。
    QMouseEvent(Type type, const QPointF & localPos,
                Qt::MouseButton button,  Qt::MouseButtons buttons,
                Qt::KeyboardModifiers modifiers,
                const QPointingDevice * device = QPointingDevice::primaryPointingDevice());

    QMouseEvent(Type type, const QPointF & localPos,
                const QPointF & globalPos,
                Qt::MouseButton button,  Qt::MouseButtons buttons,
                Qt::KeyboardModifiers modifiers,
                const QPointingDevice * device = QPointingDevice::primaryPointingDevice());

    QMouseEvent(Type type, const QPointF & localPos,
                const QPointF & scenePos,            const QPointF & globalPos,
                Qt::MouseButton button, Qt::MouseButtons buttons,
                Qt::KeyboardModifiers modifiers,
                const QPointingDevice * device = QPointingDevice::primaryPointingDevice());

    QMouseEvent(Type type, const QPointF & localPos,
                const QPointF & scenePos, const QPointF & globalPos,
                Qt::MouseButton button, Qt::MouseButtons buttons,
                Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source,
                const QPointingDevice * device = QPointingDevice::primaryPointingDevice());

    ~QMouseEvent();

    QMouseEvent * clone() const override { return new QMouseEvent(*this); }

    inline QPoint pos() const { return position().toPoint(); }

    //返回鼠标事件标志。 鼠标事件标志提供有关鼠标事件的额外信息。
    Qt::MouseEventFlags flags() const;
    /*
    enum Qt::MouseEventFlag { //此枚举提供了有关QMouseEvent的附加信息。
        NoMouseEventFlag             = 0x00,
        MouseEventCreatedDoubleClick = 0x01,
            //这表明Qt已从该事件中创建了一个MouseButtonDblclick事件。
            //该标志是在引发MouseButtonPress的事件中设置的,
            //而不是在后续的MouseButtonDblclick事件中设置的。
        MouseEventFlagMask           = 0xFF
    };
    Q_DECLARE_FLAGS(MouseEventFlags, MouseEventFlag)
    Q_DECLARE_OPERATORS_FOR_FLAGS(MouseEventFlags)
    */

}; //完结 class QMouseEvent : public QSinglePointEvent

++测试一下

在这里插入图片描述

(5)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值