Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch the link click event in QPlainTextEdit

Tags:

c++

qt

If I create a link using appendHtml in QPlainTextEdit, how can I figure out if user click on it, and do something with the URL? There is no signal for clicking on URL, like in QTextBrowser.

Is there any way to accomplish this, other than creating a completely new Qt control that does this?

NOTE: I am not interested in different components like QTextEdit or QTextBrowser as these are incredibly slow. I specifically want to catch link clicks within either QPlainTextEdit or any customization of it, which has the same performance.

like image 723
Petr Avatar asked Dec 25 '22 12:12

Petr


2 Answers

There is the function QPlainTextEdit::anchorAt:

Returns the reference of the anchor at position pos, or an empty string if no anchor exists at that point.

To activate some link the user should press left mouse button on this object and release the button also on this link. That can be tracked by mousePressEvent and mouseReleaseEvent.

Unfortunately there is no simple mechanism to check on release that the button is released on the same link object. It is possible to compare only anchor text. So, the false positive detection can happen if there are several anchors with the same link. If it is a problem, it possible to do the similar trick with checking text selection state as in QTextBrowser if the widget text is selectable.

The simplest implementation:

#ifndef PLAINTEXTEDIT_H
#define PLAINTEXTEDIT_H

#include <QPlainTextEdit>
#include <QMouseEvent>

class PlainTextEdit : public QPlainTextEdit
{
    Q_OBJECT

private:
    QString clickedAnchor;

public:
    explicit PlainTextEdit(QWidget *parent = 0) : QPlainTextEdit(parent)
    {
    }

    void mousePressEvent(QMouseEvent *e)
    {
        clickedAnchor = (e->button() & Qt::LeftButton) ? anchorAt(e->pos()) :
                                                         QString();
        QPlainTextEdit::mousePressEvent(e);
    }

    void mouseReleaseEvent(QMouseEvent *e)
    {
        if (e->button() & Qt::LeftButton && !clickedAnchor.isEmpty() &&
            anchorAt(e->pos()) == clickedAnchor)
        {
            emit linkActivated(clickedAnchor);
        }

        QPlainTextEdit::mouseReleaseEvent(e);
    }

signals:
    void linkActivated(QString);
};

#endif // PLAINTEXTEDIT_H

The signal linkActivated is emitted with href anchor text. For example the signal will be emitted with the string "http://example.com" when the following anchor is activated:

QString html = "<a href='http://example.com'>Click me!</a>";
text->appendHtml(html);
like image 128
Orest Hera Avatar answered Jan 06 '23 05:01

Orest Hera


Seems QPlainTextEdit doesn't support links at all. As the docu states it is for plain text with bit formatting only.

But it seems you can use a QTextBrowser as text editor if you set the readOnly property to false. Something like setProperty("readOnly", false) should work.

like image 37
Aaron Avatar answered Jan 06 '23 03:01

Aaron