全部,
如果我有一个带有一堆文本的 QTextEdit,并且想要在该文本中的某个位置插入一个超链接,我是否可以免费处理该超链接,或者我将不得不编写一些额外的代码来处理超链接悬停/单击?
蒂亚!
[编辑]
我的意思是问 - 输入 www.google.com 并按
Space Bar
或 Enter
键后 QTextEdit 是否可以识别超链接,以便正确呈现。
我不希望我的用户输入 < a href=....
。
谢谢您,对于造成的混乱深表歉意。
[/编辑]
迟到的答复总比没有答复好。我已经解决了这个问题,以回答用户@caramel的另一个问题,不幸的是,在我完成之前,他已经删除了它......我想我最好不要让它浪费掉。
在
QTextEdit
中显示链接很简单:使用 QTextBrowser 子类。这是有关该主题的许多问题中给出的答案;然而,所有这些问题都仅限于使链接在小部件中正确运行,并且没有一个真正解决用户可以键入 URL 的情况。
有许多细节需要解决,所有这些都使得练习变得非常重要:
这个答案中呈现的模式是我选择在这里使用的模式。 它需要一些小的修复才能在 C++ 中工作(所有
\
必须为编译器转换为 \\
)并在编辑期间工作(该模式必须被元素包围以保证它不会与粘在没有空格来分隔它们的单词。
(\\(|\\b)https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)(\\)|\\b)
QTextBrowser
方法,
setOpenExternalLinks
仍然是首选类别。如果没有这个,您最好的办法就是复制 URL 粘贴到浏览器中,而不是直接单击生成的链接。QTextBrowser
默认情况下是只读的,我们需要解决这个问题。
为了避免读取控件包含的整个文本,我们使用
QTextCursor
来确定当前正在编辑的文本部分。linkAddress
替换正在键入的 [linkAddress](linkAddress)
文本),所以我们需要在方法末尾恢复光标位置。
这是一个完整的解决方案,所有逻辑都在连接到
QTextEdit::textChanged
的 lambda 中设置。
#include <QtWidgets/QApplication>
#include <QtCore/QRegularExpression>
#include <QtWidgets/QTextBrowser>
#include <QtGui/QTextDocumentFragment>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextBrowser* te = new QTextBrowser();
te->setReadOnly(false);
te->setOpenExternalLinks(true);
te->setTextInteractionFlags(Qt::TextEditorInteraction | Qt::TextBrowserInteraction);
//MySyntaxHighlighter* highlighter = new MySyntaxHighlighter(te);
QRegularExpression re(
"(\\(|\\b)https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)(\\)|\\b)",
QRegularExpression::PatternOption::CaseInsensitiveOption | QRegularExpression::PatternOption::DontCaptureOption | QRegularExpression::PatternOption::InvertedGreedinessOption
);
QObject::connect(te, &QTextEdit::textChanged, [te, re]() {
auto cursor = te->textCursor();
int cachedPosition = cursor.position();
auto testSeparator = [](char16_t character) -> bool {
return character == ' ' || character == '\r' || character == '\n' || character == '\t' ||
character == 8233 /*\u2029: paragraph separator*/
;
};
//Browse the text around where the edition is taking place
char16_t character = '\0';
if (!cursor.atStart()) {
do {
if (!cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor))
break;
character = cursor.selectedText()[0].unicode();
} while (!testSeparator(character));
cursor.clearSelection();
if (testSeparator(character))
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor);
}
do {
if (!cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor))
break;
character = cursor.selectedText().right(1)[0].unicode();
} while (!testSeparator(character));
//Change the text to create/remove a link if necessary
if (auto textToAnalyze = cursor.selectedText(); re.match(textToAnalyze).hasMatch()) { //Add link if a URL is detected
te->blockSignals(true);
cursor.beginEditBlock();
cursor.removeSelectedText();
cursor.insertMarkdown(QStringLiteral("[%1](%1)").arg(textToAnalyze));
cursor.endEditBlock();
te->blockSignals(false);
}
else if (auto textMarkDown = cursor.selection().toMarkdown(); re.match(textMarkDown).hasMatch()) { //Remove link if a URL is being removed (Del / backspace key)
te->blockSignals(true);
cursor.beginEditBlock();
cursor.removeSelectedText();
if (!textToAnalyze.isEmpty())
cursor.insertMarkdown(textToAnalyze);
cursor.endEditBlock();
te->blockSignals(false);
}
else
return;
cursor.setPosition(cachedPosition);
te->setTextCursor(cursor);
});
te->show();
return a.exec();
}