Название: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 24, 2009, 17:24 Есть дерево, представленное QTreeWidget. Пытаюсь сделать так, чтобы при нажатии на checkbox элемента дерева, отмечались/разотмечались соответствующие узлы дерева. Короче говоря, хотелось бы, чтобы это работало стандартно: если отмечают корень - отмечаются все узлы и листья, если отмечают узел - отмечаются все листья этого узла, если разотмечают (убирают отметку) у листа, то если это единственный лист, то снимается отметка с узла и т.д.
Код, который я написал, работает неправильно. Сможете помочь сделать верно или же подскажите, где взять готовый код? Это ведь стандартная вещь? Код
если что-то непонятно, то тут (http://www.forum.crossplatform.ru/index.php?showtopic=2261&pid=15228&st=0&#entry15228) можно посмотреть! Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: spirit от Февраль 24, 2009, 17:37 нет, это не стандартное поведение. нужно реализовывать самому.
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 24, 2009, 17:42 Почему не стандартное? В чем нестандартность заключается? Если все-же нестандартное, то поможете реализовать корректно?
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: spirit от Февраль 24, 2009, 17:44 ну в Qt такое поведение не предусмотрено.
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 24, 2009, 17:47 За время существования данного элемента в Qt, разве подобная задача не решалась совсем ни разу? Я думаю, решали. Искал гуглом, но не нашел. Может у кого-то уже есть подобное, может поделитесь?
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: pastor от Февраль 24, 2009, 17:50 Первое что кинулось в глаза - это рекурсия. Откройте для себя QTreeWidgetItemIterator
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 24, 2009, 17:52 Я клоню к тому, что, наверняка, кто-нибудь уже решал эту задачку. Поделитесь, пожалуйста, кодом. А называю способ стандартным, ну потому что он естественен по идее!!!
Заранее спасибо. Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 24, 2009, 18:12 Первое что кинулось в глаза - это рекурсия. Откройте для себя QTreeWidgetItemIterator А как правильно написать приведенной мною кусок кода? Каким способом этот итератор может помочь? Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: spirit от Февраль 24, 2009, 18:21 по идее так должно работать, не проверял правда :)
Код
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: pastor от Февраль 24, 2009, 18:32 Инеторатор упростит вот этот код:
Код
и будет выглядеть примерно так: Код
Но даже в этом коде есть вопросы. Если не исполуется tristate для чек боксов (а судя по коду этот так), тогда ненужна проверка checkState(column) == 1. Более того что из скрина в первом посте видно, что свой-во сheckable используется для первого столбца. Имхо тогда нужно так: Код
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 24, 2009, 18:53 pastor, я правильно Вас понял, что итератор сам пройдется по родительской ветке? Если нет, то в нем не вижу смысла.
А на счет колонки - Вы правильно поняли, но в слоте все-равно есть этот параметр, даже учитывая, что он по-умолчанию 0, поэтому я Код ! spirit, спасибо. Мне понравилось решение с Код . Более элегантно, чем у меня. Принял к сведению. Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 24, 2009, 19:07 Вот более адекватный вариант.
Код
Но все же есть некоторые некорректности: 1) когда я нажимаю на корень, выделяются(снимаются выделения) с узлов, а на листьях - остаются. 2) когда в узле не один лист, а несколько - то при нажатии на лист - выделение затрагивает и узел. Я понимаю, что у меня эти ситуации и не учтены в коде. Но вот хотел бы учесть. Буду благодарен за помощь! Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: lit-uriy от Февраль 24, 2009, 19:18 итератор проходит по всем элементам
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 24, 2009, 19:28 Цитата: lit-uriy итератор проходит по всем элементам Код: /// Нажатие на элемент дерева Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 24, 2009, 19:35 Итератор, который проходит все элементы, начиная с item! Почему он не считает элемент item базовым, т.е. максимальная проходимость - это родитель элемента item? Как обрезать его дальнейший проход?
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 24, 2009, 21:24 Кто-нибудь, помогите, пожалуйста!
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: pastor от Февраль 24, 2009, 22:56 Итератор, который проходит все элементы, начиная с item! Почему он не считает элемент item базовым, т.е. максимальная проходимость - это родитель элемента item? Как обрезать его дальнейший проход? Что-то неопнятны вопросы... QTreeWidgetItemIterator пройдет по всем подчиненным айтемам и подчиненным айтемам подчиненных айтемов и т.д. :) Уточни свои вопросы. ЗЫ: Приаттач свой компилябельный код, чтобы самому не писать экзампл. Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: Sergeich от Февраль 24, 2009, 23:32 При нажатии на чекбокс выделяюся все потомки, при снятии галочки все дочерние соответсвенно помечаются ненажатыми, плюс прмежуточное состояние, когда отмечено не все:
objecttreemodel.h Код: #ifndef OBJECT_TREE_MODEL_H objecttreemodel.cpp Код: #include "objecttreemodel.h" Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 25, 2009, 10:29 Цитата: Sergeich При нажатии на чекбокс выделяюся все потомки, при снятии галочки все дочерние соответсвенно помечаются ненажатыми, плюс прмежуточное состояние, когда отмечено не все: Sergeich, cпасибо. ПопробуюЦитировать Уточни свои вопросы. Так spirit накатал компилябельный код. Осталось main добавить и усе!ЗЫ: Приаттач свой компилябельный код, чтобы самому не писать экзампл. pastor, что именно уточнять и не знаю. Все вроде бы сказал. Мне неясно, почему итератор идет по всем оставшимся после item узлам. Мне казалось, в нем должен быть немного другой принцип работы.... Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 25, 2009, 10:41 Sergeich, я правильно понял, что мне следует сделать представление вместо виджета, т.е. QTreeView вместо QTreeWidget. А в качестве модели задать созданную Вами на основе QStandardItemModel?
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: spirit от Февраль 25, 2009, 10:43 имхо, алгоритм Сергеича можно адаптировать к вашей задачи не используя модели.
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 25, 2009, 11:10 Цитата: spirit имхо, алгоритм Сергеича можно адаптировать к вашей задачи не используя модели. Это и пытался сделать, но нет у QTreeWidgetItem функции rowCount(), а без нее самому считать? Или как?Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: spirit от Февраль 25, 2009, 11:12 childCount == rowCount
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 25, 2009, 12:42 Sergeich, спасибо большое за идею. Чтобы не использовать модель, по совету spiritа постарался подкорректировать алгоритм под свой QTreeWidgetItem. Единственное, что мне в том алгоритме не нужно было - это третье состояние. Пользователей оно введет в транс, им оно не нужно. Поэтому его нафиг убрал. После обработки напильником, рубанком и наждачной бумагой вышло такое: :)
Код
Понимаю, алгоритм получился не самым удачным. Была бы вложенность листьев равна 5-6 или более, то такая штука не прокатила бы, но через рекурсию как было показано в ранних постах, не прокатывает. Если это делать через модель, то думаю, алгоритм Sergeicha подошел бы идеально. Осталось чуть скорректировать работу отметки предка и все нормуль будет! :) Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: pastor от Февраль 25, 2009, 12:48 Мне неясно, почему итератор идет по всем оставшимся после item узлам. "после" имеется в виду по тем, которые с ним на одном уровне вложенности? Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 25, 2009, 12:58 Цитировать "после" имеется в виду по тем, которые с ним на одном уровне вложенности? Ну не совсем. Проверка всех элементов того же уровня вложенности и его родителя. Не более. Никаких соседей учитывать не надо, а итератор учитывает...Сделал окончательный вариант. Получилось такое чудо: Код
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: pastor от Февраль 25, 2009, 13:57 Да, с итератором там все понятно.. )))
Немного передалал твой код, вернее только его первую часть. Теперь она способна "выдержать" любой уровень вложенности и без рекурсии. Я законектил этот слот на itemClicked вместо itemPressed (т.к. наблюдались глюки при быстром кликанье на узле) Код
Вторую часть кода я не трогал, так как несовсем понял что нужно получить в итоге. Если установлено состояние для айтема как checked то и для родителя устанавливается точно такое-же состояние. А вот для прародтеля нет. И это несовсем понятно (логично). Я бы восользовался 3 состояниями: checked - выделены все айтемы unchecked - не выделен ниодин partially checked - выделены не все айтемы Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: spirit от Февраль 25, 2009, 14:01 Цитировать Я бы восользовался 3 состояниями: +1checked - выделены все айтемы unchecked - не выделен ниодин partially checked - выделены не все айтемы Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 25, 2009, 14:16 Да, с итератором там все понятно.. ))) ООО, вот тоже такие глюки наблюдаю. Спасибо, попробую! :)Немного передалал твой код, вернее только его первую часть. Теперь она способна "выдержать" любой уровень вложенности и без рекурсии. Я законектил этот слот на itemClicked вместо itemPressed (т.к. наблюдались глюки при быстром кликанье на узле) Вторую часть кода я не трогал, так как несовсем понял что нужно получить в итоге. Если установлено состояние для айтема как checked то и для родителя устанавливается точно такое-же состояние. А вот для прародтеля нет. И это несовсем понятно (логично). Я бы восользовался 3 состояниями: checked - выделены все айтемы unchecked - не выделен ниодин partially checked - выделены не все айтемы Спасибо, попробую этот код. Нет, 3 состояния - перебор. У летчиков мозги съедут. Если хотя-бы один элемент (лист) (т.е. название файла) присутствует в этапе полета (узел), тогда этот элемент выделен. Да и потом на таком принципе удобнее дальнейшую обработку вести (в смысле когда 2 состояния)! Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: spirit от Февраль 25, 2009, 14:18 ну тебе виднее, но логичнее всего и правилнее -- это как сказл pastor иметь три состояния. ;)
Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: BRE от Февраль 25, 2009, 14:27 Нет, 3 состояния - перебор. У летчиков мозги съедут. Это надуманная причина (нельзя недооценивать наших летчиков). ;DДа и потом на таком принципе удобнее дальнейшую обработку вести (в смысле когда 2 состояния)! А вот это явная причина... (удобней тебе). ;)Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 25, 2009, 14:35 Это надуманная причина (нельзя недооценивать наших летчиков). ;D Да не недооцениваю я летчиков. Сам к ним в некотором роде отношусь! :) Летчики - консерваторы. На старой программе было два состояния. Увидят три состояния испугаются. Не будут понимать, что за 3 состояние, откуда взялось! Чем проще работать с программой, тем большее количество людей ей пользуются....А вот это явная причина... (удобней тебе). ;) Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: Sergeich от Февраль 25, 2009, 23:50 Насчет кода: код из работающего проекта, писался и отлаживался в течении получаса, причем по моей ленности была использована QStandardItemModel вместо QAbstractItemModel. Вроде работает.
По поводу трех состояний: без третьего никак нельзя. Поясняю: если (не)отмечаются все потомки у родителя ставится (снимается) галочка. Что делать если потомки выбраны через одного? Именно для этого и был придуман т.н. tristate. Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 26, 2009, 12:20 Цитата: Sergeich Насчет кода: код из работающего проекта, писался и отлаживался в течении получаса, причем по моей ленности была использована QStandardItemModel вместо QAbstractItemModel. Вроде работает. Есть несколько вопросов. В связи с некоторыми деталями при работе с деревом этапов, увиденными сегодня, возникло желание перейти от QTreeWidget к QTreeView. Соответственно, хочется сделать так, как в указанном Вами коде. При этом сделать более корректно, т.е. используя QAbstractItemModel. Но проблема в том, что у этого класса нет сигнала itemChanged и им подобных. Как поступить в этом случае?По поводу трех состояний: без третьего никак нельзя. Поясняю: если (не)отмечаются все потомки у родителя ставится (снимается) галочка. Что делать если потомки выбраны через одного? Именно для этого и был придуман т.н. tristate. Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: spirit от Февраль 26, 2009, 12:23 как это нету? все есть :)
Цитировать void QAbstractItemModel::dataChanged ( const QModelIndex & topLeft, const QModelIndex & bottomRight ) This signal is emitted whenever the data in an existing item changes. The affected items are those between topLeft and bottomRight inclusive (of the same parent). Note that this signal must be emitted explicitly when reimplementing the setData() function. See also headerDataChanged(), setData(), and layoutChanged(). Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: pastor от Февраль 26, 2009, 12:32 Есть несколько вопросов. В связи с некоторыми деталями при работе с деревом этапов, увиденными сегодня, возникло желание перейти от QTreeWidget к QTreeView. Соответственно, хочется сделать так, как в указанном Вами коде. При этом сделать более корректно, т.е. используя QAbstractItemModel. А зачем переходить на QTreeView? Помоему QTreeWidget справляется с задачей неплохо, или ваша задача подразумевает оч большой объем данных? Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 26, 2009, 14:14 Посмотрел я на QAbstractItemModel и решил, что запутаюсь - решил, остаться на QStandardItemModel! :)
А зачем переходить на QTreeView? Помоему QTreeWidget справляется с задачей неплохо, или ваша задача подразумевает оч большой объем данных? Дело в том, что при переходе на модель-представление, очень большой кусок кода вынесется из класса TLV, который и так чересчур большой. Да и обработка отдельно взятого элемента, а не списка мне будет удобнее. Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: AD от Февраль 26, 2009, 16:06 Насчет кода: код из работающего проекта, писался и отлаживался в течении получаса, причем по моей ленности была использована QStandardItemModel вместо QAbstractItemModel. Вроде работает. Еще раз спасибо. Сделал через модель - представление. Подставил Ваш класс. Все работает на ура! :))))По поводу трех состояний: без третьего никак нельзя. Поясняю: если (не)отмечаются все потомки у родителя ставится (снимается) галочка. Что делать если потомки выбраны через одного? Именно для этого и был придуман т.н. tristate. Название: Re: QTreeWidget - нажатие на узел дерева Отправлено: Makss от Июль 30, 2010, 21:21 тоже понадобилось такая весч, реализовывал сам, потом тему эту увидил, вот выкладываю, мож кому понадобится:
Код: if(item->checkState(0) == Qt::Checked) { Функции selectItem и unselectItem ставят и убирают соответственно, галочки у дочерних элементов,думаю ни кому не составит труда их написать, поэтому их не выкладываю Код вполне рабочий, по крайней мере ситуаций отличных от правильной работы я не встречал |