1

I've been assembling a text editor based on this example by Peter Goldsborough. The text box is populated from an html, but displays as rich text.

I've made it so users are able to click on hyperlinks already in the text box. However, I have no idea where to start in adding functionality so that users can add their own, new clickable hyperlinks as they edit. I would be very grateful for pointers from those who know!

(I am specifically trying to avoid the approach taken here - this fellow seems to be using a parser that scans the entire document for link-like structure and adds in the html tags. That seems much harder and more error-prone than it needs to be, and I wonder if there is just a way to surround highlighted text with html tags.)

I tried out the suggestion below by @kuba-ober, though since I'm working in the PyQt4 binding of Qt for Python, I modified it:

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

That did not work, unfortunately, but I used that to adapt some of the formatting methods in Goldsborough's example to yield the following:

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)

That results in a link (blue underlined text which, when converted to html, is correctly formatted with "a href" tags), but it is not clickable (hovering over the text with the mouse doesn't change to the pointing hand, and clicking doesn't do anything)...

Grav
  • 347
  • 1
  • 2
  • 15

2 Answers2

1

A QTextBrowser operates on QTextDocument. The html is a representation format for the data structure that the QTextDocument represents.

The approach in your linked solution unnecessarily operates on the hypertext representation, while the high-level QTextDocument structure is much easier to operate on as it has the logical structure already "parsed out" - after all, a QTextDocument is a represention of the AST of the hypertext.

You need to use the cursor mechanism of the document to operate on the selection and turn it into a hyperlink. Namely, mergeBlockCharFormat to a format with an anchor:

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;
}

Note that merely providing a link doesn't make it act as a link. Following external links is potentially dangerous and you need to explicitly enable ii. If you need to open links in the browser itself, set:

browser->setOpenLinks(true);

Even if openLinks is false (it's the default), the anchorClicked signal is emitted and you can act on it.

If you need to open external links in the system default web browser, set:

browser->setOpenExternalLinks(true);

When set, the anchorClicked signal won't be emitted for those links.

An external link is a link with URL scheme other than file or qrc.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • Thank you @kuba-ober! That seems to have gotten me partway there - I've updated the description above. – Grav May 25 '17 at 23:16
0

Ok, I figured it out - links don't work when the qtextbrowser is set to read-only mode. More details on that here. If anyone has any info on how to overcome this apparent limitation in Qt, I'd be grateful, but for now I'm gonna work around this by having a quick-switch between read-only and editable mode.

Grav
  • 347
  • 1
  • 2
  • 15