Я пытаюсь показать всплывающую подсказку, когда курсор находится над ключевым словом в текстовом редакторе, используя:
QTextCursor cursor = cursorForPosition(pos);
cursor.select(QTextCursor::WordUnderCursor);
Это работает хорошо, но определение слова не соответствует моим потребностям. Например, ключевое слово \abcde распознается как 2 слова \ и abcde. Точно так же слово a1:2 распознается в трех частях a1, : и 1. В основном я хотел бы изменить поведение, например, слово определяется как набор символов, разделенных пробелом.
Я попробовал QTextCursor::BlockUnderCursor, но он делает то же самое, что и QTextCursor::LineUnderCursor, и возвращает всю строку.
Если я хорошо понимаю, мне нужно зацикливаться от якоря влево с шагами -1, пока я не достигну пробела, и мне нужно сделать то же самое из положения вправо с шагом +1, пока я не достигну пробела.
Я нашел способ выделять слова, разделенные пробелом, при изменении положения курсора.
void MainWindow::on_textEdit_cursorPositionChanged()
{
QTextCursor *cursor = new QTextCursor(ui->textEdit->textCursor());
int start,end;
while(!cursor->atEnd())
{
cursor->movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
if (cursor->selectedText()==' ')
break;
cursor->clearSelection();
}
end=cursor->position();
while(!cursor->atStart())
{
cursor->movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);
if (cursor->selectedText()==' ')
break;
cursor->clearSelection();
}
start=cursor->position();
for(int i=start;i<end;i++)
{
cursor->movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
}
QString s=cursor->selectedText();
}
Мы должны добавить проверку на возврат строки в дополнение к пробелу. \n не работает, потому что возвращается конец абзаца юникода, поэтому я использовал cursor.selectedText().at(0) == QChar(8233). Я не уверен в Linux и Windows, и позже я проверю Windows. Спасибо
@JRR Я обновил условие разрыва вместо указанного вами условия, я также использую Linux, и оно работает, я должен добавить его и к обоим условиям, что касается окон, я проверил и увидел, что окна используют '\ r\n', посмотрите, если это сокращает ваши исследования. Удачи if (cursor->selectedText()==' ' || cursor->selectedText()==QChar(8233))
И как это будет обрабатывать мышь? Не забудьте дважды щелкнуть, перетащить Shift, щелкнуть правой кнопкой мыши и т. д.
Если вы выбросите QTextEdit и замените оболочкой Qt для Scintilla, вы можете использовать SCI_SETWORDCHARS(), чтобы составить слово. scintilla.org/ScintillaDoc.html#SCI_SETWORDCHARS
@ user3450148 на моей стороне это реализовано в bool CodeEditor::event(QEvent *event) повторной реализации такого события всплывающей подсказки if (event->type() == QEvent::ToolTip) {} else { QPlainTextEdit::event(event);}, и это работает хорошо.
Что ж, начнем с настоящей проблемы . Была "ошибкой" начиная с Qt4. Небольшое обсуждение можно найти здесь. В истинном стиле Qtc ошибка была закрыта с помощью этого комментария:
Это легко сделать пользователями, реализующими свой собственный выбор на основе их собственные критерии
И ноль примеров того, как это сделать, еще в 2009 году. С тех пор Qt принял Границы слов Unicode . Они также удвоили предосудительную практику написания кода, помещая все, что кто-либо хотел бы изменить, во внутренние закрытые классы. Вот фрагмент из QTextCursor
Некоторые разработчики PyQt утверждают, что взломали его здесь. Это вам мало поможет, потому что с тех пор кому-то пришла в голову блестящая идея заставить select() использовать перечисление.
Если вы используете Qt6, вы облажались, или так кажется. Я не могу найти официальную версию Qt6 qtextengine.cpp. Большинство людей, включая меня, перестали использовать Qt за последние два года из-за подобных вещей.
Ваше «решение» состоит в том, чтобы создать собственный класс QTextEngine и заставить ваш QTextCursor использовать его в макете. Вам нужно переопределить это жестко закодированное фиаско, чтобы всегда возвращать false.
Ваше второе «решение» — установить eventFilter(). В нем вы должны перехватывать все события в QTextEdit, которые могут выбрать/переместить слово, и обрабатывать их самостоятельно.
Третье «решение» — создать собственный класс QTextEdit и переопределить обработчик event() по умолчанию. Опять же, вы должны перехватывать каждое нажатие клавиши/мыши/любое событие, которое может выбрать или переместить слово.
НЕ пытайтесь использовать ярлык и сопоставлять сигнал selectionChanged(). Если кто-то попытается выбрать 3 символа с помощью мыши/клавиатуры, вы форсируете его до полного слова.
При переопределении событий или их фильтрации обязательно замените QTextCursor в виджете редактирования.
На протяжении многих лет многие люди предпочитали создавать собственный QTextEngine, потому что это было одно место, где можно было все исправить. Хм, они тоже строили из исходников. Они создали пользовательскую библиотеку Qt после изменения класса QTextEngine. Наиболее добавлено такое свойство, как
Логическое значение enableUnicodeWords;
Если это правда, наступательный метод работал как есть. Если false, он всегда возвращает false. Настройка исходного кода Qt требует, чтобы вы где-то опубликовали указанные настройки. Нет, я не нашел ничего опубликованного с помощью быстрого поиска.
Это было проблемой по крайней мере с 2009 года, и, поскольку она затрагивала только настольные приложения, ее игнорировали. Qt провел последнее десятилетие, сосредоточившись на телефонах и QML в ущерб всему остальному.
Похоже, вам нужно перебирать символы, чтобы настроить QTextCursor под свои нужды. Это не должно быть слишком сложно, используя QTextCursor::anchor() , QTextCursor::position() и QTextCursor::setPosition() или QTextCursor::movePosition().