Qt5Demo-如何创建QColorFactory

Color Editor Factory Example

本例程展示了了如何使用QItemDelegate来创建一个编辑控件
例程概览
当我们在QListView, QTableView,或者QTreeView中编辑数据时,编辑控件是通过委托来创建和显示的,QItemDelegate是Qt自己的一个默认的Item View,我们可以使用QItemEditorFactory来创造一个编辑控件,一个独立的由QItemEditorFactory创建的实例默认被用在所有的委托上。
一个 item editor factory 包含了一系列的QItemEditorCreatorBase的实例,QItemEditorC热at而是一个专业的生产编辑控件的工厂,他可以提供针对一种QVariant数据类型的专门的编辑控件(所有的在Qt中储存的模型都存放的是QVariant类型的数据),一个编辑控件可以是任何Qt或者其他的widget。
在这个例程中,我们创造了一个编辑控件(在ColorListEditor 类中实现),它可以编辑QColor的数据类型,且通过QitemDelegates来使用,我们要做的是通过创建一个新的QItemEditorCreatorBase,并使用它来生产ColorListEditors,并且把它登记为一个新的工厂,随后我们把这个工厂设置为默认的item编辑工厂(唯一的工厂实例),为了测试我们的编辑器,我们把它应用在一个Window类中,他可以把这个编辑控件应用在一个QTableWidget中,然后我们就可以使用这个控件来设置QColor

Window Class 的实现

在window类中,我们针对我们的color editor创建了一个item编辑控件并且将它添加到默认的工厂中,我们同样创造了一个QTableWidget,来测试我们的编辑控件,他将会存放一些数据并且显示在window中。
我们来进一步看看代码:

  Window::Window()
  {
      QItemEditorFactory *factory = new QItemEditorFactory;

      QItemEditorCreatorBase *colorListCreator =
          new QStandardItemEditorCreator<ColorListEditor>();

      factory->registerEditor(QVariant::Color, colorListCreator);

      QItemEditorFactory::setDefaultFactory(factory);

      createGUI();
  }

QStandarditemEditorCrator是一个继承于 QItemEditorCreatorBase的实例类,它的构造函数中有一个模板类,在这个类中,所有的实例都是由createWidget()返回的,这个creator使用一个构造函数,并将QWidget作为它唯一的参数,这个模板类必须提供这些,这样,我们就不需要一个QStandardItemEditorCreator的子类了。
在这个工厂设置以后,所有标准的item委托都会用它(尽管有的委托是在这个工厂创造之前创造的)
createGUI()函数设置table并且将数据填写到里面

ColorListEditor定义

ColorListEditor继承于QComboBox并且允许用户去在下拉菜单中选择QColor

  class ColorListEditor : public QComboBox
  {
      Q_OBJECT
      Q_PROPERTY(QColor color READ color WRITE setColor USER true)

  public:
      ColorListEditor(QWidget *widget = nullptr);

  public:
      QColor color() const;
      void setColor(const QColor &color);

  private:
      void populateList();
  };

QItemDelegate 负责控制编辑控件和模型,比如它从model中检索数据,且从model中的编辑控件中储存数据,一个编辑控件它编辑的数据储存在这个编辑控件的用户数据属性中,且它的委托使用Qt的属性系统通过名称来访问它,我们使用Q_PROPERTY宏来声明我们的数据属性,这个属性通过USER关键词被设置成为用户类型。

ColorListEditor 的实现

在ColorListEditor的构造函数中,我们只调用populateList()这个函数,这个我们后面再谈,我们先看Color()函数

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

We return the data that is selected in the combobox. The data is stored in the Qt::DecorationRole as the color is then also displayed in the popup list (as shown in the image above).

  void ColorListEditor::setColor(const QColor &color)
  {
      setCurrentIndex(findData(color, Qt::DecorationRole));
  }

The findData() function searches the items in the combobox and returns the index of the item that has color in the Qt::Decoration role.

  void ColorListEditor::populateList()
  {
      const 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);
      }
  }

Qt通过名称可以知道一些预先定义的颜色,我们仅仅通过轮询的方式来添加到我们的编辑控件中

Further Customization of Item View Editors

你可以定制Qt的模型显示框架通过多种方式,在这个实例中展示的程序可以展示定制的编辑控件,更多的定制化可以通过对QItemEditorFactory和QItemEditorCreaterBase这两个类进行派生,也可以通过对QItemDelegate类进行派生,如果你想使用工厂模式来创建的话
一些建议:

  • 如果编辑控件窗口用户没有对其进行事前定义,委托将会使用它的属性名称对工厂进行询问,在这种情况下,你可以使用QItemEditorCreator类,他会使用属性名进行编辑。作为构造函数的依据。
  • 如果编辑控件需要其他的构造函数或者初始化函数而不是由QItemEditorCreatorBase来提供,一定要重用QItemEditorCreatorBase::createWidget().
  • 你也可以对QItemEditorFactory进行派生,如果你仅仅想针对特定的数据类型提供一个编辑控件,或者使用其他的创造编辑控件的方法。

在这个例子中,我们使用了标准的QVariant数据类型,你也可以使用其他的数据类型,在StarDelegateExample中,我们展示了如何在QVariant中储存其他的数据类型,并且绘制编辑这个类继承于QItemDelegate。

github链接

https://github.com/chechem3/tableview_add_combox

代码

  • ColorListEditor.h
#pragma once

#include <QComboBox>

QT_BEGIN_NAMESPACE
class QColor;
class QWidget;
QT_END_NAMESPACE

class ColorListEditor : public QComboBox
{
	Q_OBJECT
	Q_PROPERTY(QColor color READ color WRITE setColor USER true)

public:
	ColorListEditor(QWidget *parent);
	~ColorListEditor();

public:
	QColor color() const;
	void setColor(const QColor &color);

private:
	void populateList();
};

  • ColorListEditor.cpp
#include "ColorListEditor.h"
#include <qwidget.h>

ColorListEditor::ColorListEditor(QWidget *parent)
	: QComboBox(parent)
{
	populateList();
}

ColorListEditor::~ColorListEditor()
{
}

QColor ColorListEditor::color() const
{
	return qvariant_cast<QColor>(itemData(currentIndex(), Qt::DecorationRole));
	//qvariant_cast<T>(const QVariant &value)这个函数功能是将value转换为<T>
	//Qt::DecorationRole是QT的命名空间中的一个枚举变量,每一个在model中的item
	//都有一个关联数据的单元的设置,每一个都有自己的角色,这个角色被view用来表明
	//model中的何种类型的data数据是需要的,定制的模型需要返回如下类型的数据
	//预先定义的角色(和关联类型)如下::可以看官方的Qt名称空间的定义
}

void ColorListEditor::setColor(const QColor & color)
{
	setCurrentIndex(findData(color, Qt::DecorationRole));
	//设置选中的combox index
}

void ColorListEditor::populateList()
{
	const QStringList colorNames = QColor::colorNames();
	//QColor::colorNames()里面包含了预先定义的颜色列表

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

  • Window.h
#pragma once

#include <QtWidgets/QWidget>
#include "ui_Window.h"

class Window : public QWidget
{
	Q_OBJECT

public:
	Window(QWidget *parent = Q_NULLPTR);

private:
	Ui::WindowClass ui;
	void creatGUI();
};

  • Window.cpp
#include "Window.h"
#include "ColorListEditor.h"
#include <qitemeditorfactory.h>
#include <qvector.h>

#include <qwidget.h>
#include <QTableWidgetItem>

Window::Window(QWidget *parent)
	: QWidget(parent)
{
	//ui.setupUi(this);

	QItemEditorFactory *factory = new QItemEditorFactory;
	//QItemEditorFactory类提供了一个用来编辑在view和代理中的item数据
	//当我们在itemview中通过委托编辑和显示数据时,QStyledItem是一个默认安装在Qt的
	//item view中的委托,我们使用QItemEditorFactory类来创一个关于它的一个编辑
	//原来有一个默认的编辑,如果用户新建编辑的话,将会替代原来的规则
	//当我们需要自定义view的规则的时候,可以考虑使用这种方式来编辑

	QItemEditorCreatorBase *colorListCreator =
		new QStandardItemEditorCreator<ColorListEditor>;
	//QItemEditorCreatorBase类提供了一个抽象的基类,当我们创建item editor creators
	//的时候必须派生出新的子类

	factory->registerEditor(QVariant::Color, colorListCreator);
	//registerEditor::注册一个item editor creator通过QItemEditorCreatorBase
	//指定的用户需要的数据格式

	QItemEditorFactory::setDefaultFactory(factory);
	//设置默认的编辑factory通过给定的factory

	ui.setupUi(this);
	creatGUI();
}

void Window::creatGUI()
{
	const QVector<QPair<QString, QColor>> list = 
	{
		{tr("Alice"), QColor("aliceblue")},
		{tr("Neptun"), QColor("aquamarine")},
		{tr("Ferdinand"), QColor("springgreen")}
	};
	//QPair::是一个可以储存成对数据的模板类
	
	ui.tableWidget->setRowCount(3);
	ui.tableWidget->setColumnCount(2);

	ui.tableWidget->setHorizontalHeaderLabels({ tr("Name"), tr("Hair Color") });
	ui.tableWidget->verticalHeader()->setVisible(false);
	ui.tableWidget->resize(150, 50);
	//setHorizontalHeaderLabels::设置横向头标签
	//verticalHeader()::指向纵向头,然后设置消失

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

		QTableWidgetItem *nameItem = new QTableWidgetItem(pair.first);
		QTableWidgetItem *colorItem = new QTableWidgetItem;
		colorItem->setData(Qt::DisplayRole, pair.second);
		//这是使用了setdata的按照role的方式去添加data的方式

		ui.tableWidget->setItem(i, 0, nameItem);
		ui.tableWidget->setItem(i, 1, colorItem);
	}

	ui.tableWidget->resizeColumnToContents(0);
	//resizeColumnToContents::按照给定的委托设置去重新绘制/调整列

	ui.tableWidget->horizontalHeader()->setStretchLastSection(true);
	//setStretchLastSection::这个属于tableview的横轴头的设置,设置为true
	//后,最后一列的头文件将会无限延伸

	setWindowTitle(tr("Color Editor Factory"));
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值