QMimeData :: data函数调用花费太长时间才能完成

问题描述

我正在尝试在运行Wayland的Linux上检索存储在剪贴板中的内容,作为一项更复杂的任务的一部分,在反复试验之后,我设法发现对data()函数调用需要花费几秒钟的时间,在x11上,它会立即返回。

这对我来说是个大难题,因为我必须遍历许多可能的mime类型。为了轻松重现此问题,我添加了以下代码

#include "mainwindow.h"

#include <QApplication>
#include <QClipboard>
#include <QByteArray>
#include <QMimeData>
#include <QThread>
#include <QDebug>

class ClipMon : public QThread {

public:
    void run() override {
        QClipboard *board = QApplication::clipboard();
        while (true) {
            const QMimeData *dt = board->mimeData();
            QByteArray bt = dt->data("text/plain");
            qDebug() << bt.data() << "\n";
        }
    }
private:
};

int main(int argc,char *argv[])
{
    QApplication a(argc,argv);
    MainWindow w;
    w.show();
    ClipMon thr;
    thr.start();

    return a.exec();
}

我在qDebug()行之前设置了一个断点,程序在几秒钟后恢复了执行。它有时会立即运行,但是将其他内容复制到剪贴板会使它再次花费一段时间。

我在Wayland上使用Ubuntu 20.04,并且尝试同时使用Qt 5.12和Qt 5.6。 您有什么可能的原因吗?谢谢。

LE:我发现调用data(mimeType)函数且mimeType为“ COMPOUND_TEXT”才是罪魁祸首。此调用以及所有后续的其他mimeTypes调用将花费很长时间。如果有人有解释,我将不胜感激。

解决方法

我可以怀疑线程背后的想法,所以这是我的建议:

剪贴板位于qobject中,因此您可以注册应用以发出信号,例如当剪贴板中的内容更改时,您可以摆脱线程并提高应用程序的性能

这里是一个如何使用lambda的示例,但是您可以继续使用SIGNAL,SLOTS

connect(QApplication::clipboard(),&QClipboard::dataChanged,[]()
{
    qDebug() << "new data!";
    QClipboard* board = QApplication::clipboard();
    const QMimeData* dt = board->mimeData();
    QByteArray bt = dt->data("text/plain");
    qDebug() << bt.data() << "\n";
});