Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - *QT* | Как сделать свой QAbstractItemModel

Ответить
Настройки темы
C/C++ - *QT* | Как сделать свой QAbstractItemModel
pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Вопрос знатокам QT4: я хочу изображать группы объектов в виде дерева, для этого в SQL хранится табличка типа
Код: Выделить весь код
create table person_path
(
    id          integer identity(1,1) primary key,
    path_id     integer references person_path(id),
    name        varchar(30) not null,
    comment     varchar(255),
    constraint unique_person_path unique (path_id, name)
);
как теперь сделать из QSqlQueryModel такую модель, чтобы она отображалась в виде дерева? я вырезал из примеров кусок кода, который делает подобное, но не впираю, что за что отвечает. Растусуйте, пожалуйста.
Код: Выделить весь код
Model::Model(int rows, int columns, QObject *parent)
    : QAbstractItemModel(parent),
      rc(rows), cc(columns),
      tree(new QVector<Node>(rows, Node(0)))
{

}

Model::~Model()
{
    delete tree;
}

QModelIndex Model::index(int row, int column, const QModelIndex &parent) const
{
    if (row < rc && row >= 0 && column < cc && column >= 0) {
        Node *p = static_cast<Node*>(parent.internalPointer());
        Node *n = node(row, p);
	if (n)
	    return createIndex(row, column, n);
    }
    return QModelIndex();
}

QModelIndex Model::parent(const QModelIndex &child) const
{
    if (child.isValid()) {
        Node *n = static_cast<Node*>(child.internalPointer());
        Node *p = parent(n);
        if (p)
            return createIndex(row(p), 0, p);
    }
    return QModelIndex();
}

int Model::rowCount(const QModelIndex &parent) const
{
    return (parent.isValid() && parent.column() != 0) ? 0 : rc;
}

int Model::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return cc;
}

QVariant Model::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();
    if (role == Qt::DisplayRole)
	return "Item " + QString::number(index.row()) + ":" + QString::number(index.column());
    if (role == Qt::DecorationRole) {
        if (index.column() == 0)
            return iconProvider.icon(QFileIconProvider::Folder);
        return iconProvider.icon(QFileIconProvider::File);
    }
    return QVariant();
}

QVariant Model::headerData(int section, Qt::Orientation orientation, int role) const
{
    static QIcon services(QPixmap(":/images/services.png"));
    if (role == Qt::DisplayRole)
        return QString::number(section);
    if (role == Qt::DecorationRole)
        return qVariantFromValue(services);
    return QAbstractItemModel::headerData(section, orientation, role);
}

bool Model::hasChildren(const QModelIndex &parent) const
{
    if (parent.isValid() && parent.column() != 0)
        return false;
    return rc > 0 && cc > 0;
}

Qt::ItemFlags Model::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return 0;
    return (Qt::ItemIsDragEnabled|Qt::ItemIsSelectable|Qt::ItemIsEnabled);
}

Model::Node *Model::node(int row, Node *parent) const
{
    if (parent && !parent->children)
	parent->children = new QVector<Node>(rc, Node(parent));
    QVector<Node> *v = parent ? parent->children : tree;
    return const_cast<Node*>(&(v->at(row)));
}

Model::Node *Model::parent(Node *child) const
{
    return child ? child->parent : 0;
}

int Model::row(Node *node) const
{
     const Node *first = node->parent ? &(node->parent->children->at(0)) : &(tree->at(0));
     return (node - first);
}

Отправлено: 13:06, 25-03-2008

 

Новый участник


Сообщения: 3
Благодарности: 0

Профиль | Отправить PM | Цитировать


// Получение индекса класса QModelIndex по номеру строки и номеру колонки для родительского элемента parent
// примечание: данный метод вызывает виджет отображения при обходе модели данных
QModelIndex Model::index(int row, int column, const QModelIndex &parent) const
{
if (row < rc && row >= 0 && column < cc && column >= 0) {
Node *p = static_cast<Node*>(parent.internalPointer());
Node *n = node(row, p);
if (n)
return createIndex(row, column, n);
}
return QModelIndex();
}

// Получить родительский элемент класса QModelIndex для подчиненного элемента child
QModelIndex Model::parent(const QModelIndex &child) const
{
if (child.isValid()) {
Node *n = static_cast<Node*>(child.internalPointer());
Node *p = parent(n);
if (p)
return createIndex(row(p), 0, p);
}
return QModelIndex();
}

// получить количество подчиненных элементов для узла parent
int Model::rowCount(const QModelIndex &parent) const
{
return (parent.isValid() && parent.column() != 0) ? 0 : rc;
}

// получить количество отображаемых колонок с данными для узла parent
// здесь можно было установить количество данных, которое содержит каждый узел,
// например список строк или количество полей из таблицы
int Model::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return cc;
}

// получить данные узла index для роли данных role
//примечание: именно здесть виджет получает данные из узла
QVariant Model::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role == Qt::DisplayRole) // отображаемое значение
return "Item " + QString::number(index.row()) + ":" + QString::number(index.column());
if (role == Qt::DecorationRole) { // в данном случае декорация это иконка - а можно что угодно
if (index.column() == 0)
return iconProvider.icon(QFileIconProvider::Folder);
return iconProvider.icon(QFileIconProvider::File);
}
return QVariant(); // для других ролей пустое значение, а лучше вызвать родительский метод
}

// получить данные для заголовка виджета отображения модели с номером колонки или строки section
// ориентацией по колонкам или по строкам и роли получаемых данных role
// примечание: чаще всего имеет значение только для корневого узла. Или выдавать значение заголовков для встраиваемых виджетов
QVariant Model::headerData(int section, Qt::Orientation orientation, int role) const
{
static QIcon services(QPixmap(":/images/services.png"));
if (role == Qt::DisplayRole)
return QString::number(section);
if (role == Qt::DecorationRole)
return qVariantFromValue(services);
return QAbstractItemModel::headerData(section, orientation, role);
}

// Проверка на наличие подчиненных узлов для узла parent
// <Не обязательный метод - достаточно перекрыть rowCount>
bool Model::hasChildren(const QModelIndex &parent) const
{
if (parent.isValid() && parent.column() != 0)
return false;
return rc > 0 && cc > 0;
}

// Установить свойства для узла index
// в данном случае это: может выбираться и может быть активным
Qt::ItemFlags Model::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
return (Qt::ItemIsDragEnabled|Qt::ItemIsSelectable|Qt::ItemIsEnabled);
}

//__________________________________________________
// Это, как я понял, методы доступа к данным каждого узла
// которые будут закрепляться за QModelIndex

Model::Node *Model::node(int row, Node *parent) const
{
if (parent && !parent->children)
parent->children = new QVector<Node>(rc, Node(parent));
QVector<Node> *v = parent ? parent->children : tree;
return const_cast<Node*>(&(v->at(row)));
}

Model::Node *Model::parent(Node *child) const
{
return child ? child->parent : 0;
}

int Model::row(Node *node) const
{
const Node *first = node->parent ? &(node->parent->children->at(0)) : &(tree->at(0));
return (node - first)

Отправлено: 10:29, 14-05-2008 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.

pva pva вне форума Автор темы

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Как можно эту штуку скрестить с SQL-запросом?

Отправлено: 15:06, 14-05-2008 | #3


Новый участник


Сообщения: 3
Благодарности: 0

Профиль | Отправить PM | Цитировать


Вложения
Тип файла: gz treemodels.tar.gz
(3.8 Kb, 195 просмотров)

Например вот так..))

Отправлено: 07:10, 28-05-2008 | #4


Новый участник


Сообщения: 3
Благодарности: 0

Профиль | Отправить PM | Цитировать


http://forum.oszone.net/attachment.p...1&d=1211951234

Отправлено: 07:11, 28-05-2008 | #5



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - *QT* | Как сделать свой QAbstractItemModel

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Как сделать свой сервак Bars66 Флейм 19 25-10-2009 12:20
Как сделать свой всплывающий банер re5pect Вебмастеру 5 23-01-2009 20:46
Прочее - Как сделать свой сервер Andrei076 Сетевые технологии 2 07-06-2008 22:52
Интерфейс - Как сделать свой пак иконок? Cesc Microsoft Windows 2000/XP 7 25-11-2007 12:09
Как мне сделать в инете свой сайт? Yewgeniy Вебмастеру 28 29-01-2007 00:03




 
Переход