(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)
谢谢