在 Qt 中,如何将 QString 注册到我的系统剪贴板,包括引用和非引用?

In Qt, how can I register a QString to my System's clipboard, both quoted and non-quoted?

如果我想在剪贴板中使用带引号的字符串:

qDebug() << QString("Boat\nProgramming");

然后我复制输出:

"Boat\nProgramming"

如果我想在剪贴板中使用非引号字符串:

qDebug().noquote() << QString("Boat\nProgramming");

然后我复制输出:

Boat
Programming

在 Qt 中将带引号和不带引号的字符串注册到我的 [Ubuntu] 系统剪贴板的正确方法是什么?


背景故事/用例:

我构建了一个命令行应用程序,它为我呈现字符串,我偶尔需要将这些字符串转储到网站的字符串解释器(如果需要的话,文本到语音)以进行调试。将其转储到剪贴板而不是手动突出显示文本、复制和粘贴,确实改进了我的工作流程。

"Quoted string" 非常模棱两可。例如,在 shell 中,美元符号是特殊的(并且通常应该像其他一些字符一样进行转义)。但是在 HTML 中,<>&'" 是特殊的(通常应该转义)。在 SQL 语句中,您应该只转义双引号和 nul 字符。在 C 中,您将转义控制字符和引号、双引号和反斜杠等...在 JSON 中规则略有不同。

所以首先编写适当的引用转换代码。也许你想实现以下功能

QString quoted_for_shell(const QString&);
QString quoted_for_html(const QString&);
QString quoted_for_c(const QString&);

等等。

(也许您还应该编写反向反引号转换代码;顺便说一句,引用可能很棘手:您如何用俄语、西里尔字母引用我的全名:Василий Дмитриевич Старынкевич 在 C 语言中,因为并非所有C 实现使用 UTF-8,即使 they should)

一旦你实施了报价机制(这可能比你想象的更难、更不明确!),你 "just" 想要将 QString 复制到剪贴板。然后阅读 QClipboard and perhaps the chapter on drag and drop.

的文档

顺便说一句,当心 code injection(这部分是为什么引用非常重要)。想想一些恶意的 rm -rf $HOME 字符串等等......

其实剪贴板处理是一件很微妙的事情X11. See ICCCM & EWMH. You very probably need some event loop running (notably for very long strings of many millions bytes, the selection processing has then to be incremental with several handshakes, and details could be tricky, but are handled by Qt). So you might need QApplication::exec

这是我实现的一个非常准系统的解决方案:

// #include <QCoreApplication>
// I had to swap to QGuiApplication to get the clipboard functionality.
#include <QGuiApplication>
#include <QClipboard>
#include "whatever.h"

int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);
    a.clipboard()->setText(QString("Boat\nProgramming")); // Quoted
    a.clipboard()->setText(QString("Boat\nProgramming")   // Non-Quoted
                           .replace("\n","\n")
                           .replace("\t","\t"));

    return 0;
}

根据 Basile Starynkevitch 的建议;这些不是严格保护的功能,而是针对小字符串的准系统解决方案。在我的例子中是临时的,纯粹用于调试目的。请务必阅读他的 post,因为他提供了避免代码注入和其他安全风险的最佳实践。