Wiki

Property Model

Версия:
Сайт: ссылка...
Лицензия:

Автор: Swappp
Тема обсуждения: Свое творение на тему свойств что ли выложить?

Вот что получилось. В комплекте класс PropertiesModel и PropertiesDelegate и простой пример.


Первый - модель, второй - делегат, в который добавлен выпадающей список для enum'ов.

При создании модели, в конструктор передается объект, свойства которого надо изменять и отображать. Свойства соответственно описываются стандартным для Qt образом с обязательным указанием флага USER. Для реализации вложенных свойств создается ReadOnly свойство типа QObject*, который хранит указатель на другой объект со свойствами. Для использование свойств типа enum, надо соответствующий enum объявить с помощью Q_ENUMS.

Пока есть две проблемы:
1. На сколько критично правильное число строк выдаваемое rowCount()? На текущей момент выдается число всех свойств, а индексы создаются только для свойств с флагом USER.
2. Есть некоторые проблемы с вложенными свойствами. По задаче, для которой я это делал, требуется, при изменении одного из параметров заменять объект в одном из свойств на новый, возможно другого типа. Так вот, если есть только один уровень вложенности, то проблем не возникает, просто при изменении любого параметра генерируется сигнал layoutChanged, а при большем уровне вложенности (когда все открыто), все вылетает... Есть вариант все сворачивать, но это не очень удобно... Так же можно попробовать вообще запретить пользователю сворачивание, и тогда все сворачивать перед изменением и разворачивать после.

Пример использования:
example.h

#include <QObject>
#include <QString>
#include <QDate>
 
class TestString : public QObject
{
	Q_OBJECT
	Q_PROPERTY(QString string_property READ getStringProperty WRITE setStringProperty USER true)
public:
	QString getStringProperty()
	{
		return string_property;
	}
	void setStringProperty(QString v)
	{
		string_property = v;
	}
private:
	QString string_property;
};
 
class TestDate : public QObject
{
	Q_OBJECT
	Q_PROPERTY(QDate date_property READ getDateProperty WRITE setDateProperty USER true)
public:
	QDate getDateProperty()
	{
		return date_property;
	}
	void setDateProperty(QDate v)
	{
		date_property = v;
	}
private:
	QDate date_property;
};
 
class TestObject : public QObject
{
	Q_OBJECT
	Q_ENUMS(TestEnum)
	Q_PROPERTY(int int_property READ getIntProperty WRITE setIntProperty USER true)
	Q_PROPERTY(double double_property READ getDoubleProperty WRITE setDoubleProperty USER true)
	Q_PROPERTY(TestEnum enum_property READ getEnumProperty WRITE setEnumProperty USER true)
	Q_PROPERTY(QObject* object_property READ getObjectProperty USER true)
public:
	enum TestEnum { string, date };
 
	TestObject() : int_property(0), double_property(0), enum_property(date), object_property(0)
	{
		setEnumProperty(string);
	}
	int getIntProperty()
	{
		return int_property;
	}
	double getDoubleProperty()
	{
		return double_property;
	}
	TestEnum getEnumProperty()
	{
		return enum_property;
	}
	QObject* getObjectProperty()
	{
		return object_property;
	}
	void setIntProperty(int v)
	{
		int_property = v;
	}
	void setDoubleProperty(double v)
	{
		double_property = v;
	}
	void setEnumProperty(TestEnum v)
	{
		if (enum_property != v)
		{
			enum_property = v;
			delete object_property;
			if (enum_property == string)
				object_property = new TestString;
			else
				object_property = new TestDate;
			object_property->setParent(this);
		}
	}
private:
	int int_property;
	double double_property;
	TestEnum enum_property;
	QObject* object_property;
};

Example.cpp

#include <QApplication>
#include <QTreeView>
#include "properties.h"
#include "example.h"
 
int main(int argc, char *argv[])
{
	QApplication app(argc, argv);
	QTreeView view;
	QObject *o = new TestObject;
	view.setModel(new PropertiesModel(o));
	view.setItemDelegate(new PropertiesDelegate());
	view.show();
	return app.exec();
}

Скачать...