Qt 要使QClipboard::setText()在X11下工作,所需的最小调整量是多少?

Qt 要使QClipboard::setText()在X11下工作,所需的最小调整量是多少?,qt,x11,Qt,X11,在推荐之后,我发现它不适合复制。 我开始调试它,首先从QT3转换到QT4,看看是否 帮助了我,但没什么区别,最终我发现了 是,但标记为“不会修复”: 这是创建后立即设置剪贴板的副作用 QApplication。X11剪贴板是事件驱动的,因此依赖于 来自X服务器的当前时间戳。这些时间戳是自动生成的 由QApplication处理。但是,在这个简单的示例中,事件循环 未运行,因此我们不会从X服务器获取更新的时间戳, 这反过来会导致QClipboard::ownsClipboard()返回false。

在推荐之后,我发现它不适合复制。 我开始调试它,首先从QT3转换到QT4,看看是否 帮助了我,但没什么区别,最终我发现了 是,但标记为“不会修复”:

这是创建后立即设置剪贴板的副作用 QApplication。X11剪贴板是事件驱动的,因此依赖于 来自X服务器的当前时间戳。这些时间戳是自动生成的 由QApplication处理。但是,在这个简单的示例中,事件循环 未运行,因此我们不会从X服务器获取更新的时间戳, 这反过来会导致QClipboard::ownsClipboard()返回false。背景 响应键盘或鼠标事件的剪贴板会使 按预期工作

使用QClipboard::setText()的理想最低代码应该是 像下面这样

#include <qapplication.h>
#include <qclipboard.h>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QClipboard *cb = QApplication::clipboard();
    QString input = "Hello clipboard";
    cb->setText(input);

    return 0;
    //return app.exec(); makes no difference from return 0
}
#包括
#包括
int main(int argc,char*argv[])
{
QApplication应用程序(argc、argv);
QClipboard*cb=QApplication::clipboard();
QString input=“Hello剪贴板”;
cb->setText(输入);
返回0;
//return app.exec();与return 0没有区别
}
不过,正如我所说,这是行不通的。经过反复试验,我终于成功了 提出以下几点会奏效

#include <qapplication.h>
#include <qclipboard.h>
#include <QTimer>
#include <QtGui>
#include <iostream>

class MyApplication : public QApplication {
    Q_OBJECT
public:
    MyApplication(int & argc, char ** argv) : QApplication(argc, argv)
    {
    }
public slots:
    void setClipboard()
    {
        QClipboard *cb = QApplication::clipboard();
        QString input = "THIS WORKS";
        std::cout << "setText line " << __LINE__+1 << "\n";
        cb->setText(input);
    }
};

class MainWidget:public QMainWindow {
public:
    MainWidget() {
        QClipboard *clipboard = QApplication::clipboard();
        std::cout << "setText line " << __LINE__+1 << "\n";
        clipboard->setText("This will not be copied to the clipboard, apparently also too early");
    }
};


int main(int argc, char *argv[])
{
    MyApplication app(argc, argv);

    QClipboard *cb = QApplication::clipboard();
    QString input = "This will not be copied to the clipboard, too early";
    std::cout << "setText line " << __LINE__+1 << "\n";
    cb->setText(input);

    //QTimer::singleShot(3, &app, SLOT(setClipboard())); // 3 ok, 2 not ok

    MainWidget mainWid;
    //mainWid.show();

    QTimer::singleShot(2, &app, SLOT(setClipboard())); // 2 ok, 1 not ok

    return app.exec();
}
#include "main.moc"
#包括
#包括
#包括
#包括
#包括
类MyApplication:公共QApplication{
Q_对象
公众:
MyApplication(int&argc,char**argv):QApplication(argc,argv)
{
}
公众时段:
void setClipboard()
{
QClipboard*cb=QApplication::clipboard();
QString input=“这是有效的”;

std::cout我想尝试一下:

QApplication app(argc, argv);
// Paste something to your clipboard
app.processEvents();

这实际上使Qt应用程序的事件循环处理所有挂起的事件,如果不调用app.exec()则不会发生这种情况与第一个示例一样,与第二个示例非常相似,实际上是用计时器做了一些等效的事情。虽然我没有尝试过,但这也是文档建议的(将剪贴板作为对用户输入事件的响应处理).

我相信您在X11上运气不好。应由应用程序本身来管理X11剪贴板。因此,当您的应用程序关闭剪贴板上的数据时,数据将丢失


我认为最好的办法是调用命令行
xclip
命令。将剪贴板上需要的文本导入其中。我不确定该命令通常有多大可用性。而且它必须执行一些可以用较低级别的x代码重新创建的操作?

不幸的是,这没有帮助,因为app.processEvents()仅触发QT的事件处理,该事件处理依赖于未触发的某些X11活动。我最初使用“return app.exec()”而不是“return 0”在这个简单的例子中。为了让剪贴板工作,X11的which event循环必须被触发吗?在Qt端想不出任何东西。是的,这可能更像是一个X11而不是Qt问题。MainWidget的实例化显然已经足够了,但我想避免创建比需要更重的虚拟对象,当然也可以避免d如果可能,创建虚拟对象。