Название: [РЕШЕНО] Определить QRect для слова в QLabel Отправлено: Alp от Сентябрь 11, 2009, 18:56 Надо сделать (точнее, он уже сделан, надо подумать как его улучшить) виджет на базе QLable с "активными зонами". Ну, например, какое-то слово подсвечено и при клике на нем появляется окошко редактора прямо поверх слова (то, что называют in-place редактирование), после чего юзер вбивает туда что-то и завершает работу с этим редактором (нажатие Enter, потеря фокуса - неважно). Содержимое эдита после этого замещает слово на котором был произведен клик. И второй случай - с менюшками (с ними проще)
В принципе, такой код есть, писанный мной, но под кайро. Там сначала бьется по словам весь текст, потому считается прямоугольник для каждого слова, проверяются границы окна и список хот-ректов запоминается для дальнейшего использования. В общем сложно для чтения, но работает. Сейчас думаю как бы это попроще реализоваться средствами Qt. Пока в голову пришло QLabel + хтмл-ссылки (и подсветка и стили и передача типа поля/кода поля впо ссылке). Проблема одна: как попроще получить список прямоугольников для слов. Или хотя бы определить QRect для кликнутого слова. С меню проблем особых нет - взял координаты клика по OnLinkActivated, показал меню, заместил нужное, показал на лейбле, то с редактирование сложнее. Есть какие-нибудь мысли или пинки в нужном направлении? Название: Re: Определить QRect для слова в QLabel Отправлено: Rcus от Сентябрь 11, 2009, 19:15 Я думаю нужно скорее смотреть в сторону классов Rich Text Processing - эта часть управляет текстом в стандартных текстовых виджетах и имеет довольно развитый публичный API.
Название: Re: Определить QRect для слова в QLabel Отправлено: SABROG от Сентябрь 11, 2009, 20:59 По идее можно подсмотреть в коде QLineEdit, он же с точностью определяет между какими буквами был сделан клик, чтобы установить курсор ввода.
Название: Re: Определить QRect для слова в QLabel Отправлено: Alp от Сентябрь 12, 2009, 07:02 Я думаю нужно скорее смотреть в сторону классов Rich Text Processing - эта часть управляет текстом в стандартных текстовых виджетах и имеет довольно развитый публичный API. Думаю, это будет уже оверхэд. Проще тогда использовать описанный мной алгоритм.Название: Re: Определить QRect для слова в QLabel Отправлено: Alp от Сентябрь 12, 2009, 07:36 По идее можно подсмотреть в коде QLineEdit, он же с точностью определяет между какими буквами был сделан клик, чтобы установить курсор ввода. Посмотрел. Определение позиции курсора по QPoint реализуется через вызов QLineEditPrivate::xToPos(const QPoint&). А вот имплементацию этого метода в /qt/qt/src почему-то найти не могу. Точнее, вобще не могу найти имплементацию QLineEditPrivate. Может у тебя получится?Но в целом идея здравая. Попробую сделать невидимый QLineEdit, по точке определять позицию курсора (она же - индекс символа в тексте), и по ней определять границы слова. Затем немного магии: ставим курсов в начало слова, дергаем за cursorRect(), затем переставляем курсор в конец слова и снова дергаем за тот же метод. В итоге имеем два прямоугольника описывающих _курсор_ в начале слова и в конце. Оттуда получаем координаты нужного QRect для слова целиком. Попробую реализовать. Название: Re: Определить QRect для слова в QLabel Отправлено: Rcus от Сентябрь 12, 2009, 09:00 Думаю, это будет уже оверхэд. Проще тогда использовать описанный мной алгоритм. /* sigh */ Знаете что идея высказанная в последнем посте тоже использует классы обработки текста (QTextLayout в частности). Давайте поговорим об оверхеде, да.Название: Re: Определить QRect для слова в QLabel Отправлено: Alp от Сентябрь 12, 2009, 12:28 Думаю, это будет уже оверхэд. Проще тогда использовать описанный мной алгоритм. /* sigh */ Знаете что идея высказанная в последнем посте тоже использует классы обработки текста (QTextLayout в частности). Давайте поговорим об оверхеде, да.Надо ведь не только определить "вот слово, по которому кликнули", надо еще хранить информацию о типе поля, о текстовом его содержимом. В итоге: тип входных данных тот же. Начальная обработка текста: построение коллекции прямоугольников и типов данных для каждого из них Обработчик клика: определить какой прямоугольник содержит точку и вывести необходимые данные. Единственная мысль хоть как-то связанная с RT-работой - использовать не QLineEdit, QTextEdit? т.к. первый не умеет перенос строк. В остальном удобных методов получения чего надо в общем-то и нет. Название: Re: Определить QRect для слова в QLabel Отправлено: SABROG от Сентябрь 12, 2009, 12:36 QLineEdit использует публичный класс QTextLine. А именно метод:
int QTextLine::xToCursor ( qreal x, CursorPosition cpos = CursorBetweenCharacters ) const Возможно даже, что все уже есть. Остается только это применить, в документации класс описан. И где-то я в QQ видел применение этого класса для отрисовки текста. Название: Re: Определить QRect для слова в QLabel Отправлено: Igors от Сентябрь 12, 2009, 12:41 А если просто создать "сверху" нужные QLineEdit'ы и замаскировать их под static text ?
Название: Re: Определить QRect для слова в QLabel Отправлено: Alp от Сентябрь 12, 2009, 12:59 QLineEdit использует публичный класс QTextLine. А именно метод: Пришлось отказаться от столь подходящего QLineEdit, т.к. в легенде (отображаемом тексте с хотспотами) могут быть символы перевода строки. Методы переводящие точку в позицию курсора и наоборот уже нашел.int QTextLine::xToCursor ( qreal x, CursorPosition cpos = CursorBetweenCharacters ) const Возможно даже, что все уже есть. Остается только это применить, в документации класс описан. И где-то я в QQ видел применение этого класса для отрисовки текста. Название: Re: Определить QRect для слова в QLabel Отправлено: Alp от Сентябрь 12, 2009, 13:00 А если просто создать "сверху" нужные QLineEdit'ы и замаскировать их под static text ? Была мысль. Но что делать если длина строки превышает ширину виджета? Вручную бить на несколько QLineEdit? =)Название: Re: Определить QRect для слова в QLabel Отправлено: Alp от Сентябрь 12, 2009, 13:22 К сожалению, проблема решена. Точнее, придется использовать старый алгоритм с разбивкой по словам и подсчетом размеров каждого слова.
Использовать для этих целей QTextEdit и QLineEdit не получится, т.к. метод cursorRect возвращает именно rect, а не геометрию. Т.е. начальная точка курсора всегда будет (0,0). У QLineEdit cursorRect вообще защищеный, так что при всем желании не взять координаты каретки. Далее, не совсем понятно как использовать QTextEdit, в отсутствии нормальных программных методов перемещения по тексту. Либо вызывать в цикле moveCursor(NextChar), либо никак. Других методов программно переместить курсор-каретку, похоже, нет. Аналогичные методы у QTextCursor'а не перемещают каретку. Название: Re: Определить QRect для слова в QLabel Отправлено: Alp от Сентябрь 23, 2009, 19:45 В результате получилось вот что:
Код
На вход получает Rect виджета, на котором рисуется текст (для верного расставления переносов), метрика выбранного шрифта и строку (допускаются символы перевода строки, по умолчанию считается, что wordWrap включен). |