Russian Qt Forum
Ноябрь 26, 2024, 18:41 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QTableView досрочно обрезает строки многострочного текста в ячейках  (Прочитано 4373 раз)
Sasha
Гость
« : Июль 14, 2015, 14:33 »

Здравствуйте,
Есть ячейка таблицы допустим с текстом "qqqwww rrr\nzzz"
Если по ширине в ячейке не вмещается первая строка "qqqwww rrr", то она обрезается (+ в конце рисуется троеточие).
И, самое главное, что вторая строчка "zzz" тоже не рисуется.
Как с этим бороться?

Я выяснил что:
1) если задать в ячейке стиль wrap, то всё нормально рисуется до упора, т.е. до самого низа, и только там обрезается. Но недостаток в том, что не всегда хорошо, когда 1 строчка разделяется на несколько строк. К тому же, если слово в первой строчке тоже не вмещается, то возникает та же проблемма с досрочным обрезанием. Как следствие неудаётся запретить переносы слов, заменив все пробелы на  неблокированные пробелы.
2) если пойти в недры qt, то там будет цикл по строчкам, в котором, при первом же обрезании стоит break.
3) если в делегате разделить текст построчно на N строк и потом вызвать рисование ячейки N раз каждый раз давая на вход текст в котором все строки кроме i-ой пустые (для примера выше, на 1-ой итерации будет "qqqwww rrr\n", на второй "\nzzz"), то почти хорошо, кроме того, что по вертикали строки слипаются, т.к. кроме обрезания происходит ещё и центровка необрезанного текста.

Как ещё можно обойти эту особенность? И вообще досрочное обрезание - это глюк или новый прикол белых имеет какой-то смысл?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Июль 14, 2015, 15:47 »

Схожие проблемы в QListWidget решал своим делегатом, используя QTextLayout (там есть пример как рисовать многострочный QLabel). Нужно учесть (в перекрытом sizeHint) что если строка слишком длинная, то обрезать ее придется  (напр 5 строк максимум)
Записан
Sasha
Гость
« Ответ #2 : Июль 14, 2015, 17:15 »

Схожие проблемы в QListWidget решал своим делегатом, используя QTextLayout (там есть пример как рисовать многострочный QLabel).
В недрах Qt, кстати, они через QTextLayout и рисуют в конечном итоге, но не хотелось сильно отдаляться от стандартного рисования ячейки.
Нужно учесть (в перекрытом sizeHint) что если строка слишком длинная, то обрезать ее придется  (напр 5 строк максимум)
Это я не понял. Почему нужно обрезать?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Июль 15, 2015, 08:43 »

В недрах Qt, кстати, они через QTextLayout и рисуют в конечном итоге, но не хотелось сильно отдаляться от стандартного рисования ячейки.
К сожалению, рисуют не так как (мне) нужно. Конечно лучше было бы добиться того же нужными опциями/флагами, но я такой возможности не нашел
Это я не понял. Почему нужно обрезать?
Ну вот в айтем QListWidget попал текст аж страница. Если ничего не делать, выходит громадная ячейка с wrap. Как там с таблицей - смотрите по обстановке
Записан
Sasha
Гость
« Ответ #4 : Июль 15, 2015, 16:07 »

Это я не понял. Почему нужно обрезать?
Ну вот в айтем QListWidget попал текст аж страница. Если ничего не делать, выходит громадная ячейка с wrap. Как там с таблицей - смотрите по обстановке
Примерно понятно, но по-моему нужно просто рисовать пока не дошли до низа ячейки.
Записан
Sasha
Гость
« Ответ #5 : Июль 15, 2015, 17:55 »

В общем сделал так, как не хотел делать с самого начала - предварительно подготовил строку:
Код
C++ (Qt)
...
QRect rcText = style->subElementRect( QStyle::SE_ItemViewItemText, &opt, widget );
const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1; // hak from qt
rcText = rcText.adjusted( textMargin, 0, -textMargin, 0 ); // remove width padding // hak from qt
int rcTextW = rcText.width();
opt.text.replace( '\n', QChar::LineSeparator );
QStringList l = opt.text.split( QChar::LineSeparator );
opt.text = "";
for( int i=0,n=l.size(); i<n; i++ )
  {
l[i] = opt.fontMetrics.elidedText( l[i], opt.textElideMode, rcTextW );
opt.text += l[i];
if( i<(n-1))opt.text += QChar::LineSeparator;
  }
opt.textElideMode = Qt::ElideNone;
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget);
...
 
Но это может однажды перестать правильно работать
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.143 секунд. Запросов: 22.