crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Помогите убрать костыли )
alien
  опции профиля:
сообщение 10.7.2010, 21:59
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 2
Регистрация: 10.7.2010
Пользователь №: 1876

Спасибо сказали: 0 раз(а)




Репутация:   0  


Вообщем нужно отбразить таблицу из Lua в QTreeView
Пример таблици
testtableret={
        {["name"]="giud",value=10282},
        {["name"]="count",value=5},
        {["name"]="Item 50365",["value"]=
            {
                
                {["name"]="Slot",["value"]=1},
                {["name"]="Entry",["value"]=50365},
                {["name"]="DisplayId",["value"]=0},
                {["name"]="ItemsCount",["value"]=0},
                {["name"]="Price",["value"]=0},
                {["name"]="MaxDurability",["value"]=0},
                {["name"]="BuyCount",["value"]=0},
                {["name"]="ExtendedCostId",["value"]=0},
            }
        },
        {["name"]="Item 50367",["value"]=
            {
                
                {["name"]="Slot",["value"]=2},
                {["name"]="Entry",["value"]=50367},
                {["name"]="DisplayId",["value"]=0},
                {["name"]="ItemsCount",["value"]=0},
                {["name"]="Price",["value"]=0},
                {["name"]="MaxDurability",["value"]=0},
                {["name"]="BuyCount",["value"]=0},
                {["name"]="ExtendedCostId",["value"]={{["name"]="Test",["value"]=5},{["name"]="Tes1",["value"]=            {
                
                {["name"]="Slot",["value"]=1},
                {["name"]="Entry",["value"]=50365},
                {["name"]="DisplayId",["value"]=0},
                {["name"]="ItemsCount",["value"]=0},
                {["name"]="Price",["value"]=0},
                {["name"]="MaxDurability",["value"]=0},
                {["name"]="BuyCount",["value"]=0},
                {["name"]="ExtendedCostId",["value"]=0},
            }}}},
            }
        },
}

Делаю на основе http://doc.trolltech.com/4.5/itemviews-simpletreemodel.html
http://doc.trolltech.com/4.5/itemviews-sim...eeitem-cpp.html Без изменений.
Функция получает список Имя,Obj
void MainWindow::ToObjList(QList<PacketParser::objects>* objlist,luabind::object obj)
{

    for(luabind::iterator iter(obj), end; iter != end; ++iter) {

          if(luabind::type(*iter)==LUA_TTABLE)
              {
               PacketParser::objects* tmp=new PacketParser::objects();
                  for(luabind::iterator it(*iter), end; it != end; ++it) {

                  if(luabind::type(*it)==LUA_TSTRING)
                    tmp->name=new QString(luabind::object_cast<const char *>(*it));
                  else
                    tmp->value=*it;


                 }
                  objlist->append(*tmp);
              }
    }
}

Передаем список в модель
QList<PacketParser::objects> objlist;
     ToObjList(&objlist,PP.GetTable());

     model=new TreeModel(&objlist);
    ui->treeView->setModel(model);

И собственно говоря основной код
void TreeModel::setupModelDataRec(luabind::object obj,QList<TreeItem*> &parent,bool fromTbl)
{
QList<QVariant> columnData;

int hastable=1;
for(luabind::iterator iter(obj), end; iter != end; ++iter)
{
   //qDebug(tr("%1").arg(luabind::type(*iter)).toAscii());
   switch(luabind::type(*iter))
   {
    case LUA_TNIL:
        columnData<<"nil";
    break;

    case LUA_TBOOLEAN:
        if(obj) { columnData<< "true"; }
        else {  columnData<< "false"; }
    break;

    case LUA_TNUMBER:
        columnData<<luabind::object_cast<double>(*iter);
    break;

    case LUA_TSTRING:
       columnData<<luabind::object_cast<const char *>(*iter);
     break;

    case LUA_TTABLE:
    {
        hastable=0;

      if(!fromTbl) parent << parent.last()->child(parent.last()->childCount()-1);
      if(!columnData.isEmpty())
      parent.last()->appendChild(new TreeItem(columnData, parent.last()));
       if(!fromTbl)  setupModelDataRec(*iter,parent,true); else setupModelDataRec(*iter,parent,false);
      if(!fromTbl)   parent.pop_back();
    }
     break;
}

}
if(hastable) parent.last()->appendChild(new TreeItem(columnData, parent.last()));
}

void TreeModel::setupModelData(QList<PacketParser::objects>* objlist, TreeItem *parent)
{
   QList<TreeItem*> parents;
   QList<int> indentations;
   parents << parent;
   indentations << 0;
   QList<PacketParser::objects>::iterator i = objlist->begin();
   while (i !=  objlist->end()) {
   QList<QVariant> columnData;
   columnData<<*(*i).name;
  switch(luabind::type((*i).value))
  {
   case LUA_TNIL:
       columnData<<"nil";
   break;

   case LUA_TBOOLEAN:
       if((*i).value) { columnData<< "true"; }
       else {  columnData<< "false"; }
   break;

   case LUA_TNUMBER:
       columnData<<luabind::object_cast<double>((*i).value);
   break;

   case LUA_TSTRING:
      columnData<< luabind::object_cast<const char *>((*i).value);
   break;

  }

   parents.last()->appendChild(new TreeItem(columnData, parents.last()));
   if (luabind::type((*i).value)==LUA_TTABLE)
           setupModelDataRec((*i).value,parents);
   ++i;
   }
}

Больше всего костылей в setupModelDataRec
может есть кто подскажет?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 11.7.2010, 6:34
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


С рекурсией правильная задумка
Если расписать исходные данные, то они имеют вид

TABLE=
{
    {["VAR1"]="name1",value=VAL_ALONE}, // таких строк может быть сколько угодно
    {["VAR1"]="name2",value=VAL_ALONE},
    ...
    {["VAR1"]="name3",["VAR2"]=TABLE}, // таких строк может быть сколько угодно
    {["VAR1"]="name4",["VAR2"]=TABLE},
}


Тут у нас:
["VARn"] - имя параметра
VAL_ALONE - одиночное значение без кавычек
TABLE - таблица, рекурсивно определённая через себя же

а про какие костыли речь то ?

Сообщение отредактировал Алексей1153 - 11.7.2010, 9:17
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
alien
  опции профиля:
сообщение 11.7.2010, 13:51
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 2
Регистрация: 10.7.2010
Пользователь №: 1876

Спасибо сказали: 0 раз(а)




Репутация:   0  


Костыли вот они.
hastable=0;

if(!fromTbl) parent << parent.last()->child(parent.last()->childCount()-1);
if(!columnData.isEmpty())
parent.last()->appendChild(new TreeItem(columnData, parent.last()));
if(!fromTbl) setupModelDataRec(*iter,parent,true); else setupModelDataRec(*iter,parent,false);
if(!fromTbl) parent.pop_back();
Просто чтобы было возможно делать вот такое например
CODE
{["name"]="Item 50367",["value"]=
{

{["name"]="Slot",["value"]={{["name"]="Test",["value"]=5}}},

Тоесть приходится делать таблицу в таблице даже если она одна. Чтобы можно было делать вот так
CODE
{["name"]="Item 50367",["value"]=
{

{["name"]="Slot",["value"]={{["name"]="Test",["value"]=5},{["name"]="Test",["value"]=5}}},

Для этого пришлось сделать дополнительный параметр bool fromTbl
Дальше переменная hastable; тоже костыль тот еще. Тоесть если эта таблица то п выходу из рекурсии не нужно делать
if(hastable) parent.last()->appendChild(new TreeItem(columnData, parent.last()));
Как бы это получше записть
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 11.7.2010, 15:24
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


не знаю насчёт реализации в QT, но вообще подобные задачи на практике решаются в виде одной таблицы типа OBJECT, в которой у каждой записи кроме уникального идентификатора и пользовательских значений есть ещё поле PARENT, если PARENT - нулевой, то объект - внешний, конечный. а если ненулевой, то он должен указывать на идентификатор другой записи в этой же таблице и содержит свойство родительского объекта. это вид отображения деревьев в БД при этом обрабатывается всё рекурсией.
многократно реализовывали такие таблицы в реальной жизни. просто и удобно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 11.7.2010, 16:38
Сообщение #5


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


А, ну если речь про класс-дерево, то вот пример (из рабочего проекта выдрано, немного подредактировано, поэтому может с ходу не скомпилиться :) )

заголовок
Раскрывающийся текст
#pragma once
#include <map>

class CTree
{
public:
    typedef __int64 td_ID;

    enum e_id
    {
        e_root____id=0,
        e_invalid_id=-1,
    };

private:
    struct s_IDkey
    {
        td_ID m_ID;
        td_ID m_IDparent;

        s_IDkey(
            td_ID m_IDparent=e_invalid_id,
            td_ID m_ID=e_invalid_id
            )
            :m_IDparent(m_IDparent)
            ,m_ID(m_ID)
        {
        }

        bool IsValidKnot()const
        {
            if(m_ID==e_invalid_id)return false;
            if(m_ID==e_root____id)return false;
            if(m_IDparent==e_invalid_id)return false;
            return true;
        }

        bool operator<(const s_IDkey& t2)const
        {
            if(m_ID<t2.m_ID)return true;
            if(m_ID>t2.m_ID)return false;
            return m_IDparent<t2.m_IDparent;
        }

    };


public:
    struct s_knotdata
    {
        s_IDkey m_ID_ID;
        
        //здесь описываются данные для узла
        //...
        //...

        s_knotdata(s_IDkey& m_ID_ID)
            :m_ID_ID(m_ID_ID)
        {
        }

        s_knotdata(
            td_ID m_ID=e_invalid_id,
            td_ID m_IDparent=e_root____id
            )
            :m_ID_ID(m_IDparent,m_ID)
        {
        }
    };

private:
    typedef std::map<s_IDkey,s_knotdata> td_List;
    td_List m_List;

public:
    CTree();
    ~CTree();

    void ClearTree();
    bool AddKnot(const s_knotdata& KD);
};


реализация
Раскрывающийся текст
#include "CTree.h"

bool CTree::AddKnot(const s_knotdata& KD)
{
    if(!KD.m_ID_ID.IsValidKnot())return false;
    m_List[KD.m_ID_ID]=KD;
    return true;
}

void CTree::ClearTree()
{
    m_List.clear();
}

CTree::CTree()
{
}

CTree::~CTree()
{
}


пример заполнения
Раскрывающийся текст
    CTree tree;

    tree.ClearTree();
    //                                      //root
    tree.AddKnot(CTree::s_knotdata(1      ));    //|-1
    tree.AddKnot(CTree::s_knotdata(3,1    ));    //| |-3
    tree.AddKnot(CTree::s_knotdata(4,1    ));    //| |-4
    tree.AddKnot(CTree::s_knotdata(7,4    ));    //|   |-7
    tree.AddKnot(CTree::s_knotdata(8,7    ));    //|   | |-8
    tree.AddKnot(CTree::s_knotdata(9,7    ));    //|   | |-9
    tree.AddKnot(CTree::s_knotdata(2      ));    //|-2
    tree.AddKnot(CTree::s_knotdata(5,2    ));    //  |-5
    tree.AddKnot(CTree::s_knotdata(6,5    ));    //  | |-6


Сообщение отредактировал Алексей1153 - 11.7.2010, 16:38
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.4.2024, 17:18