Версия для печати темы
Форум на CrossPlatform.RU _ Qt GUI _ [РЕШЕНО] Дерево и скролл
Автор: Elfinit 20.12.2009, 0:06
Доброго всем времени суток!
У меня 4 вопроса:
1. Есть QTreeWidget. У него, как я понял, по умолчанию есть скрол. Так вот он мне не нужен. Мне надо, чтобы при expand-е или collaps-е меняло размер само дерево,а вертикальный скрол вообще появляться не должен. Как сделать?
2. Никак не хочет появляться горизонтальный скрол(
3. У дерева слишком большие отступы при переходе к очередному уровню. Их можно как-то уменьшить? Желательно, чтобы картинка-branch была прямо под первой буквой родительского узла, а можно даже ещё левее.
4. Можно ли как-то сделать, чтобы вертикальный скрол появлялся не справа, а слева. Соответственно, горизонтальный - не снизу, а сверху.
Заранее спасибо))
Автор: DIMEDROLL 20.12.2009, 2:49
Цитата(Elfinit @ 19.12.2009, 23:06)
Мне надо, чтобы при expand-е или collaps-е меняло размер само дерево,а вертикальный скрол вообще появляться не должен.
это как? приведи пример, где такое уже есть?
Автор: Elfinit 20.12.2009, 11:09
Цитата(DIMEDROLL @ 20.12.2009, 2:49)
это как? приведи пример, где такое уже есть?
Если бы я знал, как - вопрос бы не возник)) Пример, где это уже есть - Лайтрум. Там на всю левую панельку - общий скрол.
Автор: Litkevich Yuriy 20.12.2009, 12:59
Цитата(Elfinit @ 20.12.2009, 14:09)
общий скрол.
что значит общий, в QTree* тоже общий
Автор: frg10 20.12.2009, 13:51
Цитата(Elfinit @ 20.12.2009, 0:06)
1. Есть QTreeWidget. У него, как я понял, по умолчанию есть скрол. Так вот он мне не нужен. Мне надо, чтобы при expand-е или collaps-е меняло размер само дерево,а вертикальный скрол вообще появляться не должен. Как сделать?
Попробуй tree->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
Цитата(Elfinit @ 20.12.2009, 0:06)
2. Никак не хочет появляться горизонтальный скрол(
Подозреваю, что аналогично: setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn) или setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded)
Автор: Elfinit 20.12.2009, 14:24
Цитата(Litkevich Yuriy @ 20.12.2009, 12:59)
в QTree* тоже общий
Привожу объясняющие скрины. Блоки "Общее", "Папки" и "Альбомы" лежат на одном ScrollArea.
Второй скрин показывает, как это сделано в LightRoom
Цитата(frg10 @ 20.12.2009, 13:51)
Попробуй tree->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
Не помогает, скрол просто не появляется, но блок не увеличивается.
Цитата(frg10 @ 20.12.2009, 13:51)
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn) или setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded)
Как я уже только не пробовал) Вообще, погуглив, понял, что это больной вопрос, когда в дереве один столбец. А у меня ещё и элементы дерева - виджеты.
Автор: Litkevich Yuriy 20.12.2009, 15:47
Elfinit, работать должно так:
когда раскрываем подветви поддерева ("folders", "catalog", будем называть поддеревья), то размер поддерева увеличивается в высоту, чтобы содержимое поддерева полностью поместилось.
правильно ли я понял?
Если так, то Qt Designer версии >=4.5, редактор свойств. Останется только своё оформление навесить и линейку прокрутки перенести в другое место.
Автор: Elfinit 20.12.2009, 23:12
Цитата(Litkevich Yuriy @ 20.12.2009, 15:47)
"folders", "catalog", будем называть поддеревья
Дело в том, что "Общее", "Папки" и "Альбомы" - это не поддеревья, это обычные фрэймы. Переделывать всю левую панельку так, чтобы в ней было одно только дерево-нереально (блок "Папки" появился гораздо позднее остальных и только для него уместна "логика" дерева, в "Альбомы" и "Общее" нет никаких ветвей). Т.о. дерево тут - ТОЛЬКО внутри блока "Папки". Если бы вся панелька была на основе одного дерева - проблемы бы не возникало вообще, скрол бы сам появлялся. А мне нужно, чтобы дерево в "Папки" увеличивалось в размере, сдвигая при необходимости ниже блок "Альбомы".
А скрол в левую часть убрать как? На основе обычной Scroll Area никак?
Автор: igor_bogomolov 21.12.2009, 9:22
Цитата(Elfinit @ 20.12.2009, 0:06)
4. Можно ли как-то сделать, чтобы вертикальный скрол появлялся не справа, а слева. Соответственно, горизонтальный - не снизу, а сверху.
Установи для QScrollArea свойство layoutDirection в Qt::RightToLeft, а для всех его детей Qt::LeftToRight и будет счастье
Цитата
3. У дерева слишком большие отступы при переходе к очередному уровню. Их можно как-то уменьшить? Желательно, чтобы картинка-branch была прямо под первой буквой родительского узла, а можно даже ещё левее.
Посмотри на свойство QTreeWidget
indentationЦитата
1. Есть QTreeWidget. У него, как я понял, по умолчанию есть скрол. Так вот он мне не нужен. Мне надо, чтобы при expand-е или collaps-е меняло размер само дерево,а вертикальный скрол вообще появляться не должен. Как сделать?
Как вариант, скрыть скроллы, ловить сигнал
QTreeView::expanded, вычислять размер и делать ресайз
Автор: Elfinit 21.12.2009, 10:09
Цитата(igor_bogomolov @ 21.12.2009, 9:22)
вычислять размер
А как подсчитать количество отображённых в данный момент "строк"?
Автор: igor_bogomolov 21.12.2009, 10:24
Есть такие методы:
bool QTreeView::isExpanded ( const QModelIndex & index ) const
QRect QTreeView::visualRect ( const QModelIndex & index ) const [virtual]
По моему, их вполне достаточно, что бы написать алгоритм подсчета количества отображаемых строк.
Автор: Elfinit 21.12.2009, 11:45
Итак, решение получилось такое:
1. Реализация экспанда/коллапса осуществляется использованием следующих методов:
/* static */
int FoldersTree::getVisibleChildsCount(QTreeWidgetItem *item)
{
// нужно вычислить, сколько всего открытых потомков у узла, до уровня листьев дерева
int childs_count = item->childCount();
int hidden_childs = childs_count;
for (int i=0;i<childs_count;i++) {
QTreeWidgetItem *ti = item->child(i);
if (ti->isExpanded()) {
hidden_childs += getVisibleChildsCount(ti);
}
}
return hidden_childs;
}
//пересчёт размера
void FoldersTree::recalculateGeometry()
{
int new_height = qMax(200, shown_rows*FolderTreeItem::folder_tree_item_height);
setMinimumHeight(new_height);
setMaximumHeight(new_height);
}
//отлов сворачивания/разворачивания узлов
void FoldersTree::treeItemExpanded(QTreeWidgetItem *item)
{
((FolderTreeItem*)item)->load();
shown_rows += getVisibleChildsCount(item);
recalculateGeometry();
}
void FoldersTree::treeItemCollapsed(QTreeWidgetItem *item)
{
shown_rows -= getVisibleChildsCount(item);
recalculateGeometry();
}
// слоты-обработчики вставки/удаления в дерево/из дерева
void FoldersTree::insertedChild(FolderTreeItem *to, FolderTreeItem *item)
{
if (to->isExpanded()) {
shown_rows += getVisibleChildsCount(item);
recalculateGeometry();
}
}
void FoldersTree::removedChild(FolderTreeItem *from, FolderTreeItem *item)
{
if (from->isExpanded()) {
shown_rows -= getVisibleChildsCount(item);
recalculateGeometry();
}
}
2-3. Благодаря setIndentation проблема решилась, и необходимость в горизонтальном скроле отпала.
4. setLayoutDirection по методу, описанному igor_bogomolov
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)