Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Qt4] реализация собственной модели, Возможно наследование элементов модели? 
:(
    Опции темы
evilguard
Дата 22.3.2008, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 19.11.2006

Репутация: нет
Всего: нет



Реализую модель, от QAbstractItemModel - брал из стандартного примера. Там реализуется наследник от этого класса а также класс элемента с данными(допустим TreeItem). Каждый элемент содержит в себе QList<TreeItem*>children - список указателей на детей. Для реализации того поведения которое я хочу мне нужно было выделить отдельный подкласс этого класса, чтобы он вел себя как папка(директория) - а из TreeItem убрать возможность добаления "детей". Я унаследовал от TreeItem класс TreeFolderItem, соответственно из TreeItem убрал члена QList<TreeItem*>children, а также все функции связанные с возможностью манипулировать дочерними эжлементами. Соответственно в классе модели поменял во всех местах, где есть операции с детьми - на TreeFolderItem, при этом он наследует интерфейс TreeItem.
Но программа почему-то не заработала, вылетала после добавления одного этлемента в модель. Когда убрал класс потомок, и вернул весь функционал связанный с "детьми" в класс TreeItem все стало нормально. Посему вопрос - получается модель не поддерживает хранения элементов разных классов, но реализованных с общим интерфейсом?
PM MAIL   Вверх
SABROG
Дата 22.3.2008, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Наверно эту часть никто не читает, когда тему создает:

Цитата

    * В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
    * Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
    * Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
    * В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
    * Не забывайте пользоваться кнопкой "Код".
    * Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
    * Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
    * Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.


Т.е. я бы сначала разобрался в каком месте происходит краш, использую дебаггер, прежде чем думать, что Qt не поддерживает что-то.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
evilguard
Дата 22.3.2008, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 19.11.2006

Репутация: нет
Всего: нет



да, я прочел уже))
Код

#include <QList>
#include <QVariant>

class MObject;

class TreeFolderItem;
class Renderer;

class TreeItem
{
    public:
        TreeItem(MObject *object = 0, TreeFolderItem *parent = 0);
        virtual ~TreeItem();

        TreeFolderItem *parent() const { return parentItem; }
        void setParentItem(TreeFolderItem *parent) { parentItem = parent; }

        QVariant data(int role) const;
        void setData(int column, int role, const QVariant &value);

        int row() const;
        virtual void render(Renderer *renderer);

    private:
        MObject *m_pointer;
        bool m_checked;
        QString name;

        TreeFolderItem *parentItem;
};

class TreeFolderItem : public TreeItem
{
    friend class TreeModel;
    friend class TreeItem;

    public:
        TreeFolderItem(MObject *object = 0, TreeFolderItem *parent = 0);
        ~TreeFolderItem();

        void appendChild(TreeItem *child);
        TreeItem *child(int row);
        int childCount() const;
        
        void render(Renderer *renderer);

    private:
        QList<TreeItem*> children;
};


Код

#include <QIcon>
#include <QPixmap>

#include "treeitem.h"
#include "mobject.h"

TreeItem::TreeItem(MObject *object, TreeFolderItem *parent)
{
    parentItem = parent;
    m_checked = true;
    m_pointer = object;
}

TreeItem::~TreeItem()
{
    delete m_pointer;
}

void TreeItem::setData(int column, int role, const QVariant &value)
{
    if (column < 0)
        return;

    if (role == Qt::CheckStateRole)
    {
        m_checked = value.toInt()!=0 ? true : false;
    }
}

QVariant TreeItem::data(int role) const
{
    if (role == Qt::CheckStateRole)
        return m_checked? Qt::Checked : Qt::Unchecked;

    static QIcon folder(QPixmap("Images/folder.png"));
    if (role == Qt::DisplayRole)
        switch (m_pointer->type())
    {
        case MObject::Grid:
        case MObject::Polygon:
        case MObject::Model:
        case MObject::Property:
            return m_pointer->objectName;
        case MObject::Folder:
            return name;
        default:
            return QObject::tr("Unknown");
    }
    if (role == Qt::DecorationRole)
        return folder;
    return QVariant();
}

int TreeItem::row() const
{
    if (parent())
        return parent()->children.indexOf(const_cast<TreeItem*>(this));

    return 0;
}

void TreeItem::render(Renderer *renderer)
{
    m_pointer->Render(renderer);
}

/******************************************************
                TreeFolderItem
 ******************************************************/


TreeFolderItem::TreeFolderItem(MObject *object, TreeFolderItem *parent) :
        TreeItem(object, parent)
{

}

TreeFolderItem::~TreeFolderItem()
{
    qDeleteAll(children);
}

void TreeFolderItem::appendChild(TreeItem *item)
{
    children.append(item);
    item->setParentItem(this);
}

TreeItem *TreeFolderItem::child(int row)
{
    return children.value(row);
}

int TreeFolderItem::childCount() const
{
    return children.count();
}

void TreeFolderItem::render(Renderer *renderer)
{
    TreeItem *iterator;
    foreach(iterator, children)
        iterator->render(renderer);
}


Код

#include <QAbstractItemModel>
#include <QModelIndex>
#include <QVariant>

class TreeItem;
class TreeFolderItem;
class Renderer;
class MObject;

class TreeModel : public QAbstractItemModel
{
    Q_OBJECT

public:
    TreeModel(QObject *parent = 0);
    ~TreeModel();

    QVariant data(const QModelIndex &index, int role) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role);
    Qt::ItemFlags flags(const QModelIndex &index) const;
    QVariant headerData(int section, Qt::Orientation orientation,
                        int role = Qt::DisplayRole) const;
    QModelIndex index(int row, int column,
                      const QModelIndex &parent = QModelIndex()) const;
    QModelIndex index(const TreeItem *item, int column) const;

    QModelIndex parent(const QModelIndex &index) const;
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    TreeItem *itemFromIndex(const QModelIndex &index) const;

    bool appendTopLevelItem(TreeItem *item);
    void add(MObject *object);
    void Render(Renderer *renderer);

private:
    TreeFolderItem *rootItem;
};



Код

#include "treemodel.h"
#include "treeitem.h"
#include "glwidget3d.h"
#include "mobject.h"
#include "renderer.h"
#include "mabstractview.h"

TreeModel::TreeModel(QObject *parent)
    : QAbstractItemModel(parent)
{
    rootItem = new TreeFolderItem();
}

TreeModel::~TreeModel()
{
    delete rootItem;
}

int TreeModel::columnCount(const QModelIndex &parent) const
{
    return 1;
}

bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (!index.isValid())
        return false;
    TreeItem *item = itemFromIndex(index);
    if (item)
    {
        item->setData(index.column(), role, value);
        return true;
        }
        return false;
}

QVariant TreeModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    TreeItem *item = itemFromIndex(index);
    return item->data(role);
}

Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
/*    Qt::ItemFlags flags = QAbstractItemModel::flags(index); 
    if (index.column() == 0) 
        flags |= Qt::ItemIsUserCheckable; 
    return flags;*/
    return (Qt::ItemIsDragEnabled|Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsUserCheckable|Qt::ItemIsDropEnabled);
}

QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
                               int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
        if (section == 0)
            return tr("Список объектов");
    return QVariant();
}


QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)
            const
{
    TreeFolderItem *parentItem;

    if (!parent.isValid())
        parentItem = rootItem;
    else
        parentItem = static_cast<TreeFolderItem*>(parent.internalPointer());

    TreeItem *childItem = parentItem->child(row);
    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();
}

QModelIndex TreeModel::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();

    TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
    TreeFolderItem *parentItem = childItem->parent();

    if (parentItem == rootItem)
        return QModelIndex();

    return createIndex(parentItem->row(), 0, parentItem);
}

int TreeModel::rowCount(const QModelIndex &parent) const
{
    TreeFolderItem *parentItem;

    if (!parent.isValid())
        parentItem = rootItem;
    else
        parentItem = static_cast<TreeFolderItem*>(parent.internalPointer());

    return parentItem->childCount();
}

TreeItem *TreeModel::itemFromIndex(const QModelIndex &index) const
{
    if (index.isValid())
        return static_cast<TreeItem *>(index.internalPointer());
    else
        return rootItem;
}

QModelIndex TreeModel::index(const TreeItem *item, int column) const
{
    if (!item || (item == rootItem))
        return QModelIndex();
    const TreeFolderItem *par = item->parent();
    TreeItem *itm = const_cast<TreeItem*>(item);
    if (!par)
        par = rootItem;
    return createIndex(par->children.lastIndexOf(itm), column, itm);
}

bool TreeModel::appendTopLevelItem(TreeItem *item) 
{ 
    beginInsertRows(index(rootItem, 0), rootItem->children.count(), rootItem->children.count());
    rootItem->appendChild(item);
    endInsertRows();
    TreeItem *itm = rootItem->children.at(0);
    return true;
}
void TreeModel::add(MObject *object)
{
    TreeItem *item = new TreeItem(object);
    appendTopLevelItem(item);
}

void TreeModel::Render(Renderer *renderer)
{
    rootItem->render(renderer);
}



Добавлено @ 16:01
в обществе дебаггера я провел сегодня пол-дня 
Если запускать в режиме дебага в KDevelop - он выкидывает меня на файл qlist.h:
http://ipicture.ru/uploads/080322/CI6F2VgPda.png
Помогите заодно разобраться - что означает это - там красный кругляшок и зеленый треугольник - где произошла ошибка, я не пойму.

Это сообщение отредактировал(а) evilguard - 22.3.2008, 16:03
PM MAIL   Вверх
nickless
Дата 23.3.2008, 02:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 13
Всего: 181



Цитата(evilguard @  22.3.2008,  12:49 Найти цитируемый пост)
Для реализации того поведения которое я хочу мне нужно было выделить отдельный подкласс этого класса, чтобы он вел себя как папка(директория)

А стандратные QDir и QDirModel не подходят?

Цитата(evilguard @  22.3.2008,  13:48 Найти цитируемый пост)
он выкидывает меня на файл qlist.h:

Это уже скорее всего следствие предыдущих ошибок, надо смотреть что происходило раньше.


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
SABROG
Дата 23.3.2008, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Для теста можно убрать из класса все лишнее и оставить только пустой конструктор и деструктор и попытаться добавить указатель на такой класс в QList.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0476 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.