Search code examples
qthyperlinkpyqtqtextbrowser

Handling different links differently in QTextBrowser


I'm trying to set up a QTextBrowser where most hyperlinks work normally, but hyperlinks that begin with an arbitrary prefix will instead call a function.

@three-pineapples supplied some great instructions here for how to achieve the latter behavior, detecting a prefix on a url and calling a method based on that url.

The problem is, in order for this to work, the QTextBrowser's setOpenLinks() method has to be set False so that the QTextBrowser will emit the anchorClicked() signal. Otherwise, the prefixed links are handled automatically by Qt and have no custom behavior. But if I set setOpenLinks() False, normal links now don't work properly.

Any ideas how to re-implement link-handling manually in the environment with setOpenLinks() set False, or else getting the custom behavior on the prefixed links in the environment where it is set True? Thanks for your help!


Solution

  • Method 1: full control (but duplicating Qt code)

    If you want to have full control, disables Qt's link handling mechanism using setOpenLinks(false) and implement link handling yourself completely, based on the Qt implementation (QTextBrowserPrivate::_q_activateAnchor) for normal links:

    bool isFileScheme =
            url.scheme() == QLatin1String("file")
    #if defined(Q_OS_ANDROID)
            || url.scheme() == QLatin1String("assets")
    #endif
            || url.scheme() == QLatin1String("qrc");
    if ((openExternalLinks && !isFileScheme && !url.isRelative())
        || (url.isRelative() && !currentURL.isRelative() && !isFileScheme)) {
        QDesktopServices::openUrl(url);
        return;
    }
    
    q->setSource(url);
    

    So, open the url using QTextBrowser::setSource or open it externally using QDesktopServices::openUrl.

    Method 2: integrated approach

    Enable Qt's link handling mechanism using setOpenLinks(true). anchorClicked will be emitted in general when the link has a file scheme or more exactly when the following condition fails:

    if ((openExternalLinks && !isFileScheme && !url.isRelative())
        || (url.isRelative() && !currentURL.isRelative() && !isFileScheme)) 
    

    If you do not call setSource or change the content of the QTextDocument, the source will be automatically set to the clicked url.