23. [Python GUI] PyQt5中的模型与视图框架-抽象视图基类QAbstractItemView

PyQt5的抽象视图基类QAbstractItemView

一、QAbstractItemView的基本概念

QAbstractItemView 类继承自 QAbstractScrollArea,后者又继承自 QFrame,该类是 Qt 所有视图类的基类, Qt 的所有视图都需要子类化该类。注意:该类是抽象类,因此不能创建该类的对象。

该类的构造函数原型为: QAbstractItemView(QWidget* parent = Q_NULLPTR);

QAbstractItemView类支持以下的键盘操作:

20221126165619

QAbstractItemView类的当前项目或当前索引:

  • 当前项目用于键盘导航和焦点指示(原理见下图),若按下编辑键 F2,将会编辑当前项目
  • 当前项目不一定是当前已被选择(高亮)的项目, 当前项目可以处于被选择状态,也可以不处于被选择状态。
  • 只能有一个当前项目,但可以同时有多个被选择的项目。
  • 当前项目通常是具有焦点的项目。

20221126165825

本小节暂时不介绍怎样实现自定义的视图,因为自定义视图需要自行绘制(通常在paintEvent()函数内完成),所以需在讲解委托之后讲解怎样自定义视图。

二、QAbstractItemView类中的属性

2.1 与滚动有关的属性

  • autoScroll: bool
    访问函数:
    bool hasAutoScroll() const;
    void setAutoScroll(bool);
    是否启用自动滚动,默认为 tru(启用)

  • alternatingRowColors: bool
    访问函数:
    bool alternatingRowColors() const;
    void setAlternatingRowColors(bool);
    是否使用交替的颜色绘制背景色,若为 true,则使用 QPalette::AlternateBase 和
    QPalette::Base 绘制背景色,否则使用 QPalette::Base 绘制背景色。默认为 false。

  • autoScrollMargin: int
    访问函数:
    int autoScrollMargin() const;
    void setAutoScrollMargin(int);
    描述触发自动滚动时视口边缘区域的大小, 当用户拖动至该区域时视图将自动滚动, 默认
    为 16 像素。原理见下图
    20221126170253

  • horizontalScrollMode: ScrollMode
    访问函数:
    ScrollMode horizontalScrollMode() const;
    void setHorizontalScrollMode(ScrollMode);
    void resetHorizontalScrollMode();

  • verticalScrollMode: ScrollMode
    访问函数:
    ScrollMode verticalScrollMode() const;
    void setVerticalScrollMode(ScrollMode );
    void resetVerticalScrollMode();
    以上属性分别表示视图在水平或垂直方向上的滚动模式,即一次滚动一个像素还是一个项目的内容,默认值由 QStyle::SH_ItemView_ScrollMode 决定。 ScrollMode 枚举取值如下:
    20221126170448

2.2 与拖放有关的属性

  • dragEnabled: bool
    访问函数:
    bool dragEnabled() const;
    void setDragEnabled(bool);
    是否启用拖放操作,注意,视图默认未启用拖放。

  • defaultDropAction: Qt::DropAction
    访问函数:
    Qt::DropAction defaultDropAction() const;
    void setDropAction(Qt::DropAction);
    此属性描述拖放时的默认放置动作(见属性 showDropIndicator 的图示)。若未设置该属性,则当支持的放置动作支持 Qt::CopyAction 时,放置操作为 Qt::CopyAction。 枚举Qt::DropAction 见 QAbstractItemModel::supportedDropActions()函数。

  • showDropIndicator: bool
    访问函数:
    bool showDropIndicator() const;
    void setDropIndicatorShow(bool);
    拖动项目在项目放下时,是否向用户显示放置指示符(通常该位置会以不同的形式显示,比如以阴影形式显示等,见下图)
    20221126170647

  • dragDropMode: DragDropMode
    访问函数:
    DragDropMode dragDropMode()
    void setDragDropMode(DragDropMode);
    描述视图支持的拖放模式。 DragDropMode 枚举见下表
    20221126170726

  • dragDropOverwriteMode: bool
    访问函数:
    bool dragDropOverwriteMode() const;
    void setDragDropOverwriteMode(bool);
    描述施放操作放置时的覆盖行为,若该值为 true,则选定的数据将在放置时覆盖现在的数据,若为 false,则在放置数据时,所选数据将作为新项目被插入。对于 QListView 和QTreeView 默认为 false,对于 QTableView 默认为 true。 该属性对不同视图的行为并不一致。

2.3 编辑项目

  • editTriggers: EditTriggers
    访问函数:
    EditTriggers editTriggers() const;
    void setEditTriggers(EditTriggers);
    描述编辑项目的触发方式,枚举 EditTrigger 见下表
    20221126170919

2.4 选择项目

  • selectionBehavior: SelectionBehavior
    访问函数:
    QAbstractItemView::SelectionBehavior selectionBehavior() const;
    void setSelectionBehavior(QAbstractItemView::SelectionBehavior)
    描述视图的选择行为(比如按行或列选择等)。 SelectionBehavior 枚举见下表
    20221126171018

  • selectionMode: SelectionMode
    访问函数:
    QAbstractItemView::SelectionMode selectionModer() const;
    void setSelectionMode(QAbstractItemView::SelectionMode)
    描述视图的选择模式(比如是否可以同时选择多个项目等)。 SelectionMode 枚举见下表
    20221126171113

2.5 其他属性

  • tabKeyNavigation: bool
    访问函数:
    bool tabKeyNavigation() const;
    void setTabKeyNavigation(bool);
    描述 tab 键是否用于项目导航,若为 true,则按下 tab 键会选择(高亮) 下一个项目; 若为false,则按下 tab 键没有任何反应,但是若 setEditTriggers()函数的设置包含QAbstractItemView::AnyKeyPressed,则按下 tab 键会直接编辑下一个项目。

  • textElideMode: Qt::TextElideMode
    访问函数:
    Qt::TextElideMode textElideMode() const;
    void setTextElideMode(Qt::TextElideMode);
    描述省略符“…”的位置,所有视图的默认值都是 Qt::ElideRight(即右侧)。 枚举Qt::TextElideMode 如下:
    20221126171436

  • iconSize: QSize
    访问函数:
    QSize iconSize() const;
    void setIconSize(const QSize &);
    信号: iconSizeChanged(const QSize&);
    描述视图项目图标的大小。

三、QAbstractItemView类中的函数

3.1 纯虚函数

  • virtual void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags) = 0; //protected
    将选择标志 flags 应用于矩形 rect 中的项目,或 rect 所触及到的项目。在实现自已的视图时,该函数应该调用 selectionModel()->select(selection,flags),其中的 selection 要么是空的 QModelIndex,要么是包含在 rect 中的所有项目的 QItemSelection。枚举QItemSelectionModel::SelectionFlags 参见 QItemSelectionModel 类

  • virtual QRect visualRect(const QModelIndex &index) const = 0; //纯虚函数
    返回由索引 index 所指项目占用的视口上的矩形(注意:矩形是包括位置和大小的)。若项目显示在多个区域,则该函数应返回包含索引的主区域,而不是索引可能包含、触及或导致绘图的完整区域。

  • virutal QRegion visualRegionForSelection(const QItemSelection &selection) const = 0; //受保护的
    从 selection 选择的项目的视口返回区域。

  • virtual int horizontalOffset() const = 0; //纯虚函数,受保护的

  • virtual int verticalOffset() const = 0; //纯虚函数,受保护的
    返回视图的水平/垂直偏移量,必须返回视口在窗口部件中 x 和 y 坐标的偏移量(通常滚动条的值(value())就是需要的偏移量)。

  • virtual QModelIndex indexAt(const QPoint &point) const = 0; //纯虚函数
    返回视口坐标点 point 处的模型索引

  • virtual bool isIndexHidden(const QModelIndex &index) const = 0 ; //纯虚函数,受保护的
    若索引 index 所引用的项目隐藏在视图中,则返回 true,否则返回 false,隐藏是视图特定的特性。

  • virtual QModelIndex moveCursor(CursorAction cursorAction , Qt::KeyboardModifiers modifiers) = 0; //纯虚函数,受保护的
    根据cursorAction和键盘修饰符modifiers,返回指向视图中的下一个对象的模型索引。枚举 CursorAction 见下表
    20221126172123

  • virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) = 0; //纯虚函数
    必要时滚动视图,以确保 index 处的项目是可见的,视图根据参数 hint 来定位项目。ScrollHint 枚举见下表
    20221126172206

3.2 与模型有关的函数

  • QAbstractItemModel *model() const; //返回该视图使用的模型
    virtual void setModel(QAbstractItemModel *model); //虚拟的
    • 设置视图的模型
    • 除非视图被设置为模型的父对象,否则视图不会获取模型的所有权。
    • 注意:使用该函数后,还会重新创建并设置一个新的选择模型(QItemSelectionModel),并且会替换之前由 setSelectionModel()设置的任何选择模型,但是旧的选择模型不会被删除

3.3 与拖放有关的函数

  • DropIndicatorPosition dropIndicatorPosition() const; //受保护的
    返回放置指示符(见属性 showDropIndicator)相对于最近项目的位置。枚举DropIndicatorPosition 见下表
    20221126172419

  • virtual void startDrag(Qt::DropActions supportedActions); //虚拟的,受保护的
    通过使用参数 supportedActions 调用 drag->exec()来启用拖动。

3.4 与委托有关的函数

  • void setItemDelegate(QAbstractItemDelegate *delegate);
    把该视图和模型的委托设置为 delegate,现有的委托将被移除,但不会被删除,QAbstractItemView 不会接受委托的所有权。设置委托后,便可以完全控制项目的编辑和显示。注意:最好不要在视图之间共享同一个实例的委托。

  • void setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate);
    void setItemDelegateForRow(int row, QAbstractItemDelegate *delegate);
    把该视图和模型所在列 column 或行 row 的委托设置为 delegate,设置委托后,列或行上的所有项目都将由delegate 进行绘制和管理,而不再使用默认委托(即itemDelegate()),现有的委托将被移除,但不会被删除, QAbstractItemView 不会接受委托的所有权。若委托已分配给行和列,则行/列委托将优先管理相交的单元索引。

  • QAbstractItemDelegate* itemDelegate() const;
    QAbstractItemDelegate* itemDelegate(const QModelIndex &index) const;
    QAbstractItemDelegate* itemDelegateForColumn(int column) const;
    QAbstractItemDelegate* itemDelegateForRow(int row) const;
    以上函数表示获取视图和模型在索引 index 或列 column 或行 row 处使用的项目委托。

3.5 与编辑有关的函数

  • void edit(const QModelIndex &index); //槽
    若索引 index 指定的项目是可编辑的,则编辑该项目。

  • virtual bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)); //虚拟的,受保护的
    在索引index 处开始编辑项目,必要时创建编辑器,若视图的 State(状态)为EditingState,则返回 true,否则返回 false。参数 trigger 指定引起编辑的方式,相关的事件由 event描述。若把 trigger 指定为 QAbstractItemView::AllEditTriggers,则可以强制编辑,EditTrigger 枚举见 editTriggers 属性

  • virtual void commitData(QWidget *editor); //槽, 虚拟的,受保护的
    将编辑器 editor 中的数据提交给模型。

  • virtual closeEditor(QWidget *editor,QAbstractItemDelegate::EndEditHint hint);//槽, 虚拟的,受保护的
    关闭编辑器 editor,然后释放它,参数 hint 用于指示视图应如何响应编辑操作结束时的行为,比如 hint 可以表示当编辑操作结束时,打开视图中的下一个项目进行编辑。枚举 QAbstractItemDelegate::EndEditHint hint 见 QAbstractItemDelegate 类。

  • virtual void editorDestroyed(QObject *editor); //槽, 虚拟的,受保护的
    销毁编辑器 editor。

  • void openPersistentEditor(const QModelIndex &index);
    在索引 index 处打开持久编辑器,若没有编辑器,则委托将创建一个新的编辑器。 普通编辑器当离开该项目时会自动关闭,而持久编辑器则会一直存在,直到调用colsePersistentEditor()关闭

  • bool isPersistentEditorOpen(const QModelIndex &index) const; //qt5.10
    返回索引 index 处项目的持久编辑器是否已打开。

  • void closePersistentEditor( const QModelIndex &index);
    关闭索引 index 处的持久编辑器

3.6 与选择有关的函数

  • QItemSelectionModel *selectionModel() const; //返回当前的选择模型

  • virtual void setSelectionModel(QItemSelectionModel *selectionModel) ; //虚拟的
    把当前的选择模型设置为 selectionModel。注意:若在此函数之后调用 setModel()函数,则该函数设置的选择模型会被调用 setModel()函数时创建的选择模型替换。旧的选择模型应由应用程序来删除,也就是说,若旧选择模型未被其他视图使用时,当删除其父对象时,旧选择模型会被自动删除,但是,若旧选择模型没有父对象,或父对象是一个长期存在的对象,则最好调用它的 QObject::deleteLater()函数来显示删除。

  • void clearSelection(); //槽
    取消所有选择的项目,当前索引不会被改变

  • virtual void selectAll(); //槽, 虚拟的
    选择视图中的所有项目

  • virtual QModelIndexList selectedIndexes() const; //虚拟的,受保护的
    返回视图中所有可被选择项目和非隐藏项目的索引列表,该列表不包含重复项目,且未排序。

  • virtual QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex &index,const QEvent *event = Q_NULLPTR) const; //虚拟的,受保护的
    返回在更新包含索引 index 的选择时,使用的 SelectionFlags(选择标志),事件 event 是用户输入事件,比如鼠标或键盘事件。重新实现此函数可定义自已的选择行为。枚举QItemSelectionModel::SelectionFlags 参见 QItemSelectionModel 类

  • virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) const; //槽, 虚拟的,受保护的
    当选择改变时,调用此槽函数, deselected 表示之前的选择(可能为空), selected 表示新的选择。

3.7 与索引有关的函数

  • QModelIndex currentIndex() const; //返回当前项目的模型索引

  • void setCurrentIndex(const QModelIndex &index); //槽

    • 把索引 index 处的项目设置为当前项目。除非选择模式是 NoSelection,否则该项目会被选择(高亮显示)。
    • 注意:此函数还会更新用户执行的任何新选择的起始位置。
    • 另外,还可使用 QItemSelectionModel 类中的函数来设置当前项目,其方法如下:
      QAstractItemView::selectionModel()->setCurrentIndex()。
  • QModelIndex rootIndex() const;
    返回模型根项目的模型索引,根项目是视图的顶级项目的父项目,根目录的索引可能是无效索引。

  • virtual void setRootIndex(const QModelIndex &index); //槽, 虚拟的
    把索引 index 所指项目设置为根项目

3.8 与滚动有关的函数

  • void scrollToBottom(); //槽
    void scrollToTop(); //槽
    以上函数表示将视图滚动到底/顶部

  • void setDirtyRegion(const QRegion &region); //受保护的
    将区域 region 标记为脏区域(Dirty Region),并安排更新,只有在自定义视图子类时,才需调用此函数。

  • QPoint dirtyRegionOffset() const; //受保护的
    返回视图中 Dirty Region(脏区域)的偏移量。若使用 ScrollDirtyRegion()并在该类的子类中实现了paintEvent(), 则应使用从该函数返回的偏移量来转换paint事件给出的区域。

  • void scrollDirtyRegion(int dx, int dy); //受保护的
    通过在相反方向移动脏区域,以使视图滚动(dx,dy)像素。只有在自定义视图子类实现滚动视口时,才需调用此函数。 若在该类的子类中重新实现QAbstractScrollArea::scrollContentsBy()函数,则应在调用视口上的 QWidget::scroll()之前调用此函数,或者只调用 QAbstractItemView::update()函数。

  • virtual QSize viewportSizeHint() const; //虚拟的,受保护的, qt5.2
    QAbstractScrollArea::viewportSizeHint()的重新实现。返回视口的大小提示(不含滚动条)

  • virtual bool viewportEvent(QEvent *event); //虚拟的,受保护的
    QAbstractScrollArea::viewportEvent()的重新实现。若 event 是 QEvent::ToolTip 或QEvent::WhatsThis,则此函数用于处理工具提示、 What’s this 模式,对于其他事件,则传递给父类的 viewportEvent()函数处理。

3.9 与外观有关的函数

  • virtual QStyleOptionViewItem viewOptions() const; //虚拟的,受保护的
    返回由视图的调色板(palette)、字体(font)、状态、对齐等填充的 QStyleOptionViewItem结构。

  • QSize sizeHintForIndex(const QModelIndex &index) const;
    返回索引 index 所指项目的大小提示或无效索引的无效大小

  • virtual int sizeHintForColumn(int column) const; //虚拟的
    返回列 column 的宽度大小提示,若没有模型,则返回-1,此函数用于具有水平标头的视图,以根据列 column 查找标头部分的大小提示。

  • virtual int sizeHintForRow(int row) const; //虚拟的
    返回行 row 的高度大小提示,若没有模型,则返回-1,此函数用于具有垂直标头的视图,以根据列 row 查找标头部分的大小提示。注意:要控制行的高度,必须重新实现QAbstractItemDelegate::sizeHint()函数。

  • void update(const QModelIndex &index) ; //槽
    更新索引 index 占用的区域

  • virtual void updateGeometries(); //槽, 虚拟的,受保护的
    更新视图的子部件的几何形状。

3.10 其他

  • QWidget* indexWidget(const QModelIndex &index) const;返回索引 index 处的 QWidget 部件。

  • void setIndexWidget(const QModelIndex &index, QWidget *widget);
    把部件 widget 设置到索引 index 所指项目上,并把部件 widget 的所有权传递给视口。若索引无效(比如根索引),则此函数什么也不做,必须把 widget 的 autoFillBackground属性设置为 true,否则部件的背景将是透明的。若部件 A 被替换为部件 B,则部件 A将被删除。

  • State state() const; //受保护的
    void setState(State state); //受保护的
    以上函数表示,返回或设置项目视图的状态,通常只在重新实现自已的视图时才有意义。枚举 State 见下表
    20221126173906

  • virtual void reset(); //槽, 虚拟的
    重置视图的内部状态。此函数将重置编辑器、滚动条位置、选择等,并且现在的更改不会被提交(即在编辑器中改变的数据不会提交给模型),若要在重置视图时保存更改,需要重新实现此函数。

  • virtual void keyboardSearch(const QString &search); //虚拟的
    移动并选择与字符串 search 最匹配的项,若没有该项目,则什么都不会发生。在默认实现中,若 search 为空,或自上次搜索以后的时间间隔超过QApplication::keyboardInputInterval(),则会重置搜索。

  • virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector()); //槽, 虚拟的,受保护的
    当在模型中更改具有角色 roles 的项目时,会调用此槽函数,更改的项目范围为 topLeft到 bottomRight,若只有一个项目被改变,则 topLeft == bottomRight。若 roles 为空,则意味着所有项目都已更改。

  • virtual currentChanged(const QModelIndex &current, const QModelIndex &previous); //槽, 虚拟的,受保护的
    当新项目成为当前项目时,会调用此槽函数, previous 表示上一个当前项目, current表示新项目。

  • virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); //槽, 虚拟的,受保护的
    当行即将被移除时,调用此槽函数,移除的行是父级 parent 下从 start 开始到 end 结束的行。

  • virtual void rowsInserted(const QModelIndex &parent, int start, int end); //槽, 虚拟的,受保护的
    在插入行时调用此槽函数,新行是父级 parent 下从 start 开始到 end 结束的行。

  • void executeDelayedItemsLayout(); //受保护的
    执行预定的布局(Scheduled Layout),而无需等待事件处理开始。

  • void scheduleDelayedItemsLayout(); //受保护的
    计划视图中项目的布局,以便在事件处理开始时执行。即使在事件处理之前多次调用该函数,视图也只会执行一次布局。

3.11 重新实现的父类中的函数

  • 以下函数为重新实现的 QWidget 类中的相关函数。

    • virtual void dragEnterEvent(QDragEnterEvent* event); //虚拟的,受保护的
    • virtual void dragLeaveEvent(QDragLeaveEvent* event); //虚拟的,受保护的
    • virtual void dragMoveEvent(QDragMoveEvent* event); //虚拟的,受保护的
    • virtual void dropEvent(QDropEvent* event); //虚拟的,受保护的
    • virtual void focusInEvent(QFocusEvent *event); //虚拟的,受保护的
    • virtual focusNextPrevChild(bool next);//虚拟的,受保护的
    • virtual focusOutEvent(QFocusEvent *event);//虚拟的,受保护的
    • virtual void inputMethodEvent(QInputMethodEvent *event); //虚拟的,受保护的
    • virtual Qvariant inputMethodQuery(Qt::InputMethodQuery query); //虚拟的
    • virtual void keyPressEvent(QKeyEvent *event); //虚拟的,受保护的
    • virtual void mouseMoveEvent(QMouseEvent *event); //虚拟的,受保护的
    • virtual void resizeEvent(QResizeEvent *event); //虚拟的,受保护的
  • virtual void mouseDoubleClickEvent(QMouseEvent *event); //虚拟的,受保护的
    若双击位于有效项目上,该函数会发送 QAbstractItemView::doubleClicked()信号,并调用该项目上的 edit()函数。

  • virtual void mousePressEvent(QMouseEvent *event); //虚拟的,受保护的
    该函数会发送 QAbstractItemView::pressed()信号

  • virtual void mouseReleaseEvent(QMouseEvent *event); //虚拟的,受保护的
    若项目被按下,该函数会发送 QAbstractItemView::clicked()信号。

  • virtual void timerEvent(QTimerEvent *event); //虚拟的,受保护的
    该函数为重新实现的 QObject 类中的相关函数。

四、QAbstractItemView类中的信号

  • void pressed(const QModelIndex &index) ; //信号
    当按下鼠标时,发送此信号, index 为鼠标按下的项目索引,只有索引有效时才会发送此信号,可使用 QApplication::mouseButtons()函数来获取按下鼠标按钮的状态。

  • void clicked(const QModelIndex &index); //信号
    当单击鼠标左键时发出此信号, index 为鼠标点击时的项目索引,只有索引有效时才会发送此信号。

  • void activated(const QModelIndex &index); //信号
    当用户激活索引 index 指定的项目时,发送此信号,如何激活信号取决于平台,通常可以双击若按下回车键激活项目。

  • void viewportEntered(); //信号
    当鼠标进入视口时,发送此信号,需启用鼠标跟踪功能才能使用此信号。

  • void entered(const QModelIndex &index); //信号
    当鼠标进入索引index指定的项目时,发送此信号,需启用鼠标跟踪功能才能使用此信号。

  • void doubleClicked(const QModelIndex &index); //信号
    双击鼠标时,发送此信号, index 表示双击的项目的索引,只有在 index 有效时,才会发送此信号。

五、经常使用的函数

QAbstractItemView 类中的函数虽然比较多,但由于受保护的函数只能在子类化时在子类的成员函数中调用,因此若不自定义视图,而使用 Qt 预定义的标准视图(比如 QTableView 等),则能使用的函数就并不多了,现整理如下:
20221126174736

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

smart_cat

你的鼓励将是我写作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值