Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: [Matrix] от Ноябрь 09, 2011, 22:54



Название: QTreeWidget resizeColumnToContents
Отправлено: [Matrix] от Ноябрь 09, 2011, 22:54
resizeColumnToContents работает только для topLevelItem's для дочерних не ресайзится колонка, как можно это исправить? qt 4.7.4 mingw windows


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 10, 2011, 00:05
Видимо в момент вызова у тебя дочерние свернуты и не учитываются.
Возможно тебя устроит treeWidget->header()->setResizeMode( QHeaderView::ResizeToContents );
Это автоматически подгоняет размер секций. Но это значительно замедляет быстродействие списка.
Если элементов не много, то не страшно.


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: grin от Ноябрь 10, 2011, 02:04
вот тут люди жалуются, что не отображаемые колонки не ресайзятся: http://www.qtcentre.org/threads/2519-treeWidgets-resizeColumnToContents-not-working-properly

treeWidget->header()->setResizeMode( QHeaderView::ResizeToContents );

из личного опыта работы с QTreeView + QAbstractItemModel - если ты добавил в модель (читай в виджет) колонку после того, как вызывал QHeaderView::serReisizeMode(QHeaderView::ResizeToContents) - то для добавленной колонки размер будет равен treeWidget->header()->defaultSectionSize(). это неверно - смотри вторую страницу

Отсюда совет - использовать QHeaderView::serReisizeMode(QHeaderView::ResizeToContents), каждый раз, после того, как ты изменил количество колонок.



Название: Re: QTreeWidget resizeColumnToContents
Отправлено: [Matrix] от Ноябрь 10, 2011, 10:14
да в том-то и дело, что когда дочерние были видны, я делал resizeToContents, но требования к отображению я уже реализовал


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 10, 2011, 10:38
Отсюда совет - использовать QHeaderView::serReisizeMode(QHeaderView::ResizeToContents), каждый раз, после того, как ты изменил количество колонок.

Это автоматически подгоняет размер секций. Но это значительно замедляет быстродействие списка.

grin, наталкивает на какие-нибудь мысли?


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: grin от Ноябрь 10, 2011, 21:03
ну я полагаю

if(treeWidget->isVisible());
    treeWidget->setUpdatesEnabled(false);
treeWidget->header()->serResizeMode(QHeaderView::ResizeToContents);
if(treeWidget->isVisible());
    treeWidget->setUpdatesEnabled(true);

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


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 10, 2011, 23:29
ну я полагаю

if(treeWidget->isVisible());
    treeWidget->setUpdatesEnabled(false);
treeWidget->header()->serResizeMode(QHeaderView::ResizeToContent);
if(treeWidget->isVisible());
    treeWidget->setUpdatesEnabled(true);
Это не спасет. Думаю, подобный код почти ничего не даст.
Проблема не в том, что перерисовывается постоянно, а в том, что пересчитывается по любому изменению данных.
Изменяешь один, а проверить надо все, чтобы найти самый широкий.

Читай ассистент снова и снова на темы setResizeMode (http://doc.qt.nokia.com/stable/qheaderview.html#setResizeMode-2) и ResizeMode (http://doc.qt.nokia.com/stable/qheaderview.html#ResizeMode-enum) до тех пор, пока не настанет просветление.


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: grin от Ноябрь 11, 2011, 01:04
блин, я ж прям засомневался и набросал тестик (проект приаттачил в зипе) - на убунте qt 4.8.0 - так вот - всё работает - через QHeaderView::setResizeMode(). даже для невидимых колонок дочерних айтемов, даже если содержимое этих колонок стало (runtime) больше того, по которому была выставленна ширина колонока до внесения изменений. даже если элементы (и/или) их колонки не были видны до вызова setResizeMode().

а вот resizeColumnToContents() в данном случае безбожно глючит.

касательно производительности - есть сигнатура вызова QHeaderView::setResizeMode() - где первым параметром указывается идентификатор колонки, к которой надо применить (переприменить) режим - и вызывать надо только после ДОБАВЛЕНИЯ колонки - (что право довольно редко в ходе выполнения программы) - сама по себе проверка ширины пусть даже 1000-чи элементов (не такая уж трудоёмкая задача), перерисовка этих элементов отнимает в разы больше времени.

Но это всё лирика =) как показал тот же тест, для QTreeWidget resizeMode достаточно выставить один раз, т.к. у него модель внутренняя не меняется, так что даже выставив затем можно безбоязненно добавлять колонки - их ширина будет соответствовать заданному режиму.


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 01:18
Я не понимаю, чего ты тут не догоняешь?  ???
Прочитай ответ #4 тридцать один раз. После него обсуждать уже нечего.

setResizeMode(ResizeToContents)
перевод для танкистов: установить режим изменения размера в соответствии с содержимым.
для ваще танкистов: повторный вызов этой функции не требуется, в дальнейшем размеры обновляются автоматически.
для слесарей: коробка автомат.

resizeColumnToContents
перевод для танкистов: изменить размер в соответствии с содежимым.
для ваще танкистов: если нужно чтобы размер подтянулся под измененившееся содержимое, вызови эту функцию еще раз. и делай так каждый раз.
для слесарей: коробка механическая.

Первый вариант учитывает все элементы списка.
Второй вариант учитывает, то ли только видимые на момент вызова функции, то ли только элементы первого уровня (topLevelItems), уже не припомню.

Ну как отпустило?


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 01:20
видимо надо ждать еще одного проекта.  ;D


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 01:24
даже 1000-чи элементов (не такая уж трудоёмкая задача), перерисовка этих элементов отнимает в разы больше времени.

А если у тебя 10000 элементов в списке?
Что быстрее, отрисовать 40 видимых в данный момент на экране или посчитать длину в каждой колонке у 10000 элементов?



Название: Re: QTreeWidget resizeColumnToContents
Отправлено: grin от Ноябрь 11, 2011, 02:00
andrew.k =) забавный ты

В ответ #2 я ошибся - для QTreeWidget не надо перезадавать resizeMode после каждого изменения количества колонок (но для связки QTreeView + QAbstractItemModel - это действительно надо).

resizeColumnToContents() содержит баг в том плане, что в документации не говорится о том, что функция при ресайзе учитывает только видымые поля. Исходя из этого правильным решением (имхо) является задание resizeMode в том месте, где создаётся таблица (например в конструкторе).

З.Ы. отредактировал сообщение - удалил бессмысленный троллинг


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 02:23
не говори глупости, просто я так и не понял, что ты хотел объяснить или доказать, когда ответ и так уже был на поверхности?
И вдобавок, пишешь сам не понимаешь чего.


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 02:27
Для QTreeView это так же не надо как и для QTreeWidget, потому что второй это и есть первый.
Ты так и непонят, чем механика от автомата отличается. Иди спать.

Бага нет. Ты просишь функцию изменить размер, согласно содержимому (подразумевается на экране).

Я просто не вижу смысла снова писать одно и то же?


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: grin от Ноябрь 11, 2011, 02:31
Для QTreeView это так же не надо как и для QTreeWidget, потому что второй это и есть первый.
А ты проверь - я недавно на это наткнулся - так что знаю о чём говорю =). И QTreeWidget и QTreeView - это не одно и тоже, несмотря на наследование =).

Бага нет. Ты просишь функцию изменить размер, согласно содержимому (подразумевается на экране).
Интересно, где подразумевается? в документации это не указано =)


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 02:48
это одно и то же. оба работают на основе модели. просто в виджет эта модель встроена. работают они одинаково.

давай проект делай, где нужно два раза resizeMode задавать, иначе что?

подразумевается с точки зрения логики и здравого смысла.


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: grin от Ноябрь 11, 2011, 03:08
здравый смысл в том, что содержимое виджета (а точнее модели) я могу менять в тот момент, когда виджет не отражается, но он должен отразить всё правильно в тот момент, когда сделается видимым - хм. для меня, как и для других текущее поведение функции resizeColumnToContents() - это баг - см. https://bugreports.qt.nokia.com/browse/QTBUG-9352


Касательно проекта с QTreeView + QAbstractItemModel - сейчас не до этого - если не забуду сделаю =)


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 13:17
в сороковых годах миллионы людей считали, что евреи это баг - и их надо исправить. И что это доказывает?

Цитата по ссылке.
Код
C++ (Qt)
"Description
The QTableView's methods resizeColumnToContents(int) and resizeColumnsToContents() [b]do not work as documented![/b]"

Цитата из ассистента.
Код
C++ (Qt)
"Resizes the given column based on the size hints of the delegate used to render each item in the column.
 
Note: [b]Only visible[/b] columns will be resized. [b]Reimplement sizeHintForColumn() to resize hidden columns as well[/b]."


По-твоему, так должен работать ресайз?


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: grin от Ноябрь 11, 2011, 15:51
Цитата из ассистента.
Код
C++ (Qt)
"Resizes the given column based on the size hints of the delegate used to render each item in the column.
 
Note: [b]Only visible[/b] columns will be resized. [b]Reimplement sizeHintForColumn() to resize hidden columns as well[/b]."

Где можно увидеть указанный выше фрагмент документации?
Вот фрагмент официальной документации без всяких отсылок к sizeHintForColumn(): http://doc.qt.nokia.com/stable/qtreeview.html#resizeColumnToContents
Цитировать
void QTreeView::resizeColumnToContents ( int column ) [slot]
Resizes the column given to the size of its contents.
See also columnWidth() and setColumnWidth().



Название: Re: QTreeWidget resizeColumnToContents
Отправлено: grin от Ноябрь 11, 2011, 15:54
ну и в догонку
https://bugreports.qt.nokia.com/browse/QTBUG-9352 - статут open, резолюшн unresolved - по крайней мере авторы sdk признают что это баг, правда с низким приоритетом.


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: grin от Ноябрь 11, 2011, 17:31
из личного опыта работы с QTreeView + QAbstractItemModel - если ты добавил в модель (читай в виджет) колонку после того, как вызывал QHeaderView::serReisizeMode(QHeaderView::ResizeToContents) - то для добавленной колонки размер будет равен treeWidget->header()->defaultSectionSize().

был неправ, нет никакой необходимости задавать режим более одного раза!

З.Ы. избавился от заблуждения - что есть хорошо =). В своё оправдание скажу, что наткнулся на подобных  эфект около недели назад - видимо он был вызван чем-то другим, т.к. чистый тест (см. аттач) показал, что достаточно задать режим 1 раз.


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 17:36
Это как бы немного больше чем наполовину очевидно из названий функций.


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 17:39
Цитата из ассистента.
Код
C++ (Qt)
"Resizes the given column based on the size hints of the delegate used to render each item in the column.
 
Note: [b]Only visible[/b] columns will be resized. [b]Reimplement sizeHintForColumn() to resize hidden columns as well[/b]."

Где можно увидеть указанный выше фрагмент документации?
Вот фрагмент официальной документации без всяких отсылок к sizeHintForColumn(): http://doc.qt.nokia.com/stable/qtreeview.html#resizeColumnToContents
Цитировать
void QTreeView::resizeColumnToContents ( int column ) [slot]
Resizes the column given to the size of its contents.
See also columnWidth() and setColumnWidth().



Можно увидеть парой-тройкой сообщений выше. Поверь я его не придумал.
Не углядел. Это из QTableView::resizeColumnToContents.
Значит весь баг в том, что забыли скопировать описание.
Только очень прошу не начинай про то, что это разные контроллы, не смотря на...


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 17:42
По-твоему, так должен работать ресайз?
Ты не ответил на этот вопрос. Картинка в аттаче.


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 17:44
а вот почему этот "баг" никогда не будет исправлен.

This issue has already been reported in 2005: http://lists.trolltech.com/qt-interest/2005-09/thread01227-0.html


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: grin от Ноябрь 11, 2011, 17:51
Не углядел. Это из QTableView::resizeColumnToContents.
Значит весь баг в том, что забыли скопировать описание.
Только очень прошу не начинай про то, что это разные контроллы, не смотря на...

Да, согласен - в  QTableView::resizeColumnToContents - не глянул. При таком note это дейстивтельно только лиш "баг документации"

Касательно картинки =) да, на мой взгляд это правильно, т.к. прыгающая ширина колонок при открытии, закрытии элемента дервера - изрядно напрягает зрение.


Название: Re: QTreeWidget resizeColumnToContents
Отправлено: andrew.k от Ноябрь 11, 2011, 18:13
А на мой нет.
Я бы подобное поведение называл бы багом и писал бы разрабам.

С прискорбием сообщаю, что тема закрыта)