161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
1

QModelIndex распознается через раз

11.02.2015, 17:24. Показов 1199. Ответов 9
Метки нет (Все метки)

Дамы и господа, кто знает, подскажите пожалуйста в чем проблема.
Что хочу - запихнуть данные индекса в переменную(объявленную глобально) и использовать ее в разных функциях.
Что не получается - данные остаются пустыми.

Если делаю:
C++ (Qt)
1
2
3
4
5
6
7
QModelIndex dx[6]; 
dx[0] = model.index(0,0); //родитель
dx[1] = model.index(0,0,dx[0]); //ребенок
model.setData(dx[0],"родитель");
model.insertRows(0,1,dx[0]);
model.insertColumns(0,1,dx[0]);
model.setData(dx[1], "ребенок");
На выходе имею
родитель
|_ (пусто!!!!!)

Если сделать так:
C++ (Qt)
1
2
3
4
5
6
7
QModelIndex dx[6]; 
dx[0] = model.index(0,0); //родитель
 
model.setData(dx[0],"родитель");
model.insertRows(0,1,dx[0]);
model.insertColumns(0,1,dx[0]);
model.setData(model.index(0,0,dx[0]), "ребенок");
На выходе имею
родитель
|_ребенок

При этом:
C++ (Qt)
1
2
3
4
5
QModelIndex dx[6]; 
dx[0] = model.index(0,0); //родитель
dx[1] = model.index(0,0,dx[0]); //ребенок
model.setData(dx[0],QIcon("parent.png"));
model.setData(dx[1],QIcon("children.png"));
На выходе имею:
(картинка)тут_какой-то_родитель
|_(картинка)тут_какой-то_ребенок

Получается, что данные об индексе ребенка заносятся корректно в dx[1], но при добавлении данных происходит какая-то лабуда и данные не отображает, как будто не понимает куда их поместить.
Помогите пожалуйста разобраться в чем дело.

Добавлено через 10 минут
Работает конструкция вида

C++ (Qt)
1
2
3
4
5
6
7
QModelIndex dx[6]; 
dx[0] = model.index(0,0); //родитель
model.setData(dx[0],"родитель");
model.insertRows(0,1,dx[0]);
model.insertColumns(0,1,dx[0]);
dx[1] = model.index(0,0,dx[0]); //ребенок
model.setData(dx[1], "ребенок");
т.е. пока мы не укажем сколько у нас добавляется подстрок и под столбцов он как будто не понимает значения индекса.
Почему происходит именно так?

Добавлено через 4 минуты
Т.е. наверное вопрос будет даже такой.
Я знаю индекс ребенка. И я могу его присвоить сразу, куда то передать, или поместить по этому адресу картинку. Но если он был объявлен перед тем как я задаю insertRows\insertColumns это не имеет смысла, тк при отрисовке будет пустота(за исключением добавления картинок). Это как-то можно обойти?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.02.2015, 17:24
Ответы с готовыми решениями:

QModelIndex::data() крашится
ApplicantTableModel унаследованный от QSqlTableModel. Хочу переопределить метод data этого класса....

QTableView, doubleClicked и QModelIndex
Всем доброго времени суток! В программировании в Qt новичок и столкнулся с такой проблемой: Суть...

Получить QModelIndex из QTreeWidget или QTreeWidgetItem
Здравствуйте! У меня есть QTreeWidget и, естественно, итемы в нём. Как мне получить QModelIndex...

Canon Pixma ip3500 - не распознаётся через USB
Прикупил б/у принтер Canon Pixma ip3500. Головку надо восстанавливать, но пока суть не в этом. При...

9
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,020
14.02.2015, 10:26 2
model.insertRows(0,1,dx[0]); Сдвигает вниз строки и dx[1] равен уже не model.index(0,0,dx[0]); а model.index(1,0,dx[0]);
1
161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
15.02.2015, 14:17  [ТС] 3
Цитата Сообщение от solar_wind Посмотреть сообщение
model.insertRows(0,1,dx[0]); Сдвигает вниз строки и dx[1] равен уже не model.index(0,0,dx[0]); а model.index(1,0,dx[0]);
Простите немного не понял, в каком это примере зи приведенных выше, просто если добавлять индекс после объявления model.insertRows(0,1,dx[0]); то добавляется корректно

Добавлено через 25 минут
Просто из-за непонятнок с индексами у меня тупик. Если кто знает, подскажите пожалуйста.
У меня есть кусочек данных, которые надо распарсить и вывести в виде дерева.
родитель
->ребенок
- ->ребенок ребенка
Это все происходит в 2-3х функциях.
Вот кусок кода(пример) которые демонстрирует что мой алгоритм долженаботать!и тут он работает

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
typedef struct
{
    QString name; //сюда пихаю название
    QModelIndex modelidx; //это переменная отвечает за индекс в дереве
} SsArray;
extern SsArray array [10];
 
void func_1()
{
array[0]. modelidx = model.index(0,0); // это родитель, с индексом 0.0
model.insertRows(0,2, array[0]. modelidx);//тут я разрешаю добавить к родителю 2х детей(прорисовка по вертикали), и указываю что его родитель будет [0] элемент,т.е. 2 строки
model.insertColumns(0,1, array[0]. modelidx); );//тут я разрешаю добавить к родителю 2х детей(прорисовка по горизонтали), и указываю что его родитель будет [0] элемент, 1 столбец
 
array[1]. modelidx = model.index(0,0, array[0]. modelidx); //теперь я указываю, что у меня есть ребенок, [1] элемент, и у него координаты 0,0 т.е. он первый в списке детей и его родитель [0]элемнет
array[2]. modelidx = model.index(1,0, array[0]. modelidx); //теперь я указываю, что у меня есть еще ребенок, [2] элемент, и у него координаты 1,0 т.е. он второй в списке детей и его родитель [0]элемнет
 
model.insertRows(0,1, array[2]. modelidx); //так же как и к родителю выше я разрешаю добавить 1 элемент(прорисовка по вертикали) и его родителем будет [2] элемнет, т.е. ребенок
model.insertColumns(0,1, array[2]. modelidx);//тоже самое но по горизонтали
 
array[3]. modelidx = model.index(0,0 array[2]. modelidx);//ну и добавляю второго ребенка, родителем которого будет второй ребенок
 
//теперь задаю заранее названия
array[0].name = "А родитель(основной)";
array[1].name = "Б ребенок 1";
array[2].name = "В ребенок 2(доп родитель)";
array[3].name = "Г ребенок 3";
 
}
 
//теперь по нажатию кнопки например идет отрисовка и запуск второй функции
 
void func_2()
{
for(int i = 0; i < 4; i++){
model.setData(array[i]. modelidx, array[i].name) //добавляю на отрисовку данные с массива структур. 
}
}


На выходе я получаю
А родитель(основной)
>>>_Б ребенок 1
>>>_В ребенок 2(доп родитель)
>>>>>>>_Г ребенок 3


Все хорошо все работает.
Теперь помещаю этот алгоритм в парс.

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
QFile xmlDoc("test.xml"); //обращаюсь к документу
QXmlStreamReader reader_doc(&xmlDoc); 
 
void Parse()
{
  xmlDoc.open(QIODevice::ReadOnly); 
  while(!reader_doc.atEnd()) //пока не конец документа
   {
     reader_doc.readNext(); //читаем теги
     if(reader_doc.isStartElement())//если нашли стартовый(открывающий тег) смотрим что нашли
      {
       ....
         if(reader_doc.name() == "children")//если нашли открывающий тег children запускаем func 1
          {
            func1();
          }
      }
     if(reader_doc.isEndElement() && reader_doc.name() == "endDevice")//сразу указываем, что если мы нашли   //закрывающий тег с названием endDevice мы заканчиваем весь парс
        {
            break;
         }
}
 
void func1()
{
    while (!reader_doc.atEnd())//пока не конец документа продолждаем парсить
    {
     reader_doc.readNext();
//если находим стартовый элемент с названием device запускаем func2
     if(reader_doc.isStartElement() && reader_doc.name() == "device")
        {
            func2();
        }
//если находим конечный элемент с названием endDevice значит мы дошли до конца и запускаем отрисовку
        if(reader_doc.isEndElement() && reader_doc.name() == "endDevice")
        {
            drawTree();
            break;
        }
    }
}
 
void func2()
{
    while(!reader_doc.atEnd())//опять читаем пока не конец файла
    {
    reader_doc.readNext();
    if(reader_doc.isStartElement())//если встречается стартовый(открытый)тег смотрим
    {
        if(reader_doc.name() == "ID")//если названия тега id
           {
            zzz = reader_doc.readElementText();//zzz это перемення типа строки, она объявлена глобально. тут я читаю содержимое между тегами и помещаю в переменную. после махинаций с фор иф я получаю некую переменную которая в заранее объвявленном масиве равна этим данным. ну типа если zzz = A то j = 1, если =Б то j=2 и тд
не суть, запускаю свич кейс для махинаций с данными
           switch(j)
             {
               case 0: //если 0 или 1
               case1:
                     reader_doc.readNextStartElement(); // выхожу из этого ифа и читаю следующий стартовый тег в моем случсае это тег name
                     break;
               case 2: // это родитель! сначала мы попадем сюда, потом в case 0 потом case 3, поотм 4-5
//и вот начинаем пихать данные
                     array[0]. modelidx = model.index(0,0); //вот он родитель с индексом 0,0. сам себе хозяин
                     array[0].name = "А родитель(основной)";
//данные заполнили, по брейку выходим, залетаем сначала и попадаем в кейс 0-1.
                     break;
               case 3:
//после имени попадаю сюда, где добавляю второго ребенка
                     model.insertRows(0,2, array[0]. modelidx);
                     model.insertColumns(0,1, array[0]. modelidx); 
                     array[2]. modelidx = model.index(1,0, array[0]. modelidx); //теперь я указываю, что у меня есть еще ребенок, [2] элемент, и у него координаты 1,0 т.е. он второй в списке детей и его родитель [0]элемнет
                     array[2].name = "В ребенок 2(доп родитель)";
                     break;
               case 4:
               case5:
//и наконец попадаю сюда где должна добавить ребенка к ребенку
                     model.insertRows(0,1, array[2]. modelidx); 
                     model.insertColumns(0,1, array[2]. modelidx);
                     array[3]. modelidx = model.index(0,0 array[2]. modelidx);//ну и добавляю третьего ребенка, родителем которого будет второй ребенок
                     array[3].name = "Г ребенок 3";
                     break;
                 }
         }
 
       if(reader_doc.name() == "Name")//нашли тег нейм заходим читаем данные втури
        {
          zzz = reader_doc.readElementText(); //перезаписываю в переменную zzz данные между тегами (открытым и закрытым) <name>" Б ребенок 1"</name> 
//помещаю данные и выхожу на новый круг чтения
          model.insertRows(0,2, array[0]. modelidx);
          model.insertColumns(0,1, array[0]. modelidx); );
//объявляю добавление детей заранее перед определением индекса ребенка иначе он не поймет что к нему что то добавили
          array[1]. modelidx = model.index(0,0, array[0]. modelidx); //объявляю индекс ребенка
          array[1].name = "Б ребенок 1"; //и добавляю название
       }
   }
 
  if(reader_doc.isEndElement() && reader_doc.name() == "device") //ну и выходом отсюда будет случить закрытьй тег девайс который мы повстречаем
    {
        break;
    }
}
}
 
void drawTree();
{
//и вот мы попадаем в отрисовку
    for(int i = 0; i < 4; i++){
    model.setData(array[i]. modelidx, array[i].name) //добавляю на отрисовку данные с массива структур.
    }
}
На выходе я получаю
А родитель(основной)
>>>_Б ребенок 1
>>>_В ребенок 2(доп родитель)
Т.е. третий ребенок не отрисовывается
Что я упускаю, укажите пожалуйста. Потому что я уже смотрю на код и не понимаю где косяк. Если через qDebug запросить занные, он покажет и правильный индекс и правильное название у любого элемента, но при отрисовке это как будто куда то теряется
0
61 / 61 / 16
Регистрация: 18.09.2014
Сообщений: 521
15.02.2015, 16:41 4
какая ОС, версия Qt и что за компилятор?
0
161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
15.02.2015, 19:37  [ТС] 5
windows 7 x64, qtcreator 5.4.0, mingw 4.8
windows 7 x32, qtcreator 5.4.2, mingw 4.8
linux(kubuntu 14.04), qtcreator 5.2.0, gcc
0
61 / 61 / 16
Регистрация: 18.09.2014
Сообщений: 521
15.02.2015, 23:42 6
под линуксом проблема не исчезает? потому как в моем проекте есть пара штук, которые под дебианом работают на ура, а в винде упираются
0
161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
16.02.2015, 08:33  [ТС] 7
*на всех системах одно и то же
Нет, дело не в системе это точно. Т.к. маленький "тестовый" пример что я выложил выше, работает, Т.е. не важно сколько детей у детей, иерархия работает и в 4-5-10 вкладок. А вот и менно при парсе начинается хрень, индекс как будто теряется, но если вывести через qDebug() данные, показывает все правильно. Но при построении дерева - нет. Пока отлаживаю по кускам, но результатов никаких.
0
61 / 61 / 16
Регистрация: 18.09.2014
Сообщений: 521
16.02.2015, 08:54 8
слуушшааай.....у тебя case1 и case5 без пробелов. они же не читаются! А в пятом case как раз ребенок 3!
0
770 / 760 / 59
Регистрация: 06.07.2009
Сообщений: 3,020
16.02.2015, 08:57 9
Sph, Я же сказал, что дело все го лишь в insertRows и insertColumns
Вы уверены, что эти функции вам нужны?

Вот ваши же два примера:
C++ (Qt)
1
2
3
4
5
6
7
8
QModelIndex dx[6]; 
dx[0] = model.index(0,0); //родитель
dx[1] = model.index(0,0,dx[0]); //ребенок
model.setData(dx[0],"родитель");
model.insertRows(0,1,dx[0]);
model.insertColumns(0,1,dx[0]);
//После этих строк dx[1] уже не равен model.index(0,0,dx[0])
model.setData(dx[1], "ребенок");
C++ (Qt)
1
2
3
4
5
6
7
8
QModelIndex dx[6]; 
dx[0] = model.index(0,0); //родитель
dx[1] = model.index(0,0,dx[0]); //ребенок
model.setData(dx[0],"родитель");
model.insertRows(0,1,dx[0]);
model.insertColumns(0,1,dx[0]);
//Здесь использован только dx[0] на положение в памяти которого, данные строки не повлияли. Поэтому все корректно отображается.
model.setData(model.index(0,0,dx[0]), "ребенок");
Чего не понятно то?
1
161 / 45 / 10
Регистрация: 25.08.2014
Сообщений: 345
16.02.2015, 14:36  [ТС] 10
Цитата Сообщение от solar_wind Посмотреть сообщение
Sph, Я же сказал, что дело все го лишь в insertRows и insertColumns
Вы уверены, что эти функции вам нужны?
Ну может они и не нужны, просто я пока не понимаю, как можно добавить данные в дерево, не добавляя nsertRows и insertColumns.

Нет, с этим понятно. Что определять индекс надо после того как пишу nsertRows и insertColumns.
Так дальше я в примере и в коде своем так и делаю.
объявляю родителя.
добавляю insertRows и insertColumns
добавляю ребенка 1 с индексом (x,y,родитель)

добавляю insertRows и insertColumns
добавляю ребенка 2 с индексом(x,y, ребенок 1)

Добавлено через 1 минуту
Цитата Сообщение от zemskyi Посмотреть сообщение
слуушшааай.....у тебя case1 и case5 без пробелов. они же не читаются! А в пятом case как раз ребенок 3!
это когда копировал пробел не добавил. А так все стоит. Дети все записываются в массив структур и по одному если их выводить показывает что оин есть, а в дереве пусто

Добавлено через 9 минут
Я сейчас делаю вот по такой модели

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void func_1()
{
array[0]. modelidx = model.index(0,0); //добавили родителя
 
model.insertRows(0,2, array[0]. modelidx); //определили сколько детишек
model.insertColumns(0,1, array[0]. modelidx); ); 
array[1]. modelidx = model.index(0,0, array[0]. modelidx); //ребенок 1
array[2]. modelidx = model.index(1,0, array[0]. modelidx); //ребенок 2
 
model.insertRows(0,1, array[2]. modelidx); //определили сколько детишек у ребенка
model.insertColumns(0,1, array[2]. modelidx); 
array[3]. modelidx = model.index(0,0 array[2]. modelidx); //добавили ребенка
 
array[0].name = "А родитель(основной)";
array[1].name = "Б ребенок 1";
array[2].name = "В ребенок 2(доп родитель)";
array[3].name = "Г ребенок 3";
 
}
 
void func_2()
{
for(int i = 0; i < 4; i++){
model.setData(array[i]. modelidx, array[i].name); //вывели все на экран
}
}
Добавлено через 4 часа 36 минут
UPD.
Спасибо всем кто уделил время моему вопросу.
Забыл поставить reader.readNext(); в некоторых местах из-за чего документ читался не так как надо и пропускал последних детей.
На маленьком документе все работает как надо, вложения детей до 4-5 уровня рисует корректно. Осталось разобрать почему большой документ рисует коряво, предполагаю где то забыл так же добавить reader_GkSaved.readNext(); или break;.

Добавлено через 45 секунд
2 solar_wind
Отдельное спасибо за информацию о сдвиге индекса, пригодится!
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.02.2015, 14:36

Геймпад от playstation2 через USB adapter, распознается но не работает
Такая проблема: на ноуте джой через переходник (китайский с aliexpress, одинарный) определяется как...

Видеокарта Nvidia 740m отключается раз через раз
здравствуйте у меня ноутбук ASUS X550LB c видеокартой nvidia 740m столкнулся с такой проблемой что...

QStyledItemDeletate::paint: узнать, раскрыт ли текущий QModelIndex в QTreeView
Доброго времени суток. Есть модель, установленная в QTreeView, есть делегат, который как надо...

Как правильно передать внутренний указатель QModelIndex в QSortFilterProxyModel?
Столкнулся со следующей проблемой. При использовании QSortFilterProxyModel модельные индексы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru