QT6 源(164)模型视图架构里的视图里的拖放功能专题 :联合 QObject、 QWidget 和 QAbstractItemView 谈一谈

(1)UI 界面搭建好以后, QT 程序进入了事件循环。类似于操作系统的中断,由中断驱动操作系统的运行,中断就是函数。这是 CPU 硬件与操作系统软件的结合点。有些中断是由硬件产生的。 CPU 识别这些中断,并执行相应的代码。但对应的中断函数的功能却是可变的,由程序员写入。所以,在软件层面的代码的丰富多变,构成了可编程控制器。

(2)QT 里的模型视图架构里的视图,是预定义地支持拖放功能的。这些视图已经具备了拖放功能,不需要咱们程序员再去实现它。 这是 QT 大师们的杰作。 QT 里定义了事件的很多的类型,大约 100 种以上。其中有关于拖放的事件。 QWidget 与 QAbstractItemView 这个视图抽象基类里也有关于拖放的属性与功能函数。这些结合起来,完善与支撑起来了 QT 里的拖放功能。本文尝试总结一下。

(3) QT 里的事件类的继承关系大致如下

在这里插入图片描述

++这些事件类的不同,主要在于起数据成员与成员函数的不同,而不在于其类名字,给出这些事件类的数据成员的继承关系 :

在这里插入图片描述

(4) 总基类 QObject 里面,有关于对事件的成员函数的支持

在这里插入图片描述

(5)上面的类里关于事件处理的成员函数很少, 只要由 event ( ) 根据事件类型来实现对应的事件处理逻辑
QWidget 极大地扩充了某些常用且重要的事件类的对应处理函数,这些函数的区别,不在于名称,而在于其功能与代码实现,但其是保密的。 QT 官方只提供了头文件,没有提供这些关于处理事件的成员函数的代码实现 :

在这里插入图片描述

++ QWidget 里定义的处理事件类的成员函数,会被其子类控件继承或加以修改,就形成了不同 UI 组件的不同的 UI 样式
为了扩展某些控件的事件处理功能,就可以自定义并继承这样的控件,并补充相应的事件处理代码,或者使用 QObject 里的事件过滤(其实就是事件委托机制,但表现形式上确实类似于事件过滤)功能

(6) QWidget 里还有一个属性,就是禁用或启用拖放功能

在这里插入图片描述

(7)剩下的 QT 里的拖放功能的支持与代码实现,就都在抽象视图 QAbstractItemView 里了

在这里插入图片描述

++给出本类的关于拖放功能的代码版,包括了事件处理函数

//本精简版只关注于拖放操作。因为本基类里的内容太多了。
class Q_WIDGETS_EXPORT QAbstractItemView : public QAbstractScrollArea
{
private:

    Q_OBJECT //又插入了此宏

    //This property holds whether the view supports dragging of its own items。
    //选中后,则多选被取消,原条目被拖动起来了。默认为 false。
    Q_PROPERTY(bool dragEnabled READ dragEnabled WRITE setDragEnabled)


    //This property holds the drag and drop event the view will act upon。
    //enum DragDropMode { NoDragDrop, DragOnly, DropOnly, DragDrop, InternalMove };
    Q_PROPERTY(DragDropMode dragDropMode READ dragDropMode WRITE setDragDropMode)


    /*
    enum Qt::DropAction {
        CopyAction = 0x1,
        MoveAction = 0x2,
        LinkAction = 0x4,
        ActionMask = 0xff,
        TargetMoveAction = 0x8002,
        IgnoreAction = 0x0
    };
    */
    //This property holds the
    //  drop action that will be used by default in QAbstractItemView::drag()。
    //If the property is not set, the drop action is CopyAction when the
    //  supported actions support CopyAction.
    //此属性持有在QAbstractltemView::drag()中默认使用的拖动操作。
    //如果属性未设置,当支持的行动支持CopyAction时,拖放操作为CopyAction。
    Q_PROPERTY(Qt::DropAction     defaultDropAction
                READ              defaultDropAction
                WRITE          setDefaultDropAction)


    //This property holds whether the 此属性表示在拖动项目和放下时是否显示下拉指示器。
    //  drop indicator is shown when dragging items and dropping. //选中与否没感到有啥区别。
    Q_PROPERTY(bool showDropIndicator READ showDropIndicator WRITE setDropIndicatorShown)


    //This property holds the view's drag and drop behavior。//此属性控制视图的拖放行为。
    //如果其值为真,则所选择的数据在被放置时会覆盖现有的项目数据,而移动数据则会清空该项目。
    //If its value is true, the selected data will overwrite the
    //  existing item data when dropped, while moving the data will clear the item.
    //如果其值为假,那么所选择的数据在被放置时会作为新项目插入,而移动数据时该项目也会被移除。
    //If its value is false, the selected data will be inserted as a new item when the
    //  data is dropped. When the data is moved, the item is removed as well.
    //默认值为假,与QListView和QTreeView子类中的情况相同。而在QTableView子类中,该属性已被设置为真。
    //The default value is false, as in the QListView and QTreeView subclasses.
    //In the QTableView subclass, on the other hand, the property has been set to true.
    //Note: This is not intended to prevent overwriting of items.注:这并非旨在防止对项的覆盖。
    //模型的`flags()、实现应通过不返回`Qt:ItemIsDropEnabled`来达到此目的。
    //The model's implementation of flags() should do that by not
    //  returning Qt::ItemIsDropEnabled.
    Q_PROPERTY(bool       dragDropOverwriteMode //为 true则拖放时成覆盖操作。
                READ      dragDropOverwriteMode //为 F   则拖放时成插入操作。
                WRITE  setDragDropOverwriteMode)//默认列表与树视图为 F,表格视图为 T

public:
    //Constructs an abstract item view with the given parent.
    explicit QAbstractItemView(QWidget * parent = nullptr); //有参构造函数

    ~QAbstractItemView();


//   Q_PROPERTY(bool      showDropIndicator
//              READ      showDropIndicator    WRITE   setDropIndicatorShown)
                bool      showDropIndicator     () const;
                void       setDropIndicatorShown(bool enable);

//   Q_PROPERTY(bool      dragEnabled
//              READ      dragEnabled    WRITE   setDragEnabled)
                bool      dragEnabled() const;
                void   setDragEnabled(bool enable);


//   Q_PROPERTY(bool      dragDropOverwriteMode
//              READ      dragDropOverwriteMode
//              WRITE  setDragDropOverwriteMode)
                bool      dragDropOverwriteMode() const;
                void   setDragDropOverwriteMode(bool overwrite);

    //描述了视图可以处理的各种拖放事件。默认情况下,视图不支持拖放(NoDragDrop)。
    //Describes the various drag and drop events the view can act upon.
    //By default the view does not support dragging or dropping (NoDragDrop).
    //Note that the model used needs to provide support for drag and drop operations.
        enum    DragDropMode {
            NoDragDrop,  //Does not support dragging or dropping.
            DragOnly  ,  //The view supports dragging of its own items。
            DropOnly  ,  //The view accepts drops。
            DragDrop  ,  //The view supports both dragging and dropping。
            InternalMove //The view accepts move (not copy) operations only from itself。
        };
        Q_ENUM( DragDropMode )
//   Q_PROPERTY(DragDropMode     dragDropMode
//              READ             dragDropMode    WRITE    setDragDropMode)
                DragDropMode     dragDropMode() const;
                void          setDragDropMode(DragDropMode  behavior);


    /*
    enum Qt::DropAction { //本枚举类用于描述模型视图里的拖动操作的语义:复制、剪切或超链接。
        CopyAction       = 0x   1, //Copy the data to the target.
        MoveAction       = 0x   2, //Move the data from the source to the target.
        LinkAction       = 0x   4, //Create a link from the source to the target.
        ActionMask       = 0x  ff,
        TargetMoveAction = 0x8002, //在 Windows上,当 D&D数据的所有权应被目标应用程序接管时,
            //即源应用程序不应删除这些数据时,会使用此值。
            //在X11上,此值用于执行移动操作。Mac上不使用TargetMoveAction。
        IgnoreAction     = 0x   0  //Ignore the action (do nothing with the data).
    };
    Q_DECLARE_FLAGS(DropActions, DropAction)
    Q_DECLARE_OPERATORS_FOR_FLAGS(DropActions)
    */

//   Q_PROPERTY(Qt::DropAction     defaultDropAction
//              READ               defaultDropAction
//              WRITE           setDefaultDropAction)
                Qt::DropAction     defaultDropAction() const;
                void            setDefaultDropAction(Qt::DropAction dropAction);


protected:
    QAbstractItemView(QAbstractItemViewPrivate &, QWidget *parent = nullptr); //有参构造函数

    /*
    enum Qt::DropAction {
        CopyAction = 0x1,
        MoveAction = 0x2,
        LinkAction = 0x4,
        ActionMask = 0xff,
        TargetMoveAction = 0x8002,
        IgnoreAction = 0x0
    };
    Q_DECLARE_FLAGS(DropActions, DropAction)
    Q_DECLARE_OPERATORS_FOR_FLAGS(DropActions)
    */
    virtual void startDrag(Qt::DropActions   supportedActions);
    //Starts a drag by calling drag->exec() using the given supportedActions.


    //此枚举表示当前鼠标位置相对于索引的下拉指示器的位置:
    //This enum indicates the position of the drop indicator in relation to the
    //  index at the current mouse position:
    enum DropIndicatorPosition {
           OnItem, //The item will be dropped on    the index.
        AboveItem, //The item will be dropped above the index.
        BelowItem, //The item will be dropped below the index.
        OnViewport //The item will be dropped onto a region of the viewport with no items.
            //The way each view handles items dropped onto the viewport depends on the
            //  behavior of the underlying model in use.
            //该物品将被放置在视窗中没有任何物品的区域。
            //视窗如何处理被放置在视窗上的物品,取决于当前使用的底层模型的行为。
    };
    DropIndicatorPosition dropIndicatorPosition() const;
    //Returns the position of the drop indicator in relation to the closest item.

	//virtual bool QObject::       eventFilter(QObject * watched, QEvent * event);
    //        void QObject::installEventFilter(QObject * filterObj);
    bool                 eventFilter(QObject * object, QEvent * event) override;

    bool                 event(QEvent            * event) override;

    void        dragEnterEvent(QDragEnterEvent   * event) override;
    void         dragMoveEvent(QDragMoveEvent    * event) override;
    void        dragLeaveEvent(QDragLeaveEvent   * event) override;
    void             dropEvent(QDropEvent        * event) override;

public Q_SLOTS:

protected Q_SLOTS:

Q_SIGNALS:

    //总之,基类视图提供的信号函数很简单,这也可能是又出现选择模型的意义。

}; //完结 class QAbstractItemView : public QAbstractScrollArea


++至此,联合以上的知识点,就可以较完善的理解与使用 QT 框架提供的拖放功能了

(8)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zhangzhangkeji

谢谢支持

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

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

打赏作者

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

抵扣说明:

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

余额充值