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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QTextEdit: Применение форматирование к выделенному тексту.  (Прочитано 6530 раз)
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« : Февраль 18, 2015, 22:48 »

В моем редакторе, основанном на QTextEdit, необходимо сделать кнопку очистки форматирования выделенного текста.

Проблема в том, что setBlockFormat(), вопреки документации, применяет свое форматирование только для первого абзаца в выделенном тексте. А остальные абзацы не трогает. Причем, делает это как-то выборочно - некоторые виды форматирования применяет для всего выделенного текста, некоторые - только для первого абзаца в выделенном тексте.

Вот например, следующий код должен установить top и bottom отступ в 50 pix. И должен сделать это для всех абзацев в выделенном тексте, ибо "Sets the block format of the current block (or all blocks that are contained in the selection) to format."

Код:
   QTextEdit textArea;

   ...

   QTextBlockFormat format;

   // Убираются отступы
   format.setLeftMargin(0);
   format.setRightMargin(0);
   format.setTopMargin(50); // 50 - для отладки, чтобы было видно обработку абзаца
   format.setBottomMargin(50);
   format.setAlignment(Qt::AlignLeft);

   textArea->textCursor().setBlockFormat(format);

Однако, на деле, вертикальные отступы в 50 pix устанавливаются только первому абзацу (когда выбрали, например мышкой, сразу три абзаца). А нужно, чтобы отступы в 50 pix устанавливались всем абзацам.

Я решил тогда пробегать все блоки, которые содержатся в выделенном мышкой фрагменте. Сделал так:

Код:
   QTextCursor cursor(textArea->textCursor());
   for (QTextBlock::iterator it = cursor.block().begin(); !(it.atEnd()); ++it)
   {
       qDebug() << "Block iterator position: " << it.fragment().position() << " Fragment len: " << it.fragment().length();

       QTextCursor tempCursor = cursor;
       tempCursor.setPosition(it.fragment().position());
       tempCursor.setPosition(it.fragment().position() + it.fragment().length(), QTextCursor::KeepAnchor);
       tempCursor.setBlockFormat(format);
   }

И в отладке вижу, что даже если выделено несколько абзацев (на ~300 символов), в итераторе пробегается только один абзац:

Код:
Block iterator position:  3519  Fragment len:  35

Вопрос. Как же пробежать все абзацы в выделении и применить им нужное форматирование?
Записан

Собираю информацию по крупицам
http://webhamster.ru
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #1 : Февраль 19, 2015, 07:32 »

Делал как то редактор, и в нем очищение от форматирования делал с помощью: editor->setCurrentCharFormat( QTextCharFormat() );
Записан

Swa
Самовар
**
Offline Offline

Сообщений: 170


Просмотр профиля
« Ответ #2 : Февраль 19, 2015, 10:05 »

У меня работает этот код, формат присваивается всем выделенным абзацам.
Может, проблема где-то в другом месте?
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #3 : Февраль 19, 2015, 15:57 »

Делал как то редактор, и в нем очищение от форматирования делал с помощью: editor->setCurrentCharFormat( QTextCharFormat() );

Этот код рабочий, но у него есть побочный эффект: если в выделение попала картинка, она будет удалена.

А ведь нам нужно только очищать форматирование.
Записан

Собираю информацию по крупицам
http://webhamster.ru
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #4 : Февраль 19, 2015, 16:10 »

У меня работает этот код, формат присваивается всем выделенным абзацам.
Может, проблема где-то в другом месте?

Да, сделал минимальный пример, проблема оказалась дальше.

Чтобы гарантированно удалить все форматирование, заданное через style="...", я выдергиваю HTML-код выделенного элемента, прочищаю его от атрибутов style, и вставляю обратно:

Код:
 // Удаление какого-либо форматирования стилем
 QString htmlCode=textArea->textCursor().selection().toHtml();
 qDebug() << "Before remove style: " << htmlCode;

 // В регулярных выражениях Qt кванторы по-умолчанию жадные (greedy)
 // Поэтому напрямую регвыру указывается что кванторы должны быть ленивые
 QRegExp replace_expression("style=\".*\"");
 replace_expression.setMinimal(true);

 htmlCode.replace(replace_expression, "");

 qDebug() << "After remove style: " << htmlCode;

 QString currStyleSheet=textArea->document()->defaultStyleSheet();
 textArea->document()->setDefaultStyleSheet(" ");

 textArea->textCursor().removeSelectedText();
 textArea->textCursor().insertHtml(htmlCode);

 textArea->document()->setDefaultStyleSheet(currStyleSheet);

Проблема в том, что Qt за каким-то хером, несмотря на тот HTML, который ему передан для вставки, форматирует первую строку по какому-то ему ведомому алгоритму.

Я наблюдаю этот глюк и если вставить просто текст из браузера - первая строка в момент вставки будет как-то по-другому отформатирована даже в нативном QTextEdit, попробуйте например взять кусок разноцветного исходника отсюда:

http://www.qtcentre.org/threads/40001-How-to-change-current-line-format-in-QTextEdit

и вставить в QTextEdit. Первая строка гарантированно будет иметь более другие вертикальные отступы.

И вот с этим я никак не могу побороться. Метод setCurrentCharFormat() не подходит, так как он не только очищает формат символов, но и удаляет картинки. А мне то нужно только очищать форматирование.
Записан

Собираю информацию по крупицам
http://webhamster.ru
Bepec
Гость
« Ответ #5 : Февраль 19, 2015, 16:18 »

Мб бредово будет звучать, но там вроде идёт поведения аля "вставляемые строки имеют тот же формат, что и символ/абзац перед ними".
Просто проверьте, что будет если сначала вставить кусок текста с вашим форматированием, а потом удалить их?

PS вот это бред я написал, но а чем не попытка Веселый
Записан
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #6 : Февраль 20, 2015, 11:45 »

Мб бредово будет звучать, но там вроде идёт поведения аля "вставляемые строки имеют тот же формат, что и символ/абзац перед ними".
Просто проверьте, что будет если сначала вставить кусок текста с вашим форматированием, а потом удалить их?

PS вот это бред я написал, но а чем не попытка Веселый

Вовсе не бред. Только последовательность немного другая должна быть: вставить символ -> выделить его, задать форматирование -> Сделать то что изначально было необходимо -> удалить первый символ
... но костыль
Записан
Bepec
Гость
« Ответ #7 : Февраль 20, 2015, 12:17 »

наличие костыля лучше чем его отсутствие. А бред - по форме изложения Веселый
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #8 : Февраль 20, 2015, 20:32 »

Делал как то редактор, и в нем очищение от форматирования делал с помощью: editor->setCurrentCharFormat( QTextCharFormat() );

Кстати, проблма не только в том, что удаляются картинки.

Еще оказалось, что в Qt 4.x не удаляется цвет текста. А в Qt 5.x - удаляется. Я проверил вначале на пятой версии, а в четвертой мне такой сюрприз.
Записан

Собираю информацию по крупицам
http://webhamster.ru
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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