QClipboard无法获取从记事本/Chrome复制的剪贴板数据

7
在我的程序中,用户可以从任何地方复制一段文本,并将其粘贴到我的程序中。我使用简单的QApplication::clipboard()->text();函数,一切都按预期工作。然而,我的一些用户在尝试在Windows 8.1上复制和粘贴时遇到了问题。
以下是我如何从我的粘贴函数中访问剪贴板文本的方法:
QString clipboard = QApplication::clipboard()->text();

//check if the clipboard is empty
if(QApplication::clipboard()->text().isEmpty())
    return;

//do something with clipboard

但是如果文本是从记事本或Chrome中复制的,那么文本始终为空。Windows 7用户没有遇到任何问题。并不是所有的Windows 8用户都有这个问题,只有少数用户存在此问题。当从其他一些随机位置或程序内部进行复制时,剪贴板可以正常工作。
我尝试使用mimeData。在使用函数formats()时,只有纯文本格式可用,但文本始终为空。
从记事本/Chrome复制的文本在剪贴板查看器和其他程序中可以正常显示,并且可以粘贴到其他程序中。
复制和粘贴是我的程序中非常重要的功能,很让人沮丧的是我的用户无法从记事本或Chrome中复制和粘贴。
有什么想法吗?谢谢您的时间。 :)
编辑:我尝试了“windows”样式技术。但没有改变。这是我的当前代码,仍然不能工作:
QString clipboard = QApplication::clipboard()->text();

//check if the clipboard is empty
if(clipboard.isEmpty())
{
    //might not actually be empty. Check using the other technique
    if (IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL))
        {
            HGLOBAL hGlobal = GetClipboardData(CF_TEXT) ;//hGlobal is NULL
            if (hGlobal != NULL)//This never gets called because it is NULL
            {
                LPTSTR lpszData = (LPTSTR) GlobalLock(hGlobal) ;
                if (lpszData != NULL)
                {
                    clipboard.fromLocal8Bit((const char *)lpszData);
                    GlobalUnlock(hGlobal) ;
                }
            }
            CloseClipboard() ;
        }

    if(clipboard.isEmpty())
        return;
}

复制的文本在剪贴板查看器中显示正常,但无论如何我的程序都无法获取它: enter image description here 为什么GetClipboardData()没有捕获任何内容?再次说明,我尝试过的任何其他程序都可以粘贴复制的文本...只有我的程序不行。但如果从其他地方复制,它就可以正常工作。

首先排除 Windows 8.1 限制访问剪贴板的可能性。将有问题的源复制到另一个程序中。 - UmNyobe
从记事本/Chrome复制的文本在剪贴板查看器和其他程序中都可以正常显示,并且可以在其他程序中粘贴。 - mrg95
1
抱歉,我没有读到那行。 :| - UmNyobe
你尝试过先分配你的hglobal变量吗?像这样:HGLOBAL hGlob = GlobalAlloc(GMEM_FIXED, 64); https://msdn.microsoft.com/zh-cn/library/80db3kax.aspx - gibertoni
只是为了确认,您是否尝试在这些计算机上禁用任何防病毒或反恶意软件工具?也许有些东西正在阻止您的应用程序访问剪贴板。 - Diego Garcia
显示剩余2条评论
2个回答

1

编辑:使用这个版本时,当用户复制文本并将其放到剪贴板中时,一个函数会将文本复制到内部文本文件中,而不是直接复制到您的程序中,使用QFile。另一个函数从内部文本文件中将文本复制到您的程序中。通过这种方式,我认为您的程序不必直接处理剪贴板中的文本。

clipboard.h

#ifndef CLIPBOARD_H
#define CLIPBOARD_H

#include <QDialog>
#include <QClipboard>
#include <QLabel>
#include <QHBoxLayout>
#include <QTextEdit>
#include <QPushButton>
#include <QFile>
#include <QTextStream>

class ClipBoard : public QDialog {
    Q_OBJECT

public:
    explicit ClipBoard(QWidget *parent = 0);
    ~ClipBoard();

private slots:
    //the functions that will copy and paste text from the text file
    void copyToTextFile();
    void paste();

private:

    QPushButton *button;
    QTextEdit *edit;
    QString textFromClipBoard;
    QClipboard *clipBoardText;

    QString clipboard;

};

#endif // CLIPBOARD_H

clipboard.cpp

#include "clipboard.h"
#include "ui_clipboard.h"

ClipBoard::ClipBoard(QWidget *parent) : QDialog(parent) {

    button = new QPushButton("&Paste Copied Text");

    edit = new QTextEdit;

    /*when user copies text and text gets to clipboard, the text is copied 
      from clipboard to a text file then copied from the text file to the   
      program*/
    connect(button, SIGNAL(clicked()), this, SLOT(copyToNotepad()));
    connect(button, SIGNAL(clicked()), this, SLOT(paste()));


    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(button);
    layout->addWidget(edit);


    setLayout(layout);

}

/*This function copies text from the clipboard to an internal text file 
  created by the program*/
void ClipBoard::copyToTextFile() {
    clipboard = QApplication::clipboard()->text();

    QFile output("out.txt");
    if (output.open(QIODevice::ReadWrite | QFile::Truncate |   
    QIODevice::Text)) {
        QTextStream out(&output);
        out << clipboard;
    }
}

/*This function then copies the text from the internal text file and pastes 
  it to the text edit. So the program doesn't have to deal directly with the 
  clipboard*/
void ClipBoard::paste() {

    QFile input("out.txt");
    if (input.exists()) {
        if (input.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QTextStream in(&input);
            clipboard = in.readAll();
        }
    }

    edit->setText(clipboard);
}

ClipBoard::~ClipBoard() {

}

main.cpp

#include "clipboard.h"
#include <QApplication>

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

    ClipBoard w;
    w.show();

    return a.exec();
}

请查看并与您的代码部分进行比较,以确定是否有任何错误。但是,关于您声称在某些Windows 8.1系统上运行正常而在其他系统上不正常的情况,让我感到困惑。

谢谢。是的,我使用相同的系统,并且已经多次进行了变化。这在大多数机器上都可以工作,但我的一些用户(他们已经为我的程序付费)无法从某些程序或来源中复制和粘贴。有没有不使用qt库函数的方法?像默认的Windows方式之类的东西?也许那样会起作用。 - mrg95
在你的代码中包含 <windows.h> 头文件并使用 winAPI 方法获取剪贴板数据。查看 http://www.codeexperts.com/showthread.php?594-How-to-get-text-data-from-clipboard-using-WIN32 - Richardson Ansong
我刚刚尝试了你建议的方法。没有改变。仍然无法从记事本中粘贴,但可以从其他程序中粘贴。请查看我的编辑以了解我所做的。 - mrg95
你的编辑在我的端上运行良好。可能问题并非来自于你的程序,而是他们的端。我认为你需要从这些用户那里获取更多信息,例如:“他们能够从记事本中复制文本并粘贴到其他程序中吗?” - Richardson Ansong
好的,对此我很抱歉。但我仍然认为问题可能不是来自于你的程序。你的代码是否会对复制的文本进行某些操作,例如在粘贴之前检查是否满足某些条件? - Richardson Ansong
显示剩余9条评论

0

我曾经遇到过类似的问题,对我来说解决方案是睡觉。

void MainWindow::on_clipboard_change(){

    QThread::msleep(1); //without this line I get allways empty clipboard

    QString text = QGuiApplication::clipboard()->text();

    qDebug() << "clipboard change event triggered ( " << text << " )";

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接