Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Igors от Февраль 23, 2014, 14:44



Название: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Igors от Февраль 23, 2014, 14:44
Добрый день

Мелочевка, легко решается наследованием от QTreeWidgetItem (которое мне все равно необходимо), но все же: есть ли штатная возможность указать ноду что он может (или не может) иметь children? Потому что часто возникает ситуация когда добавляется "нод-контейнер" и "нод-лист", это по задаче известно. Если такой возможности/опции нет, то насколько стремно добавить новый флажок в flags? Вроде там "user" не обозначено...

Спасибо


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: popper от Февраль 23, 2014, 16:50
В Qt5 появился флаг Qt::ItemNeverHasChildren, но из документации не ясно, на какие ситуации он распространяется.


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Hrundel от Февраль 23, 2014, 19:24
Не понимаю, почему ищешь штатную функцию?


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Igors от Февраль 24, 2014, 10:34
Не понимаю, почему ищешь штатную функцию?
Сейчас приходится делать так
Код
C++ (Qt)
MyItem * i2 = dynamic_cast <MyItem *> (item);
if (i2 && i2->IsFolder()) {    // is a container?
...
}
Что конечно не смертельно, но лучше было бы так
Код
C++ (Qt)
if ((item->flags() & Qt::ItemNeverHasChildren) == 0) {
...
 


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Bepec от Февраль 24, 2014, 11:37
Устанавливай свой флаг в setData(Qt::UserRole...) И никакого наследования.


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Hrundel от Февраль 24, 2014, 12:13
но лучше было бы так
Код
C++ (Qt)
if ((item->flags() & Qt::ItemNeverHasChildren) == 0) {
...
 

Проще! Да и выглядит в разы понятнее.


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Igors от Февраль 24, 2014, 12:36
Устанавливай свой флаг в setData(Qt::UserRole...) И никакого наследования.
А в какой колонке? Их число запросто может меняться. Так что может не стоит столь уверенно предлагать совсем уж плохонький "костылек"?  :)


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Bepec от Февраль 24, 2014, 13:33
Почему костылёк? Нулевая колонка будет всегда у итема. Нет у него состояния, когда её нет.
К тому же костылёк это наследование. А тут использование имеющегося и предназначенного именно для пользовательской роли функционала.
PS сумеете сделать итем без нулевой колонки, я вам спасибо скажу и удивлюсь :)


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Igors от Февраль 25, 2014, 10:28
К тому же костылёк это наследование. А тут использование имеющегося и предназначенного именно для пользовательской роли функционала.
Так это ф-ционал "одного поля" (колонки), а нужен для "всей записи" (айтема). Как следствие нужно будет отследить не грохнут ли колонку "на ходу" (таких случаев мало но есть). И даже без этого использование QVariant часто оказывается худшим решением.
Код
C++ (Qt)
if (item->data(0, Qt::UserRole) == true)  // item can have children
 
Догадаться что это - мудрено. Следующая попытка использовать UserRole может ничего не знать о предыдущей, и никаких сообщений выдано не будет, все ошибки загнаны в runtime. Чем меньше QVariant - тем лучше


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: GreatSnake от Февраль 25, 2014, 11:00
Код
C++ (Qt)
if (item->data(0, Qt::UserRole) == true)  // item can have children
 
Догадаться что это - мудрено. Следующая попытка использовать UserRole может ничего не знать о предыдущей, и никаких сообщений выдано не будет, все ошибки загнаны в runtime. Чем меньше QVariant - тем лучше
Открою Вам секрет. Пользовательских ролей может быть великое множество)
Никто не мешает завести свои собственные типа
Код
C++ (Qt)
enum { IgorsRoleItemCanHaveChildren = Qt::UserRole + 1000 };


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Bepec от Февраль 25, 2014, 13:37
Прикольно смотреть как человек упорствует и не желает применять сделанную для него же функцию :D

И открою вам секрет - нельзя уничтожить первую колонку. Её можно лишь очистить, зная ваш номер UserRole и не более того. :D


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Igors от Февраль 25, 2014, 14:39
Открою Вам секрет. Пользовательских ролей может быть великое множество)
Никто не мешает завести свои собственные типа
Код
C++ (Qt)
enum { IgorsRoleItemCanHaveChildren = Qt::UserRole + 1000 };
Аккуратность никогда не помешает, но все равно я получаю "шкатулку с секретом", нет уж, спасибо, не надо. А то что их может быть "великое множество" меня никогда не радовало - значит реализация "жирная", и если айтемов много - тормоза будут.

Прикольно смотреть как человек упорствует и не желает применять сделанную для него же функцию :D
А Вам не кажется что использование QVariant для хранения битового флага уже ложится на программиста позорным пятном?  :)


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Bepec от Февраль 25, 2014, 17:04
1) вы получаете только то, что используете. Стандартный функционал QTreeWidgetItem.
И вдобавок хотите вы того или нет, QTreeWidget НЕ РАССЧИТАН на большое количество итемов. Там больше 10к уже тормоза как ни странно. Так что ваше "позорное пятно" можете ложить на Qt и всех окружающих.

2) Это не относится к теме.
А так я не считаю позорным сохранить пару байт памяти в угоду потерянным своим часам. Ибо Qt жрёть ресурсы больше, чем я съэкономлю.


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Igors от Февраль 25, 2014, 18:35
Чтобы не плодить тем, вот немного сходная задача. Сейчас я переделываю на QTreeWidget (Item) старый элемент UI (что был без Qt). С точки зрения клиента это выглядит так
Код
C++ (Qt)
class OldTree {
public:
// флаги колонок
enum {
 FLAG_COLUMN_ENABLED,
 FLAG_COLUMN_LOCKED,
 FLAG_COLUMN_NUMBER,
 FLAG_COLUMN_TEXT,
 ...
};
OldTree( int flags );   // какие колонки создавать
void addColumn( int flag );   // добавить колонку на ходу
void remColumn( int flag );   // удалить
...
};
 
class OldTreeItem {
public:
bool  IsEnabled( void ) const;  // возвращает значение в колонке  ENABLED
void  SetEnabled( bool );      // устанавливает значение в колонке  ENABLED
 
// так же для всех др колонок
};
 
Как мне сохранить интерфейс OldTreeItem (с учетом что теперь он порожден от QTreeWidgetItem)?

Спасибо


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Bepec от Февраль 25, 2014, 18:40
Как душе угодно сохраняйте. Никто ж вам не запрещает. Только удалять колонки вы не сможете, вы будете их очищать. Вот и всё.

А псевдокод адаптации я писать не буду - и ежу ясно setText() и прочая.


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Igors от Февраль 26, 2014, 11:58
А псевдокод адаптации я писать не буду - и ежу ясно setText() и прочая.
Ежу все понятно - поэтому у него вместо мозгов иголки.
Код
C++ (Qt)
item->setText(<а здесь что?>, "some text");


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Bepec от Февраль 26, 2014, 13:43
А там идёт то, что подразумевается в вашей реализации. И только вы знаете что там :) Мне вы показали только объявления, как я могу вам что-то сказать по вашей задаче? :D

Ладно, давайте как с первоклассником.

У вас будет наследник от QTreeWidget, имеющий интерфейс аналогичный со старым компонентом.

Название функций и их параметры остаются такими же для совместимости.

Содержимое функций переписывается со старого кода на новый код с использованием Qt и QTreeWidgetItem, при это сохраняя функционал старого компонента или же улучшая его.

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

Воссоздать и адаптировать старый код на новый можно только при наличии старого кода.

PS Я думаю вы достаточно разбираетесь в коде старого компонента, чтобы перенести функционал и убрать лишние детали.

PPS я даже готов вам наметать псевдокод перевода пары ваших функций при условии предоставления вами кода старых функций и алгоритма работы компонента в целом.


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Igors от Февраль 26, 2014, 14:08
PPS я даже готов вам наметать псевдокод перевода пары ваших функций при условии предоставления вами кода старых функций и алгоритма работы компонента в целом.
??? Так я уже все Вам предоставил
Код
C++ (Qt)
class OldTreeItem {
public:
bool  IsEnabled( void ) const;  { return mEnabled; } // возвращает значение в колонке  ENABLED
void  SetEnabled( bool on );    { mEnabled = on; } // устанавливает значение в колонке  ENABLED
 
// так же для всех др колонок
};
Методы сохранить, старые члены данных - на Ваше усмотрение. Пример: mEnabled


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Bepec от Февраль 26, 2014, 14:48
Код:
enum {  FLAG_COLUMN_ENABLED}

 bool  IsEnabled( void ) const;  { return data(FLAG_COLUMN_ENABLED, Qt::UserRole).toBool(); } // возвращает значение в колонке  ENABLED
 void  SetEnabled( bool on );    { setData(FLAG_COLUMN_ENABLED, Qt::UserRole, on); } // устанавливает значение в колонке  ENABLED


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Igors от Февраль 26, 2014, 16:28
Код:
enum {  FLAG_COLUMN_ENABLED}

 bool  IsEnabled( void ) const;  { return data(FLAG_COLUMN_ENABLED, Qt::UserRole).toBool(); } // возвращает значение в колонке  ENABLED
 void  SetEnabled( bool on );    { setData(FLAG_COLUMN_ENABLED, Qt::UserRole, on); } // устанавливает значение в колонке  ENABLED
Так ведь флаг FLAG_COLUMN_ENABLED совсем не соответствует индексу колонки  :)


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Bepec от Февраль 26, 2014, 17:26
Так ведь
Цитировать
PPS я даже готов вам наметать псевдокод перевода пары ваших функций при условии предоставления вами кода старых функций и алгоритма работы компонента в целом.

Вы мне дали код и никаких пояснений по алгоритму работы.
Код возвращает значение колонки enabled. Так что я сам из головы взял что колонка 0 = колонка Enabled.
Приводите весь алгоритм, тогда и будет вам код для вашего АЛГОРИТМА работы.

PS в моём случае соответствует индексу. Я его из головы взял, правда енум скопировал у вас :)


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Igors от Февраль 26, 2014, 17:41
Вы мне дали код и никаких пояснений по алгоритму работы.
Код возвращает значение колонки enabled. Так что я сам из головы взял что колонка 0 = колонка Enabled.
Приводите весь алгоритм, тогда и будет вам код для вашего АЛГОРИТМА работы.
Так я его и привел
// флаги колонок
Код
C++ (Qt)
enum {
 FLAG_COLUMN_ENABLED,
 FLAG_COLUMN_LOCKED,
 FLAG_COLUMN_NUMBER,
 FLAG_COLUMN_TEXT,
 ...
};
 
Флаг показывает имеется ли такая колонка, индексом-то он не является

PS в моём случае соответствует индексу. Я его из головы взял, правда енум скопировал у вас :)
Ах какая у Вас хорошая голова! :) А что будет если колонки ENABLED нет (флаг выкл) ?


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Bepec от Февраль 26, 2014, 18:17
Колонка будет в любом случае. Просто в каком то случае она скрыта от пользователя.

Я вам уже говорил и повторять в третий раз не буду. Колонки будут всегда. QTreeWidgetItem имеет то же число колонок что и QTreeWidget. Удалять колонки нельзя, добавлять колонки нельзя. Они существовать будут всегда. Просто в одном случае они будут скрыты, в другом показаны.

Это вам не динамически выстраиваемое дерево, это QTreeWidgetItem с его достоинствами и недостатками.

PS если и это до вас не дойдёт, я больше попыток делать не буду :)

PPS по вашему описанию я навскидку могу предложить три реализации, которые будут различаться в корне. Делать то надо так "как в старом".


Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Igors от Февраль 27, 2014, 12:45
Колонка будет в любом случае. Просто в каком то случае она скрыта от пользователя.

Я вам уже говорил и повторять в третий раз не буду. Колонки будут всегда. QTreeWidgetItem имеет то же число колонок что и QTreeWidget. Удалять колонки нельзя, добавлять колонки нельзя. Они существовать будут всегда. Просто в одном случае они будут скрыты, в другом показаны.

Это вам не динамически выстраиваемое дерево, это QTreeWidgetItem с его достоинствами и недостатками.
То есть мне лучше создать все-все возможные колонки и потом спрятать те что не нужны? Потому что удалить/добавить - никак не выйдет. Правильно?



Название: Re: QTreeWidgetItem ItemFlags::CanHaveChildren ?
Отправлено: Bepec от Февраль 27, 2014, 16:19
PPS по вашему описанию я навскидку могу предложить три реализации, которые будут различаться в корне. Делать то надо так "как в старом".
И эта входит в число трёх.