Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Zerkin от Октябрь 26, 2010, 09:56



Название: Изменение итемов виджета дерева.
Отправлено: Zerkin от Октябрь 26, 2010, 09:56
Доброго времени суток.
 Просьба сразу не закидывать камнями, ибо мало того, что с Qt знаком буквально несколько дней, так и практических навыков программирования, отличных от хеллоуворлда, увы, но мало.
 Задача у меня следующая: Организуется определенное дерево, какое - не важно, суть в том, что у каждого итема дерева должна быть иконка и чекбокс (или какая-либо возможность их выделения близкая к чекбоксу, но первое предпочтительнее).
 С иконкой всё понятно - setIcon, а вот с чекбоксом я уже долго мучаюсь. Читал что-то про флаги, пытался разобраться с ItemIsUserCheckable, но ни к чему это меня не привело (итемы становятся просто заблоченные).
 Подскажите, как можно решить эту проблему стандартными списковыми средствами, с использованием возможностей QTreeWidgetItem? Или может быть выбор такой реализации заведомо ложный? Буду очень благодарен. ;)


Название: Re: Изменение итемов виджета дерева.
Отправлено: GreatSnake от Октябрь 26, 2010, 10:00
Наверное перебил дефолтные флаги.
При заведении QTreeWidgetItem-а делай так

item->setFlags( item->flags() | Qt::ItemIsUserCheckable );
А уже после QTreeWidgetItem::setCheckState()


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Октябрь 26, 2010, 10:13
Большое спасибо, всё получилось. Жутко стыдно, что сам до конца не разобрался.
Премного вам благодарен  :)


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Октябрь 26, 2010, 10:32
Чтобы не создавать еще одну тему, добавлю вопрос здесь.
Подскажите общую идею как мне в этом же проекте реализовать такую вещь: нужно сохранять сформированную структуру дерева, чтобы при следующем запуске она у нас появлялась. Записывать в файл - это понятно, но вот пока не очень понял как саму структуру записать. Направьте правильной дорогой =)


Название: Re: Изменение итемов виджета дерева.
Отправлено: GreatSnake от Октябрь 26, 2010, 10:39
QDataStream, QVariant, QSettings


Название: Re: Изменение итемов виджета дерева.
Отправлено: BaltikS от Октябрь 26, 2010, 10:41
Лучше XML


Название: Re: Изменение итемов виджета дерева.
Отправлено: GreatSnake от Октябрь 26, 2010, 10:47
Согласен, особенно если, дерево большое.
QXmlStreamWriter/QXmlStreamReader.


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Октябрь 28, 2010, 11:26
назрел очередной вопрос.
Сейчас разбирался со слотами-сигналами и натолкнулся на следующую проблему:

написал метод по определенному добавлению чайлдов себе в дерево и связал с кнопкой на всплывающем диалоге:

в конструкторе класса
connect(dialog->okButton,SIGNAL(clicked()),this,SLOT(addItems(item)));

addItems собственно в паблик слотах. item определяется в конструкторе и не является членом моего конкретного класса-виджета. Таким образом добавляться не хочет ни при каком раскладе, но если переделать addItems без параметров (определяем item как член класса и в самом методе уже к нему обращаемся) всё работает. Не хочется превращать код в такую гадость, получается прям удаление гландов через одно место, да и универсализация вся потеряется сразу.

Наводит на мысль, что где-то не разобрался в самой системе слоты-сигналы. Что не так?


Название: Re: Изменение итемов виджета дерева.
Отправлено: GreatSnake от Октябрь 28, 2010, 11:39
Цитировать
Наводит на мысль, что где-то не разобрался в самой системе слоты-сигналы. Что не так?
Именно.
Сигнал clicked() испускает кнопка и она понятия не имеет что такое item.
Мало того такой connect() просто не отработает - если бы вы видели консоль, то наверняка увидели бы ругань.
Находите нужный вам item уже непосресдвенно в addItems() методе.


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Октябрь 28, 2010, 11:44
Находите нужный вам item уже непосресдвенно в addItems() методе.

Так, вот здесь я немного не понял. Т.е. сделать связь так, чтобы по клику обработка моим методом, которому в перпективе должен параметр передаваться, нереализуема?
Как понять, найти мой итем непосредственно в методе? Всё-таки обращаться из него к членам?


Название: Re: Изменение итемов виджета дерева.
Отправлено: GreatSnake от Октябрь 28, 2010, 12:03
Сначала внимательно почитайте это (http://doc.crossplatform.ru/qt/4.6.x/signalsandslots.html).
Ещё раз читаем внимательно:
Цитировать
Сигнал clicked() испускает кнопка и она понятия не имеет что такое item.


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Октябрь 29, 2010, 14:44
Вроде разобрался как смог.

Продолжая тему сохранения дерева:
Насчет xml, DOM или SAX? Что думаете?


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Ноябрь 12, 2010, 15:06
Всем доброго времени суток.
Появилась потребность в переделки всего под модель-представление.
Так как такая вещь явилась для меня полным откровением, то назрели первые вопросы.
От кого лучше наследоваться моей модели: QAbstractItemModel, QStandartItem модель или еще от чего?
Суть в том, что буду реализовывать индексацию в дереве по типу табличной (наводит на мысль тогда уж о QAbstractTableModel, но не уверен), но я так понял, что индексация здесь другой быть и не может. Или я ошибаюсь?  Может у кого был опыт в реализации похожих вещей, подскажите пожалуйста. И будет ли у меня возможность, переделывая в модель-представление, оставить все мои свистелки и перделки в виде иконок и чекбоксов?


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Декабрь 16, 2010, 13:31
Товарищи, а можно как-нибудь в QTreeWidget хейдер вообще убрать, ну не нужны они мне =(.


Название: Re: Изменение итемов виджета дерева.
Отправлено: BRE от Декабрь 16, 2010, 13:39
Товарищи, а можно как-нибудь в QTreeWidget хейдер вообще убрать, ну не нужны они мне =(.
void   setHeaderHidden ( bool hide )


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Декабрь 16, 2010, 13:52
О спасибо, странно, но в ассистенте в описании QTreeWidget этого нету, поэтому и обратился к вам.


update. А ну понятно, надо было искать в QTreeView =)


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Январь 11, 2011, 17:20
Созрел вопрос.
Нужно по клику на кнопку вызвать слот которому передаётся параметр. Ясно, что clicked() не передаёт никаких параметров, как следствие ничерта не работает, как такие проблемы решают люди с прямыми руками? Или мне всё-таки надо как-то заморачиваться с QSignalMapper? Убрав параметр всё прекрасно заработает, оно и ясно, но у меня задачка с рекурсией и без параметра в слоте ну никак.

p.s. Просто нужно отметить сразу все листы в дереве.


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Январь 12, 2011, 14:29
Короче говоря, так как никто не ответил, к сожалению , то сделал через слот-посредник, в котором вызываю метод обработки. Как близко это к "хорошему стилю" не знаю.


Название: Re: Изменение итемов виджета дерева.
Отправлено: twp от Январь 12, 2011, 16:13
Естественно, что параметр передавать нельзя. Не уверен подойтет ли это решение, но можно узнать кто был источником сигнала вызвав в слоте метод sender()
Это даст возможность правильно обработать нажатие кнопки при наличии нескольких источников сигнал сконекченных к одному слоту.


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Январь 17, 2011, 13:26
Подскажите, а можно без рекурсии как-то отметить листы? С итераторами не знаком, но, вроде как, это логичный путь решения проблемы, нет?


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Январь 17, 2011, 13:40
Если у кого-нибудь есть возможность, то я просил бы показать на примере использование этого итератора.
Родина вас не забудет.  ;)


Название: Re: Изменение итемов виджета дерева.
Отправлено: twp от Январь 17, 2011, 14:10
если используется QTreeWidget то это делается очень используя QTreeWidgetItem, в частности что-то типа такого:
Код:
    QTreeWidgetItem *item = treeWidget->currentItem();
    for (int i = 0; i < item->childCount(); ++i) {
        QTreeWidgetItem *child = item->child(i);
        child->setCheckState(column, Qt::Checked);
    }


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Январь 17, 2011, 14:29
Он и используется. Делал примерно так же, но напрашивалась рекурсия, так как количество чайлдов у элементов могло быть разное, и нужно было у каждого идти до конца, то есть до листа. Собственно захотелось сделать без рекурсии, а это, как я понял, через итератор можно реализовать.


Название: Re: Изменение итемов виджета дерева.
Отправлено: twp от Январь 17, 2011, 14:42
ну тогда заюзать QTreeWidgetItemIterator


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Январь 17, 2011, 14:48
Ну так я про это и говорил 3 сообщениями выше =)
Показал бы кто как им правильно воспользоваться.


Название: Re: Изменение итемов виджета дерева.
Отправлено: twp от Январь 17, 2011, 16:37
сорри, затупил. собственно вот пример из асистента:
Код:
     QTreeWidgetItemIterator it(treeWidget);
     while (*it) {
         if ((*it)->text(0) == itemText)
             (*it)->setSelected(true);
         ++it;
     }
по ходу нужно только поставить нужный метод и возможно с флагами поиграть. я так понимаю что не правильно обходит листья дерева?


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Январь 18, 2011, 10:29
Напрашивает "Ой", спасибо большое, смотрел в ассистенте про итератор, но совсем не заметил, что там был пример.
Итератор отличная штука, намного удобнее  рекурсии для моей задачи.

В Итоге получилось следующее:
Код:
    QTreeWidgetItemIterator it(signalTree);
    while (*it)
    {
         if ((*it)->child(0) == 0)
          {
              (*it)->setFlags(item->flags()|Qt::ItemIsUserCheckable);
     (*it)->setCheckState(0,Qt::Checked);
 }
         ++it;
     }


Название: Re: Изменение итемов виджета дерева.
Отправлено: Zerkin от Март 22, 2011, 18:12
Никто не подскажет, как в итоге можно индексировано ползать по элементам дерева?