Добавление возможности вставлять гиперссылки в QTextBrowser

Я собирал текстовый редактор на основе этот пример Питера Голдсборо. Текстовое поле заполняется из HTML, но отображается как форматированный текст.

Я сделал так, чтобы пользователи могли нажимать на гиперссылки, уже находящиеся в текстовом поле. Однако я понятия не имею, с чего начать добавление функциональности, чтобы пользователи могли добавлять свои собственные новые интерактивные гиперссылки при редактировании. Буду очень признателен за подсказки от знающих!

(Я специально пытаюсь избежать подхода, используемого здесь - этот парень, похоже, использует парсер который сканирует весь документ на наличие структуры, подобной ссылке, и добавляет теги html. Это кажется намного сложнее и более подвержено ошибкам, чем должно быть, и мне интересно, есть ли способ просто окружить выделенный текст тегами html.)

Я попробовал приведенное ниже предложение @kuba-ober, хотя, поскольку я работаю с привязкой PyQt4 к Qt для Python, я изменил его:

def setHyperlinkOnSelection(self, url):
    cursor = self.text.textCursor()
    if not cursor.hasSelection():
        return False
    format = QtGui.QTextCharFormat()
    format.setAnchor(True)
    format.setAnchorHref(url)
    cursor.mergeBlockCharFormat(format)
    return True

К сожалению, это не сработало, но я использовал это, чтобы адаптировать некоторые методы форматирования в примере чтобы получить следующее:

def setHyperlinkOnSelection(self, url):

    # Grab the text's format
    fmt = self.text.currentCharFormat()

    # Set the format to an anchor with the specified url
    fmt.setAnchor(True)
    fmt.setAnchorHref(url)

    # And set the next char format
    self.text.setCurrentCharFormat(fmt)

В результате получается ссылка (синий подчеркнутый текст, который при преобразовании в html правильно отформатирован с помощью тегов «a href»), но он не активен (наведение курсора мыши на текст не меняется на указывающую руку, и щелчок ничего не делает)...


person Grav    schedule 19.05.2017    source источник


Ответы (2)


QTextBrowser работает на QTextDocument. HTML — это формат представления структуры данных, которую представляет QTextDocument.

Подход в вашем связанном решении без необходимости работает с гипертекстовым представлением, в то время как с высокоуровневой структурой QTextDocument намного проще работать, поскольку она имеет логическую структуру, уже «разобранную» — в конце концов, QTextDocument является представлением AST для гипертекст.

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

bool setHyperlinkOnSelection(QTextBrowser * browser, const QString & url) {
  auto doc = browser->document();
  QTextCursor cur(doc);
  if (!cur.hasSelection())
    return false;
  QTextCharFormat format;
  format.setAnchor(true);
  format.setAnchorHref(url);
  cur.mergeBlockCharFormat(format);
  return true;
}

Обратите внимание, что простое предоставление ссылки не означает, что она действует как ссылка. Переход по внешним ссылкам потенциально опасен, и вам необходимо явно включить ii. Если вам нужно открывать ссылки в самом браузере, установите:

browser->setOpenLinks(true);

Даже если openLinks равен false (по умолчанию), сигнал anchorClicked испускается, и вы можете действовать в соответствии с ним.

Если вам нужно открывать внешние ссылки в системном веб-браузере по умолчанию, установите:

browser->setOpenExternalLinks(true);

Когда установлено, сигнал anchorClicked не будет излучаться для этих ссылок.

Внешняя ссылка — это ссылка со схемой URL, отличной от file или qrc.

person Kuba hasn't forgotten Monica    schedule 19.05.2017
comment
Спасибо @kuba-ober! Это, кажется, привело меня на полпути - я обновил описание выше. - person Grav; 26.05.2017

Хорошо, я понял - ссылки не работают, когда qtextbrowser установлен в режим только для чтения. Подробнее об этом здесь. Если у кого-нибудь есть информация о том, как преодолеть это очевидное ограничение в Qt, я был бы признателен, но пока я собираюсь обойти это, быстро переключаясь между режимом только для чтения и режимом редактирования.

person Grav    schedule 29.05.2017