为什么我从剪贴板粘贴到外部程序时,Qt程序会处理剪贴板数据?

4
我会做以下事情:

1)在Windows上,在我的Qt程序中将数据复制到剪贴板。

QApplication::clipboard()->setText(data);

2) 将数据粘贴到外部程序(notepad.exe)中。然后我的程序开始处理剪贴板数据。它调用Windows特定的方法:

QWindowsOleDataObject::GetData(...);
... QWindowsMimeText::convertFromMime(...);

这是一个问题,因为当剪贴板中的数据量很大时,我的程序在这些方法中分配内存会失败。

我无法理解它,因为调用栈非常奇怪:

qwindowsd.dll!QWindowsMimeText::convertFromMime(const tagFORMATETC & formatetc, const QMimeData * mimeData, tagSTGMEDIUM * pmedium) Line 606    C++
qwindowsd.dll!QWindowsOleDataObject::GetData(tagFORMATETC * pformatetc, tagSTGMEDIUM * pmedium) Line 144    C++
[External Code] 
Qt5Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 740    C++
qwindowsd.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 73   C++
Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 129   C++
Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 204    C++
Qt5Cored.dll!QCoreApplication::exec() Line 1188 C++
Qt5Guid.dll!QGuiApplication::exec() Line 1508   C++
Qt5Widgetsd.dll!QApplication::exec() Line 2957  C++
main(int argc, char * * argv) Line 759  C++

这是一些Qt内部工作,我不知道如何对其产生影响。

1个回答

2
Qt 可能会优化“内部”剪贴板使用。因此,QApplication::clipboard()->setText(data); 实际上并没有将 data 复制到 Windows 剪贴板 - 您可能想要在同一 Qt 应用程序中粘贴它,因此不需要将其复制到 Windows 剪贴板再返回。只有在使用外部应用程序时,才会进行真正的复制。
Qt 可能会将 OLE 数据提供程序注册为“剪贴板数据源”,当需要在外部应用程序中使用剪贴板数据时,Windows 就会使用它。
因此,从一开始就将大数据存储在 data 中。
来源:Qt Windows 剪贴板实现 QWindowsClipboard 使用:OleSetClipboard,它接受数据源指针而不是数据本身。

谢谢!听起来逻辑上很好。这是你的假设还是像你描述的那样工作?如果您有文档链接,能否分享一下? - Deutsche
@Deutsche 这是基于它之前的工作方式所做的假设,看代码似乎仍然适用(链接在编辑后的回复中)。 - Hcorg
太好了!感谢您的回答,解释了问题。如果您在这个主题上非常有经验,也许您知道如何捕获这种情况(在事件处理中出现的bad_alloc),并正确地继续软件的工作? - Deutsche
在我看来:如果bad_alloc在Qt内部抛出,那么应用程序无法恢复的可能性非常大 - Qt本身使用了很多分配,并且使用bad_alloc你不知道出了什么问题以及后果会是什么。也许尝试编写自己的QMimeData并重新实现http://doc.qt.io/qt-5/qmimedata.html#retrieveData以更好地控制内存分配。另外:请检查http://doc.qt.io/qt-5/qwinmime.html,我不知道它确切能做什么,但它是特定于Windows的,因此可能提供更多的控制。 - Hcorg

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