如何在退出PyQt应用时禁用剪贴板清空?
我有一个简单的PyQt4应用程序(下面有代码),它出现了一个问题:如果我从一个QLineEdit
中选择文本并复制到剪贴板,那么只有在我的应用程序运行时,我才能把它粘贴到其他应用程序中。看起来在退出时,PyQt应用程序会清空剪贴板,所以在关闭应用程序后,我无法粘贴文本。
我该怎么做才能避免这个问题呢?
使用的是PyQt 4.4.3,Python 2.5,操作系统是Windows XP。这个问题在PyQt 4.5以上版本和Linux上也得到了证实。
import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
edit = QtGui.QLineEdit()
edit.setText('foo bar')
edit.show()
app.exec_()
2 个回答
我在使用GNU/Linux时遇到了类似的问题,偶然发现了这个问题的答案,参考了bialix提到的网站(虽然地址变了,但通过搜索还是能找到)。最相关的部分是:
记住,在Linux系统中,除非你有像klipper这样的工具,否则当设置剪贴板的应用程序退出时,剪贴板会变空。
所以这是一个GNU/Linux系统的特性。这里有来自ubuntu wiki的更详细解释:
为什么会这样呢?
这个问题的发生是因为Xorg在复制时采取了一种保守的方式。当用户选择或复制内容时,它只复制了原始数据的一个引用。直到用户请求粘贴时,它才会去获取源程序中的实际数据。这样做可以节省很多不必要的数据传输,但代价是无法从一个已经关闭且没有将剪贴板内容保存到其他地方的程序中恢复数据。
你可以通过安装像parcellite、klipper、glipper或clipman这样的剪贴板管理工具来解决这个问题。
好的,关于剪贴板的事情其实并不是特别清楚。QT并不是直接把文本放到剪贴板里,而是存储了一种指向文本的指针。Gordon Tyler给我指了一个链接,里面有关于这个问题的讨论,解释得很清楚。下面我引用了一些代码和相关的解释。
在应用程序退出时运行这段代码(比如在关闭事件处理函数中):
from PyQt4 import QtGui, QtCore
clipboard = QtGui.QApplication.clipboard()
event = QtCore.QEvent(QtCore.QEvent.Clipboard)
QtGui.QApplication.sendEvent(clipboard, event)
这个基本概念是,默认情况下,把东西复制到剪贴板时,其实只是复制了一个指向源应用程序的引用或指针。然后当另一个应用程序想要从剪贴板粘贴数据时,它会向源应用程序请求数据。调用OleFlushClipboard会让Windows把真实的数据复制到剪贴板,而不是仅仅复制那个引用。虽然这样在复制图片时会有一些延迟,但对于字符串来说,影响并不明显。
上面的代码在多个平台上都能很好地运行,对Linux平台也没有什么不好的影响。