【问题标题】:Clickable hyperlink in QTextEditQTextEdit 中的可点击超链接
【发布时间】:2016-03-08 03:24:17
【问题描述】:

我想用QTextEdit(只读模式)来显示一个可点击的超链接,我曾经这样做过

QTextEdit *textEdit = new QTextEdit;
QTextCursor cursor(textEdit->document());
textEdit->setTextCursor(cursor);
cursor->insertHtml("<a href=\"www.google.com\" >Google</a>");
textEdit->show();

此代码会将 Google 显示为超链接,但无法点击。
如果我用过

QTextEdit *textEdit = new QTextEdit;
QTextCursor cursor(textEdit->document());
textEdit->setTextCursor(cursor);
QTextCharFormat linkFormat = cursor.charFormat();
linkFormat.setAnchor(true);
linkFormat.setAnchorHref("http://www.google.com");
linkFormat.setAnchorName("Google");
cursor.insertText("Google", linkFormat);

然后什么都没有发生。 “Google”只是普通文本。

请帮我插入指向QTextEdit的可点击超链接。

【问题讨论】:

    标签: qt qtextedit


    【解决方案1】:

    使用 QTextBrowser 更简单(正如另一个答案所建议的那样)。但是,如果出于某种原因您想使用QTextEdit,请尝试使用setTextInteractionFlags() 更改文本交互标志。 我认为您必须启用Qt::LinksAccessibleByMouse 标志。

    Qt::TextInteractionFlagQTextEdit::textInteractionFlags

    【讨论】:

    • 注意:如果您将 setTextInteractionFlag() 与 QTextEdit 一起使用,则无法检测到链接被点击。如果要手动处理激活的链接/锚点,则必须使用 QTextBrowser。
    【解决方案2】:

    要在 QTextEdit 中有可点击的超链接,你可以使用

    1. QTextCharFormat::setAnchorHref为某些文本设置链接

    2. QWidget::mousePressEvent捕捉鼠标按下事件

    3. QTextEdit::anchorAt获取链接

    这是最小的工作 PyQt 示例,

    import sys
    from PyQt5.Qt import QDesktopServices, QUrl, QApplication, QColor, Qt
    from PyQt5.QtWidgets import QTextEdit
    
    
    class MyWidget(QTextEdit):
    
        def mousePressEvent(self, e):
            self.anchor = self.anchorAt(e.pos())
            if self.anchor:
                QApplication.setOverrideCursor(Qt.PointingHandCursor)
    
        def mouseReleaseEvent(self, e):
            if self.anchor:
                QDesktopServices.openUrl(QUrl(self.anchor))
                QApplication.setOverrideCursor(Qt.ArrowCursor)
                self.anchor = None
    
    
    app = QApplication(sys.argv)
    editor = MyWidget()
    cursor = editor.textCursor()
    fmt = cursor.charFormat()
    fmt.setForeground(QColor('blue'))
    address = 'http://example.com'
    fmt.setAnchor(True)
    fmt.setAnchorHref(address)
    fmt.setToolTip(address)
    cursor.insertText("Hello world again", fmt)
    editor.show()
    app.exec_()
    

    【讨论】:

    • 这是我结束的基本解决方案。我将其更改为使用 mouseMoveEvent() 来设置锚点,并在锚点上时将光标更改为 PointingHand,并在不在锚点上时重置光标。不再需要 mousePressEvent(),如果设置了锚点,则使用 mouseRelease 打开 url。
    • 不要忘记从被覆盖的方法中调用 super() 类 mousePressEvent 和 mouseReleaseEvent 实现,否则您将失去与小部件的标准鼠标交互!
    【解决方案3】:

    据我尝试,当使用QTextEdit + Qt::LinksAccessibleByMouse 时,我可以点击链接,但没有采取任何行动(即链接未打开)。唯一可能的操作是右键单击链接并选择Copy Link Location

    如前所述,一种选择是使用QTextBrowser。在这种情况下,您还必须设置QTextBrowser::openExternalLinks 属性,以便使用默认浏览器打开链接,否则它将在文本浏览器小部件中打开。

    如果您有一个只读文本,另一种选择是使用QLabelrich format,并使用QLabel::linkActivated 信号到open the URL

    label->setTextFormat(Qt::RichText);
    QObject::connect(label, &QLabel::linkActivated, [](const QString & link) {
      QDesktopServices::openUrl(link);
    });
    

    【讨论】:

      【解决方案4】:

      如果 QTextBrowser 只读取文本,则可以使用 QTextBrowser 而不是 QTextEdit。

      【讨论】:

        【解决方案5】:

        为了使setTextInteractionFlags() 工作,需要设置openExternalLinks 属性。由于此属性在 QTextEdit 上不可用,这里有一个小技巧来启用它。

        auto &clist = edit->children();
        for each (QObject *pObj in clist)
        {
          QString cname = pObj->metaObject()->className();
          if (cname == "QWidgetTextControl")
            pObj->setProperty("openExternalLinks", true);
        }
        

        这不会解决鼠标光标问题,因此您仍需要覆盖 mouseMoveEvent

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-07
          • 2016-04-20
          • 2020-12-04
          • 2010-10-26
          • 2014-01-21
          相关资源
          最近更新 更多