我有一个 python4/gtk4 应用程序,我希望能够将三种类型的数据输出到剪贴板。
我的代码似乎没有错误,符合我对 API 的理解。我已经在单独的测试应用程序中使用自己的代码测试了文本/纯文本输出以进行粘贴,并且它有效。但是,尝试粘贴到不是我自己创建的任何其他应用程序中不会导致粘贴任何内容。这包括 gEdit 46.2 和 LibreOffice Calc。
我的复制代码:
# Access the default clipboard for the application
clipboard = Gdk.Display.get_default().get_clipboard()
# Generate CSV data for external use
csv_data = self.get_csv_data_for_selected_cells()
# Generate and serialize the selected cell list and sheet reference for internal clipboard use
selection = {
'sheet_name': self.model.sheets[self.model.current_sheet_index]['name'],
'selected_cells': self._all_selected_cells
}
serialized_selection = pickle.dumps(selection)
# Convert serialized data to GLib.Bytes for clipboard use
gbytes_selection = GLib.Bytes.new(serialized_selection)
gbytes_csv = GLib.Bytes.new(csv_data)
# Create content providers for different formats
selection_provider = Gdk.ContentProvider.new_for_bytes("application/x-tab-selection", gbytes_selection)
csv_provider = Gdk.ContentProvider.new_for_bytes("text/csv", gbytes_csv)
text_provider = Gdk.ContentProvider.new_for_bytes("text/plain", gbytes_csv) # Optionally treat CSV as plain text
# Combine content providers into a union provider that offers multiple formats
union_provider = Gdk.ContentProvider.new_union([selection_provider, csv_provider, text_provider])
# Output the supported formats for debugging purposes
print(Gdk.ContentFormats.to_string(union_provider.ref_formats()))
# Set the union provider to the clipboard
clipboard.set_content(union_provider)
# Verify clipboard content by retrieving it immediately
clipboard.read_text_async(None, self.on_retrieve_clipboard_content)
# Set focus back to the main view
self.view.sourceview.grab_focus()
self.view.scrolled_window.grab_focus()
# Attempt to retrieve and verify clipboard content again (redundancy check in case this was a focus/persistancy issue)
clipboard.read_text_async(None, self.on_retrieve_clipboard_content)
我将代码粘贴到单独的测试应用程序中:
self.clipboard.read_text_async(None, self.on_paste_text)
def on_retrieve_clipboard_content(self, clipboard, result):
# Read the text from the clipboard and print it for verification
retrieved_text = clipboard.read_text_finish(result)
if retrieved_text:
print(f"Retrieved clipboard content: {retrieved_text}")
else:
print("Failed to retrieve clipboard content.")
这是我在副本中看到的示例:
application/x-tab-selection text/csv text/plain
<__gi__.GdkContentProviderUnion object at 0x7f0389561b80 (GdkContentProviderUnion at 0x555ac7a9ef90)>
Retrieved clipboard content: 42,99.0,12
56,,
,,
,4,88
Retrieved clipboard content: 42,99.0,12
56,,
,,
,4,88
但是,当我粘贴到 gEdit 中时,根本没有粘贴任何内容。只有当我通过自己的 read_text_async 调用访问数据时,我才能从剪贴板中获取任何内容。
我显然错过了一些相当关键的东西,所以任何提示将不胜感激!
我可以使用 text/plain;charset=utf-8 而不是使用 text/plain 作为 mime 类型,它解决了跨不同应用程序粘贴的问题。
我还通过该工具了解到,csv 数据不是有用的剪贴板材料,制表符分隔值是复制和粘贴电子表格数据的标准。
现在我有了内部应用程序序列化,并且生成了一个 text/plain;charset=utf8 输出:
tsv_writer = csv.writer(output, delimiter=‘\t’) # Use tab as the delimiter
感谢 discourse.gnome.org 上的 gwillems 提供的建议(https://discourse.gnome.org/t/gdk4-clipboard-union-provider-does-not-appear-to-make-data-available-as -预计/22978)。