使用OS X上的框架,我可以使用以下内容将PNG复制到粘贴板(在C中 - 显然我可以将NSPasteboard与Cocoa一起使用):
#include <ApplicationServices/ApplicationServices.h>
int copyThatThing(void)
{
PasteboardRef clipboard;
if (PasteboardCreate(kPasteboardClipboard, &clipboard) != noErr) {
return -1;
}
if (PasteboardClear(clipboard) != noErr) {
CFRelease(clipboard);
return -1;
}
size_t len;
char *pngbuf = createMyPNGBuffer(&len); /* Defined somewhere else */
if (pngbuf == NULL) {
CFRelease(clipboard);
return -1;
}
CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, pngbuf,
len, kCFAllocatorNull);
if (data == NULL) {
CFRelease(clipboard);
free(pngbuf);
return -1;
}
OSStatus err;
err = PasteboardPutItemFlavor(clipboard, NULL, kUTTypePNG, data, 0);
CFRelease(clipboard);
CFRelease(data);
free(pngbuf);
return 0;
}
我有兴趣将此功能移植到Linux / * BSD平台。我怎样才能使用X来复制它?
答案 0 :(得分:10)
在开始之前先阅读X Selections, Cut Buffers, and Kill Rings。 X11有一个相当独特的系统,似乎没有其他人复制过。
与大多数其他系统不同的一个奇怪之处:如果拥有选择的程序(剪贴板)消失,选择也会消失。因此,当您的程序说“我有一个选择(恰好是一个图像)”然后退出时,没有人能够从您那里请求该图像的副本。为了有用,剪贴板所有者需要至少坚持到另一个程序进行选择。
还在吗?这是一个使用PyGTK完成你想要的简短程序(因为C很痛苦)。
#!/usr/bin/env python
import gtk
import sys
count = 0
def handle_owner_change(clipboard, event):
global count
print 'clipboard.owner-change(%r, %r)' % (clipboard, event)
count += 1
if count > 1:
sys.exit(0)
image = gtk.gdk.pixbuf_new_from_file(sys.argv[1])
clipboard = gtk.clipboard_get()
clipboard.connect('owner-change', handle_owner_change)
clipboard.set_image(image)
clipboard.store()
gtk.main()
引擎盖下发生了什么:
如果剪贴板管理器正在运行,则此程序可能会立即退出。否则,它将等到另一个程序中执行“剪切/复制”。
答案 1 :(得分:2)
不支持在程序终止后在GTK剪贴板上存储数据的功能。 GTK.clipboard.store可能无法存储较大的图像(大于几百kB),而compiz等高级桌面功能可能会与此机制发生冲突。没有这些缺点的一种解决方案是在后台运行一个简单的gtk应用程序。以下Python服务器应用程序使用Pyro包来公开ImageToClipboard的方法:
#! /usr/bin/env python
# gclipboard-imaged.py
import gtk, sys, threading;
import Pyro.core;
class ImageToClipboard(Pyro.core.ObjBase):
def __init__(self, daemon):
Pyro.core.ObjBase.__init__(self)
self.daemon = daemon;
def _set_image(self, img):
clp = gtk.clipboard_get();
clp.set_image(img);
def set_image_from_filename(self, filename):
with gtk.gdk.lock:
img = gtk.gdk.pixbuf_new_from_file(filename);
self._set_image(img);
def quit(self):
with gtk.gdk.lock:
gtk.main_quit();
self.daemon.shutdown();
class gtkThread( threading.Thread ):
def run(self):
gtk.main();
def main():
gtk.gdk.threads_init();
gtkThread().start();
Pyro.core.initServer();
daemon = Pyro.core.Daemon();
uri = daemon.connect(ImageToClipboard(daemon),"imagetoclipboard")
print "The daemon running on port:",daemon.port
print "The object's uri is:",uri
daemon.requestLoop();
print "Shutting down."
return 0;
if __name__=="__main__":
sys.exit( main() )
启动此程序作为后台进程,即
gclipboard-imaged.py&amp;
以下示例客户端应用程序使用命令行中提供的文件名设置剪贴板图像:
#! /usr/bin/env python
# gclipboard-setimage.py
import Pyro.core, sys;
serverobj = Pyro.core.getProxyForURI("PYROLOC://localhost:7766/imagetoclipboard");
filename = sys.argv[1];
serverobj.set_image_from_filename(filename);
要将图像复制到剪贴板,请运行
gclipboard-setimage.py picname.png