Qt模型视图框架:QHeaderView、QItemEditorFactory、QItemDelegate

QHeaderView

一、描述

QHeaderView 显示项目视图(如QTableView、QTreeView)中使用的标题。

标头使用 QAbstractItemModel::headerData() 函数从模型中获取每个部分的数据。可以使用 QAbstractItemModel::setHeaderData() 设置数据。

对于水平标题,该部分相当于模型中的一列,对于垂直标题,该部分相当于模型中的一行。

移动标题部分

标题可以固定到位,也可以使用 setSectionsMovable() 移动。它可以通过 setSectionsClickable() 设置为可点击,并根据 setSectionResizeMode() 具有调整大小的行为。

外观

QTableWidget 和 QTableView 会创建默认标题。如果希望标题可见,调用 setVisible()。

并非所有 ItemDataRoles 都会对 QHeaderView 产生影响。 如果需要绘制其他角色,可以继承QHeaderView,重新实现paintEvent()。 QHeaderView 可用以下项目数据角色,除非它们与样式冲突(这可能发生在遵循桌面主题的样式中):

  • TextAlignmentRole
  • DisplayRole
  • FontRole
  • DecorationRole
  • ForegroundRole
  • BackgroundRole

注意:每个标头为每个部分本身呈现数据,并且不依赖于委托。 因此,调用标头的 setItemDelegate() 函数将不起作用。

二、类型成员

1、enum QHeaderView::ResizeMode:调整大小模式指定标题部分的行为。

  • Interactive:用户可以调整节的大小。也可以使用 resizeSection() 以编程方式调整该部分的大小。
  • Fixed:用户无法调整该部分的大小。该部分只能使用 resizeSection() 以编程方式调整大小。
  • Stretch:将自动调整该部分的大小以填充可用空间。 用户或以编程方式无法更改大小。
  • ResizeToContents:将根据整列或整行的内容自动将节调整为最佳大小。 用户或以编程方式无法更改大小。

三、属性成员

1、cascadingSectionResizes : bool

此属性保存一旦用户调整大小的部分达到其最小大小,交互式调整大小是否影响其他部分。

此属性仅影响将 Interactive 作为其调整大小模式的部分。

默认值为false。

QTableView view;
QStandardItemModel *model = new QStandardItemModel(&view);
model->setColumnCount(3);
model->setRowCount(3);

QHeaderView * header = new QHeaderView(Qt::Horizontal);
header->setSectionResizeMode(QHeaderView::Interactive);
header->setCascadingSectionResizes(false);

view.setHorizontalHeader(header);

for (int i = 0;i < 3;++i)
{
for (int j = 0;j < 3;++j)
{
model->setData(model->index(i,j),"data");
}
}

view.setModel(model);
view.show();

header->setCascadingSectionResizes(true);

 

2、defaultAlignment : Qt::Alignment

此属性保存每个标题部分中文本的默认对齐方式。

3、defaultSectionSize : int

  • 此属性在调整大小之前保存标题部分的默认大小。
  • 此属性仅影响将 Interactive 或 Fixed 作为其调整大小模式的部分。

默认情况下,此属性的值取决于样式。因此,当样式更改时,此属性会随之更新。调用 setDefaultSectionSize() 停止更新,调用 resetDefaultSectionSize() 将恢复默认行为。

4、firstSectionMovable : bool

  • 该属性保存第一列是否可以被用户移动。
  • 此属性控制用户是否可以移动第一列。

在 QTreeView 中,第一列包含树结构,因此默认情况下是不可移动的,即使在 setSectionsMovable(true) 之后也是如此。通过调用此方法,它可以再次移动。在这种情况下,建议同时调用QTreeView::setRootIsDecorated(false)。

除非 setSectionsMovable(true) 也被调用,否则将其设置为 true 并不起作用。

5、highlightSections : bool

此属性保存是否突出显示包含所选项目的部分。默认为 false。

6、maximumSectionSize : int

此属性保存标题部分的最大大小。

此属性的默认值为 1048575,这也是最大大小。将最大值设置为 -1 会将值重置为最大大小。

除 stretch 外,所有调整大小模式都支持此属性。

7、minimumSectionSize : int

此属性保存标题部分的最小大小。

所有调整大小模式都支持此属性。

8、showSortIndicator : bool

此属性保存是否显示排序指示器。默认为 false。

9、sortIndicatorClearable : bool

此属性保存是否可以通过多次单击某个部分来清除排序指示器。

通常,单击某个部分只会更改该部分的排序顺序。通过将此属性设置为true,排序指示器将在升序和降序交替后清除。这通常会恢复模型的原始排序。

将此属性设置为 true 无效,除非sectionClickable() 也为true。

10、stretchLastSection : bool

此属性保存标题中最后一个可见部分是否占用所有可用空间。默认值为false。

如果此值设置为 true,则此属性将覆盖标题中最后一部分设置的调整大小模式。

注意: QTreeView 提供的水平标题配置为将此属性设置为 true,以确保视图不会浪费为其标题分配的任何空间。

四、成员函数

4.1、信号

1、void geometriesChanged()

当标题的几何形状发生变化时,会发出此信号。

2、void sectionClicked(int logicalIndex)

单击某个部分时会发出此信号。

请注意,sectionPressed() 信号也将被发出。

3、void sectionCountChanged(int oldCount, int newCount)

当列的数量发生变化时,即添加或删除节时,会发出此信号。

4、void sectionDoubleClicked(int logicalIndex)

双击某个部分时会发出此信号。

5、void sectionEntered(int logicalIndex)

当光标移动到该部分上并按下鼠标左键时,会发出该信号。

6、void sectionHandleDoubleClicked(int logicalIndex)

双击某个部分时会发出此信号。

7、void sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex)

当移动部分时发出此信号。

8、void sectionPressed(int logicalIndex)

当按下某个部分时会发出此信号。

9、void sectionResized(int logicalIndex, int oldSize, int newSize)

调整部分大小时会发出此信号。

10、void sortIndicatorChanged(int logicalIndex, Qt::SortOrder order)

当包含排序指示符或指示的顺序的部分发生更改时,会发出此信号。

4.2、函数

1、void headerDataChanged(Qt::Orientation orientation, int logicalFirst, int logicalLast)

使用给定的方向更新已更改的标题部分,从logicalFirst 到logicalLast 包含在内。

2、void setOffset(int offset)

设置标头的偏移量。

3、void setOffsetToLastSection()

设置偏移量以使最后一个部分可见。

4、int count()

标题节数。

5、int hiddenSectionCount()

返回标题中已隐藏的节数。

6、void hideSection(int logicalIndex) / void showSection(int logicalIndex)

隐藏/显示由 logicalIndex 指定的部分。

7、bool isSectionHidden(int logicalIndex)

某部分是否已经隐藏。

8、int length()

返回沿标题方向的长度。

9、QByteArray saveState() / bool restoreState(const QByteArray &state)

保存/恢复标题状态。

10、int sectionSize(int logicalIndex)

返回给定逻辑索引的宽度(或垂直标题的高度)。

11、void setResizeContentsPrecision(int precision)

设置使用 ResizeToContents 时计算大小的精确度。较低的值将提供不太准确但快速的自动调整大小,而较高的值将提供更准确的调整大小,但可能会很慢。

默认值为 1000,这意味着在执行自动调整大小时,具有自动调整大小的水平列将在计算时查看最多 1000 行。

12、void swapSections(int first, int second)

交换两部分。

 本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

QItemEditorFactory

一、描述

在项目视图中编辑数据时,编辑器由委托创建和显示。 QStyledItemDelegate 是默认安装在 Qt 项目视图上的委托,它使用 QItemEditorFactory 为其创建编辑器。 所有项目委托都使用 QItemEditorFactory 提供的默认唯一实例。如果使用 setDefaultFactory() 设置新的默认工厂,则现有和新委托都将使用新工厂。

工厂保存一组 QItemEditorCreatorBase 实例,这些实例是专门的编辑器,可为一种特定的 QVariant 数据类型生成编辑器(所有 Qt 模型都将其数据存储在 QVariant 中)。

标准编辑小部件

标准工厂实现为各种数据类型提供了编辑器。每当委托需要为模型提供的数据提供编辑器时,就会创建编辑器。下面是类型与提供的标准编辑器之间的关系:

  • bool:QComboBox
  • double:QDoubleSpinBox
  • int、unsigned int:QSpinBox
  • QDate:QDateEdit
  • QDateTime:QDateTimeEdit
  • QPixmap:QLabel
  • QString:QLineEdit
  • QTime:QTimeEdit

可以使用 registerEditor() 函数注册其他编辑器。

二、示例

Color Editor Factory Example 这个demo演示了QItemEditorFactory用法。

class ColorListEditor : public QComboBox
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor USER true)
public:
ColorListEditor(QWidget *widget = nullptr);
QColor color() const;
void setColor(QColor c);
};

ColorListEditor::ColorListEditor(QWidget *widget) : QComboBox(widget)
{
QStringList colorNames = QColor::colorNames();
for (int i = 0; i < colorNames.size(); ++i)
{
QColor color(colorNames[i]);
insertItem(i, colorNames[i]);
setItemData(i, color, Qt::DecorationRole);
}
}

QColor ColorListEditor::color() const
{
return qvariant_cast<QColor>(itemData(currentIndex(), Qt::DecorationRole));
}

void ColorListEditor::setColor(QColor color)
{
setCurrentIndex(findData(color, int(Qt::DecorationRole)));
}
Class Window : public QWidget
{
Q_OBJECT

public:
Window();
};

Window::Window()
{
QItemEditorFactory *factory = new QItemEditorFactory;
factory->registerEditor(QVariant::Color, new QStandardItemEditorCreator<ColorListEditor>());
QItemEditorFactory::setDefaultFactory(factory);

QList<QPair<QString, QColor> > list;
list << QPair<QString, QColor>(tr("Alice"), QColor("aliceblue")) <<
QPair<QString, QColor>(tr("Neptun"), QColor("aquamarine")) <<
QPair<QString, QColor>(tr("Ferdinand"), QColor("springgreen"));

QTableWidget *table = new QTableWidget(3, 2);
table->setHorizontalHeaderLabels(QStringList() << tr("Name")<< tr("Hair Color"));
table->verticalHeader()->setVisible(false);
table->resize(150, 50);

for (int i = 0; i < 3; ++i)
{
QPair<QString, QColor> pair = list.at(i);

QTableWidgetItem *nameItem = new QTableWidgetItem(pair.first);
QTableWidgetItem *colorItem = new QTableWidgetItem;
colorItem->setData(Qt::DisplayRole, pair.second);

table->setItem(i, 0, nameItem);
table->setItem(i, 1, colorItem);
}
table->resizeColumnToContents(0);
table->horizontalHeader()->setStretchLastSection(true);

QGridLayout *layout = new QGridLayout;
layout->addWidget(table, 0, 0);

setLayout(layout);
setWindowTitle(tr("颜色编辑工厂"));
}

QItemDelegate

一、描述

QItemDelegate 可用于为基于 QAbstractItemView 子类的项目视图提供自定义显示功能和编辑器小部件。请注意,QStyledItemDelegate 实现了绘制 Qt 项目视图的工作。因此建议在创建新委托时使用 QStyledItemDelegate 而不是使用QItemDelegate 。

在视图中显示来自自定义模型的项目时,通常只需确保模型为确定视图中项目外观的每个角色返回适当的数据就足够了。Qt 视图使用的默认委托使用此角色信息以用户期望的大多数常见形式显示项目。但是,有时需要对项目的外观进行比默认委托所能提供的更多的控制。

在视图中编辑数据时,QItemDelegate 提供了一个编辑器小部件,这是一个在编辑时放置在视图顶部的小部件。编辑器是用 QItemEditorFactory 创建的; QItemEditorFactory 提供的默认静态实例安装在所有项目委托上。

此类仅重新实现了基于小部件的委托的标准编辑功能:

  • createEditor():返回用于更改模型数据的小部件,并且可以重新实现以自定义编辑行为。
  • setEditorData():为小部件提供要操作的数据。
  • updateEditorGeometry():确保编辑器相对于项目视图正确显示。
  • setModelData():将更新的数据返回给模型。
  • closeEditor():信号表示用户已完成数据编辑,并且可以销毁编辑器小部件。

标准角色和数据类型

Qt 提供的标准视图使用的默认委托将每个标准角色(由 Qt::ItemDataRole 定义)与某些数据类型相关联。以这些类型返回数据的模型会影响委托的外观,如下所述:

  • Qt::BackgroundRole:QBrush
  • Qt::CheckStateRole:Qt::CheckState
  • Qt::DecorationRole:QIcon、QPixmap、QColor
  • Qt::DisplayRole:QString 和带有字符串表示的类型
  • Qt::EditRole:见QItemEditorFactory
  • Qt::FontRole:QFont
  • Qt::SizeHintRole:QSize
  • Qt::TextAlignmentRole:Qt::Alignment
  • Qt::ForegroundRole:QBrush

子类化

当子类化 QItemDelegate 以创建一个使用自定义渲染器显示项目的委托时,重要的是要确保该委托可以为所有必需的状态适当地呈现项目,例如选中、禁用、选中。

当需要自定义编辑器时,有两种方式实现:

不用子类化的方法:使用 QItemEditorFactory 提供自定义编辑器。

子类化的方法:子类化 QStyledItemDelegate 并重新实现 createEditor()、setEditorData()、setModelData() 和 updateEditorGeometry()。

二、成员函数

1、QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index)

创建并返回用于编辑由 index 指定项目的小部件。parent 和option用于控制编辑器小部件的显示方式。

2、void drawBackground(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)

使用painter和option呈现index的项目背景。

3、void drawCheck(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, Qt::CheckState state)

使用painter和option,使用state,在 rect 指定的矩形内呈现按下指示器。

4、void drawDecoration(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QPixmap &pixmap)

使用painter和option在 rect 指定的矩形内呈现装饰像素图。

5、void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text)

使用painter和option在 rect 指定的矩形内呈现项目视图文本。

6、void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect)

使用painter和option渲染由 rect 指定的矩形内的区域,指示它具有焦点。

7、bool eventFilter(QObject *editor, QEvent *event)

事件过滤器。如果editor是一个有效的 QWidget 并且给定的事件被处理,则返回 true,否则返回false。

默认处理以下按键事件:

  • Tab
  • Backtab
  • Enter
  • Return
  • Esc

在 Tab、Backtab、Enter、Return 键按下事件的情况下,编辑器的数据提交到模型并关闭编辑器。

如果是按下 Tab 键事件,则将打开视图中的下一项上编辑器。

如果是按下 Backtab 键事件,则将打开视图中的前一项的编辑器。

如果是按下 Esc 键事件,则编辑器将关闭而不提交其数据。

8、QItemEditorFactory * itemEditorFactory()

void setItemEditorFactory(QItemEditorFactory *factory)

项目委托使用的编辑器工厂。

9、void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)

使用painter和option为index指定的项目呈现委托。

当在子类中重新实现这个函数时,应该更新选项的 rect 变量持有的区域,使用option的状态变量来确定要显示的项目的状态,并相应地调整它的绘制方式。

例如,一个选中的项目可能需要与未选中的项目以不同的方式显示,如下面的代码所示:

if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
else
...

绘制后应确保返回到调用此函数时提供的状态。(QPainter::save() / QPainter::restore() )

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

原文链接:https://blog.csdn.net/kenfan1647/article/details/119641471

猜你喜欢

转载自blog.csdn.net/hw5230/article/details/131967764