剪贴板QClipboard
无论是拖曳还是剪贴板都需要将 QMimeData作为数据传输中介,因此需要先学习QMimeData
和QDrag 一样,QClipboard 也继承自 QtCore。
QClipboard 提供了对系统剪贴板的访问,可以在应用程序之间复制和粘贴数据。QClipboard 的使用方法和QDrag 的使用方法类似,同样使用QMimeData传输数据。
剪贴板常用的调用方法如下:
from PySide6.QtGui import QClipboard
clipboard = QApplication.clipboard()
这是QApplication 的静态方法,返回 QClipboard。
剪贴板QClipboard说明
剪贴板提供了一种在应用程序之间复制和粘贴数据的简单机制。
QClipboard支持与QDrag相同的数据类型,并使用类似的机制。有关高级剪贴板用法,请阅读拖放。
应用程序中只有一个QClipboard对象,可作为QGuiApplication::clipboard()访问。
例子:
clipboard = QGuiApplication.clipboard()
originalText = clipboard.text()
# etc.
clipboard.setText(newText)
QClipboard具有一些访问常见数据类型的便利功能:setText()允许交换Unicode文本,setPixmap()和setImage()允许在应用程序之间交换QPixmap和QImages。setMimeData()函数是灵活性的极致:它允许您将任何QMimeData添加到剪贴板中。每一个都有相应的getter,例如text()、image()和pixmap()。您可以通过调用clear()来清除剪贴板。
使用这些功能的典型示例如下:
def paste(self):
clipboard = QApplication.clipboard()
mimeData = clipboard.mimeData()
if mimeData.hasImage():
setPixmap(QPixmap(mimeData.imageData()))
elif mimeData.hasHtml():
setText(mimeData.html())
setTextFormat(Qt.RichText)
elif mimeData.hasText():
setText(mimeData.text())
setTextFormat(Qt.PlainText)
else:
setText(tr("Cannot display data"))
X11用户注意事项
- X11窗口系统有一个单独的选择和剪贴板的概念。当文本被选中时,它可以立即作为全局鼠标选择。全局鼠标选择稍后可能会复制到剪贴板。按照惯例,鼠标中键用于粘贴全局鼠标选择。
- X11也有所有权的概念;如果您在窗口中更改选择,X11将只通知所有者和上一个所有者更改,即不会通知所有应用程序选择或剪贴板数据已更改。
- 最后,X11剪贴板是事件驱动的,即如果事件循环没有运行,剪贴板将无法正常工作。同样,建议存储或检索剪贴板的内容,以直接响应用户输入事件,例如鼠标按钮或按键按下和释放。不应存储或检索剪贴板内容以响应计时器或非用户输入事件。
- 由于X11上没有在应用程序之间复制和粘贴文件的标准方法,因此目前正在使用各种MIME类型和约定。例如,Nautilus希望为文件提供x特殊/gnome复制的文件MIME类型,数据以剪切/复制操作、换行符和文件的URL开头。
macOS用户注意事项
- macOS支持一个单独的查找缓冲区,用于保存查找操作中的当前搜索字符串。可以通过指定FindBuffer模式来访问此查找剪贴板。
Windows和macOS用户注意事项
- Windows和macOS不支持全局鼠标选择;它们只支持全局剪贴板,即只在进行显式复制或剪切时将文本添加到剪贴板。
- Windows和macOS没有所有权的概念;剪贴板是一个完全全局的资源,因此所有应用程序都会收到更改通知。
Android用户注意事项
- 在Android上,只支持以下mime类型:text/plain、text/html和text/uri list。
剪贴板QClipboard方法
-
PySide6.QtGui.QClipboard.Mode
此枚举类型用于控制mimeData()、setMimeData()和相关函数使用系统剪贴板的哪一部分。
Constant Description QClipboard.Clipboard 指示应该从全局剪贴板中存储和检索数据。 QClipboard.Selection 指示应该从全局鼠标选择中存储和检索数据。仅在具有全局鼠标选择的系统(例如X11)上提供对选择的支持。 QClipboard.FindBuffer 指示应存储数据并从"查找"缓冲区中检索数据。此模式用于保存macOS上的搜索字符串。
QClipboard 类中常用的函数如表所示。
函 数 | 描 述 |
---|---|
clear([mode:PySide6.QtGui.QClipboard.Mode=QClipboard.Mode.Clipboard]) | 清除剪贴板内容。 模式参数用于控制使用系统剪贴板的哪一部分。如果模式为剪贴板,此函数将清除全局剪贴板内容。如果模式为"选择",此功能将清除全局鼠标选择内容。如果模式为FindBuffer,此函数将清除搜索字符串缓冲区。 |
setMimeData(data:PySide6.QtCore.QMimeData[,mode:PySide6.QtGui.QClipboard.Mode=QClipboard.Mode.Clipboard]) | 将剪贴板数据设置为src。数据的所有权将转移到剪贴板。如果要删除数据,请使用新数据再次调用clear()或setMimeData()。 模式参数用于控制使用系统剪贴板的哪一部分。如果模式为剪贴板,则数据存储在全局剪贴板中。如果模式为"选择",则数据将存储在全局鼠标选择中。如果模式为FindBuffer,则数据存储在搜索字符串缓冲区中。 setText()、setImage()和setPixmap()函数是更简单的包装器,分别用于设置文本、图像和像素图数据。 |
mimeData([mode:PySide6.QtGui.QClipboard.Mode=QClipboard.Mode.Clipboard])->PySide6.QtCore.QMimeData | 返回指向当前剪贴板数据的QMimeData表示形式的指针(如果平台不支持给定模式,则可以为None)。 模式参数用于控制使用系统剪贴板的哪一部分。如果模式为剪贴板,则从全局剪贴板中检索数据。如果模式为"选择",则从全局鼠标选择中检索数据。如果模式为FindBuffer,则从搜索字符串缓冲区中检索数据。 text()、image()和pixmap()函数是用于检索文本、图像和像素图数据的更简单的包装器。 |
setImage(arg__1:PySide6.QtGui.QImage[,mode:PySide6.QtGui.QClipboard.Mode=QClipboard.Mode.Clipboard]) | 将图像复制到剪贴板中。 模式参数用于控制使用系统剪贴板的哪一部分。如果模式为剪贴板,则图像将存储在全局剪贴板中。如果模式为"选择",则数据将存储在全局鼠标选择中。 这是以下内容的简写: data = QMimeData() data.setImageData(image) clipboard.setMimeData(data,mode) |
image([mode:PySide6.QtGui.QClipboard.Mode=QClipboard.Mode.Clipboard])->PySide6.QtGui.QImage | 返回剪贴板图像,如果剪贴板不包含图像或包含不受支持的图像格式的图像,则返回空图像。 模式参数用于控制使用系统剪贴板的哪一部分。如果模式为剪贴板,则从全局剪贴板中检索图像。如果模式为"选择",则从全局鼠标选择中检索图像。 |
setPixmap(arg__1:PySide6.QtGui.QPixmap[,mode:PySide6.QtGui.QClipboard.Mode=QClipboard.Mode.Clipboard]) | 将像素图复制到剪贴板中。请注意,这比setImage()慢,因为它需要首先将QPixmap转换为QImage。 模式参数用于控制使用系统剪贴板的哪一部分。如果模式为剪贴板,则像素图将存储在全局剪贴板中。如果模式为"选择",则像素图将存储在全局鼠标选择中。 |
pixmap([mode:PySide6.QtGui.QClipboard.Mode=QClipboard.Mode.Clipboard])->PySide6.QtGui.QPixmap | 返回剪贴板的像素图,如果剪贴板不包含像素图,则返回null。请注意,这可能会丢失信息。例如,如果图像是24位并且显示是8位,则结果被转换为8位,并且如果图像具有阿尔法通道,则结果仅具有掩码。 模式参数用于控制使用系统剪贴板的哪一部分。如果模式为剪贴板,则从全局剪贴板中检索像素图。如果模式为"选择",则从全局鼠标选择中检索像素图。 |
setText(arg__1:str[,mode:PySide6.QtGui.QClipboard.Mode=QClipboard.Mode.Clipboard]) | 将文本作为纯文本复制到剪贴板中。 模式参数用于控制使用系统剪贴板的哪一部分。如果模式为剪贴板,则文本将存储在全局剪贴板中。如果模式为"选择",则文本将存储在全局鼠标选择中。如果模式为FindBuffer,则文本将存储在搜索字符串缓冲区中。 |
text([mode:PySide6.QtGui.QClipboard.Mode=QClipboard.Mode.Clipboard])->str | 以纯文本形式返回剪贴板文本,如果剪贴板不包含任何文本,则返回空字符串。 模式参数用于控制使用系统剪贴板的哪一部分。如果模式为剪贴板,则从全局剪贴板中检索文本。如果模式为"选择",则从全局鼠标选择中检索文本。如果模式为FindBuffer,则从搜索字符串缓冲区中检索文本。 |
ownsClipboard()->bool | 如果此剪贴板对象拥有剪贴板数据,则返回true;否则返回false。 |
ownsFindBuffer()->bool | 如果此剪贴板对象拥有查找缓冲区数据,则返回true;否则返回false。 |
ownsSelection()->bool | 如果此剪贴板对象拥有鼠标选择数据,则返回true;否则返回false。 |
supportsFindBuffer()->bool | 如果剪贴板支持单独的搜索缓冲区,则返回true;否则返回false。 |
supportsSelection()->bool | 如果剪贴板支持鼠标选择,则返回true;否则返回false。 |
剪贴板QClipboard信号
信号 | 描述 |
---|---|
changed(mode:PySide6.QtGui.QClipboard.Mode) | 当给定剪贴板模式的数据发生更改时,会发出此信号。 |
dataChanged() | 当剪贴板数据发生更改时,会发出此信号。 在macOS和Qt 4.3或更高版本上,只有当应用程序激活时,才会检测到其他应用程序所做的剪贴板更改。 |
findBufferChanged() | 当查找缓冲区发生变化时,会发出此信号。这仅适用于macOS。 对于Qt 4.3版或更高版本,只有当应用程序激活时,才会检测到其他应用程序所做的剪贴板更改。 |
selectionChanged() | 当选择发生变化时,会发出此信号。这只适用于支持选择的窗口系统,例如X11。Windows和macOS不支持选择。 |
QClipboard 类案例
这个案例主要使用QMimeData传递数据,基础方法请参考前面章节,这里不再赘述。
可以使用最上方的 3 个按钮复制一些特定对象,也可以手动复制其他数据。
paste()函数会根据剪贴板中的数据类型来选择呈现方式,当剪贴板中的内容发生变化时触发updateClipboard()函数,用来显示当前剪贴板的 format 格式。
# -*- coding: UTF-8 -*-
# File date: Hi_2023/3/11 17:39
# File_name: 07-剪贴板QClipboard.py
import os
import sys
from PySide6.QtCore import QMimeData
from PySide6.QtWidgets import(QApplication,QWidget,QDialog,QGridLayout,QLabel,QPushButton,QTextEdit)
from PySide6.QtGui import QPixmap,QClipboard
from PySide6.QtGui import Qt
import os
os.chdir(os.path.dirname(__file__))
class Demo(QWidget):
def __init__(self,parent=None):
super(Demo,self).__init__(parent)
textCopyButton = QPushButton("&Copy Text")
PasteButton = QPushButton("&Paste")
htmlCopyButton = QPushButton("C&opy HTML")
imageCopyButton = QPushButton("Co&py Image")
self.textLabel = QLabel("Paste text")
self.typeLabel = QLabel('type label')
self.formatLabel = QLabel('format label: for valuechange')
layout = QGridLayout()
layout.addWidget(textCopyButton,0,0)
layout.addWidget(imageCopyButton,0,1)
layout.addWidget(htmlCopyButton,0,2)
layout.addWidget(PasteButton,1,0,1,2)
layout.addWidget(self.typeLabel,1,2)
layout.addWidget(self.textLabel,2,0,1,3)
layout.addWidget(self.formatLabel,3,0,1,3)
self.setLayout(layout)
textCopyButton.clicked.connect(self.copyText)
htmlCopyButton.clicked.connect(self.copyHtml)
imageCopyButton.clicked.connect(self.copyImage)
PasteButton.clicked.connect(self.paste)
self.clipboard = QApplication.clipboard()
self.clipboard.dataChanged.connect(self.updateClipboard)
self.setWindowTitle("Clipboard 例子")
def copyText(self):
self.clipboard.setText("I've been clipped!")
def copyImage(self):
self.clipboard.setPixmap(QPixmap(os.path.join(
os.path.dirname(__file__),"./images/python.png")))
def copyHtml(self):
mimeData = QMimeData()
mimeData.setHtml("<b>Bold and <font color=red>Red</font></b>")
self.clipboard.setMimeData(mimeData)
def paste(self):
mimeData = self.clipboard.mimeData()
self.typeLabel.setText('')
if mimeData.hasImage():
self.textLabel.setPixmap(mimeData.imageData())
self.typeLabel.setText(self.typeLabel.text()+ '\n'+ 'hasImage')
elif mimeData.hasHtml():
self.textLabel.setText(mimeData.html())
self.textLabel.setTextFormat(Qt.RichText)
self.typeLabel.setText(self.typeLabel.text()+ '\n'+ 'hasHtml')
elif mimeData.hasText():
self.textLabel.setText(mimeData.text())
self.textLabel.setTextFormat(Qt.PlainText)
self.typeLabel.setText(self.typeLabel.text()+ '\n'+ 'hasText')
else:
self.textLabel.setText("Cannot display data")
def updateClipboard(self):
mimeData = self.clipboard.mimeData()
formats = mimeData.formats()
_str = ''
for format in formats:
data = mimeData.data(format)
_str = _str + '\n'+ format + ': '+ str(data.data()[:20])
self.formatLabel.setText(_str)
if __name__ =="__main__":
app = QApplication(sys.argv)
demo = Demo()
demo.show()
app.exec()