Re: [Tkinter-discuss] clipboard and bytes
Hi, Vasilis Vlachoudis wrote: > I works within the same process. > When I try to launch it twice, so I can have clipboard exchange between > different processes > > I get the following exception: > Traceback (most recent call last): > File "/usr/lib/python3.6/tkinter/__init__.py", line 1702, in __call__ > return self.func(*args) > File "foo.py", line 41, in paste > res = root.tk.call(clip) > _tkinter.TclError: invalid command name "139879786444744cp" oh sure, I did not think about *that* :) This is not going to work of course with two separate program instances. > I did something else. > I've used the binascii.b2a_hex() and a2b_hex() functions > to convert the bytes() to a hex string and the reverse (double in size, > and a useless UTF-8 conversion, encode/decode) > This way it works but not a clean approach, > since I am copying in the clipboard binary data in a form of ascii. Actually I believe, if you got it working, that it is probably the most "clean" approach, at least as long as you stay within Tk; I guess that other software might only receive "junk data" from the clipboard, though. > Is there a way to create a new mime format and advertise > the format somehow in the clipboard? Quoting "man clipboard" again: " Type specifies the form in which the selection is to be returned (the desired ``target'' for conversion, in ICCCM terminology), and should be an atom name such as STRING or FILE_NAME; see the Inter-Client Communication Conventions Manual for complete details. Type defaults to STRING. The format argument specifies the representation that should be used to transmit the selection to the requester (the second column of Table 2 of the ICCCM), and defaults to STRING.(...) The format argument is needed only for compatibility with clipboard requesters that do not use Tk. If the Tk toolkit is being used to retrieve the CLIPBOARD selection then the value is converted back to a string at the requesting end, so format is irrelevant." So I guess that the answer is probably "yes" here, but it sounds to me like a non-trivial task that might require a considerable amount of extra-investigation. > I've been reading and debugging a bit what firefox is doing and how the > selection is treated. I couldn't find anywhere how to handle binary > data, but firefox when you copy an image it creates customs mime types > like image/png that contain the data in a form '0x39 0xf7 0xb8 0x8f > 0xff ...' Probably they are doing something of that ICCCM compliant things, but I really don't know anything about that. > Now I don't know if it is tk/tcl or _tkinter that makes this > interpretation or the data are really ascii written in hex format, but > I think even like this it can work for me. I think it is surely tcl/tk that does it, tkinter only calls tk's clipboard commands. However tkinter in some situations *might* do some "mangling" to the data that tk returns (e.g. in the example from my previous post, when the "embedded" helper func would return a list, self.tk.call() would turn this into a tuple). Best regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Fascinating, a totally parochial attitude. -- Spock, "Metamorphosis", stardate 3219.8 ___ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss
Re: [Tkinter-discuss] clipboard and bytes
I've been reading and debugging a bit what firefox is doing and how the selection is treated. I couldn't find anywhere how to handle binary data, but firefox when you copy an image it creates customs mime types like image/png that contain the data in a form '0x39 0xf7 0xb8 0x8f 0xff ...' Now I don't know if it is tk/tcl or _tkinter that makes this interpretation or the data are really ascii written in hex format, but I think even like this it can work for me. An interesting feature is the selection_get(type='TARGETS') which returns all possible mime/formats available. V. From: Vasilis Vlachoudis Sent: Thursday, March 01, 2018 17:13 To: Michael Lange; tkinter-discuss@python.org Subject: RE: [Tkinter-discuss] clipboard and bytes I did something else. I've used the binascii.b2a_hex() and a2b_hex() functions to convert the bytes() to a hex string and the reverse (double in size, and a useless UTF-8 conversion, encode/decode) This way it works but not a clean approach, since I am copying in the clipboard binary data in a form of ascii. Is there a way to create a new mime format and advertise the format somehow in the clipboard? Vasilis From: Vasilis Vlachoudis Sent: Thursday, March 01, 2018 16:42 To: Michael Lange; tkinter-discuss@python.org Subject: RE: [Tkinter-discuss] clipboard and bytes Many thanks! I works within the same process. When I try to launch it twice, so I can have clipboard exchange between different processes I get the following exception: Traceback (most recent call last): File "/usr/lib/python3.6/tkinter/__init__.py", line 1702, in __call__ return self.func(*args) File "foo.py", line 41, in paste res = root.tk.call(clip) _tkinter.TclError: invalid command name "139879786444744cp" I saw in the documentation that by default it uses the UTF8STRING as type I've tried to force it to type="STRING" but with no success From: Tkinter-discuss [tkinter-discuss-bounces+vasilis.vlachoudis=cern...@python.org] on behalf of Michael Lange [klappn...@web.de] Sent: Thursday, March 01, 2018 00:12 To: tkinter-discuss@python.org Subject: Re: [Tkinter-discuss] clipboard and bytes On Wed, 28 Feb 2018 20:42:51 +0100 Michael Lange wrote: (...) > So at least this primitive seems to work. Maybe you can use this > technique to achieve what you want. Or maybe this slightly modified example comes closer to what you are looking for: from tkinter import * root = Tk() def copy(string): def cp(): return string copyfunc = (root.register(cp)) return(copyfunc) root.clipboard_clear() root.clipboard_append(copy(b'foobar'), type='foo') def paste(ev): clip = root.clipboard_get(type='foo') res = root.tk.call(clip) print('->', res, type(res)) root.bind('', paste) root.mainloop() Regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. "... freedom ... is a worship word..." "It is our worship word too." -- Cloud William and Kirk, "The Omega Glory", stardate unknown ___ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss ___ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss
Re: [Tkinter-discuss] clipboard and bytes
I did something else. I've used the binascii.b2a_hex() and a2b_hex() functions to convert the bytes() to a hex string and the reverse (double in size, and a useless UTF-8 conversion, encode/decode) This way it works but not a clean approach, since I am copying in the clipboard binary data in a form of ascii. Is there a way to create a new mime format and advertise the format somehow in the clipboard? Vasilis From: Vasilis Vlachoudis Sent: Thursday, March 01, 2018 16:42 To: Michael Lange; tkinter-discuss@python.org Subject: RE: [Tkinter-discuss] clipboard and bytes Many thanks! I works within the same process. When I try to launch it twice, so I can have clipboard exchange between different processes I get the following exception: Traceback (most recent call last): File "/usr/lib/python3.6/tkinter/__init__.py", line 1702, in __call__ return self.func(*args) File "foo.py", line 41, in paste res = root.tk.call(clip) _tkinter.TclError: invalid command name "139879786444744cp" I saw in the documentation that by default it uses the UTF8STRING as type I've tried to force it to type="STRING" but with no success From: Tkinter-discuss [tkinter-discuss-bounces+vasilis.vlachoudis=cern...@python.org] on behalf of Michael Lange [klappn...@web.de] Sent: Thursday, March 01, 2018 00:12 To: tkinter-discuss@python.org Subject: Re: [Tkinter-discuss] clipboard and bytes On Wed, 28 Feb 2018 20:42:51 +0100 Michael Lange wrote: (...) > So at least this primitive seems to work. Maybe you can use this > technique to achieve what you want. Or maybe this slightly modified example comes closer to what you are looking for: from tkinter import * root = Tk() def copy(string): def cp(): return string copyfunc = (root.register(cp)) return(copyfunc) root.clipboard_clear() root.clipboard_append(copy(b'foobar'), type='foo') def paste(ev): clip = root.clipboard_get(type='foo') res = root.tk.call(clip) print('->', res, type(res)) root.bind('', paste) root.mainloop() Regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. "... freedom ... is a worship word..." "It is our worship word too." -- Cloud William and Kirk, "The Omega Glory", stardate unknown ___ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss ___ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss
Re: [Tkinter-discuss] clipboard and bytes
Many thanks! I works within the same process. When I try to launch it twice, so I can have clipboard exchange between different processes I get the following exception: Traceback (most recent call last): File "/usr/lib/python3.6/tkinter/__init__.py", line 1702, in __call__ return self.func(*args) File "foo.py", line 41, in paste res = root.tk.call(clip) _tkinter.TclError: invalid command name "139879786444744cp" I saw in the documentation that by default it uses the UTF8STRING as type I've tried to force it to type="STRING" but with no success From: Tkinter-discuss [tkinter-discuss-bounces+vasilis.vlachoudis=cern...@python.org] on behalf of Michael Lange [klappn...@web.de] Sent: Thursday, March 01, 2018 00:12 To: tkinter-discuss@python.org Subject: Re: [Tkinter-discuss] clipboard and bytes On Wed, 28 Feb 2018 20:42:51 +0100 Michael Lange wrote: (...) > So at least this primitive seems to work. Maybe you can use this > technique to achieve what you want. Or maybe this slightly modified example comes closer to what you are looking for: from tkinter import * root = Tk() def copy(string): def cp(): return string copyfunc = (root.register(cp)) return(copyfunc) root.clipboard_clear() root.clipboard_append(copy(b'foobar'), type='foo') def paste(ev): clip = root.clipboard_get(type='foo') res = root.tk.call(clip) print('->', res, type(res)) root.bind('', paste) root.mainloop() Regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. "... freedom ... is a worship word..." "It is our worship word too." -- Cloud William and Kirk, "The Omega Glory", stardate unknown ___ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss ___ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss
Re: [Tkinter-discuss] clipboard and bytes
On Wed, 28 Feb 2018 20:42:51 +0100 Michael Lange wrote: (...) > So at least this primitive seems to work. Maybe you can use this > technique to achieve what you want. Or maybe this slightly modified example comes closer to what you are looking for: from tkinter import * root = Tk() def copy(string): def cp(): return string copyfunc = (root.register(cp)) return(copyfunc) root.clipboard_clear() root.clipboard_append(copy(b'foobar'), type='foo') def paste(ev): clip = root.clipboard_get(type='foo') res = root.tk.call(clip) print('->', res, type(res)) root.bind('', paste) root.mainloop() Regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. "... freedom ... is a worship word..." "It is our worship word too." -- Cloud William and Kirk, "The Omega Glory", stardate unknown ___ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss
Re: [Tkinter-discuss] clipboard and bytes
Hi, On Wed, 28 Feb 2018 10:59:31 + Vasilis Vlachoudis wrote: (...) > In python3 Pickler requires a byte stream so I replaced all StringIO() > to BytesIO() and the targets with bytes target1 = b"" > Copying to clipboard work ok (or I believe so) > Pasting, clipboard_get() returns a str not bytes and the Unpickler > fails. Also If I try to encode("UTF-8") the clip data also it fails. according to man clipboard it is possible create custom data types to be stored in the tk clipboard: "You can put custom data into the clipboard by using a custom -type option. This is not necessarily portable, but can be very useful. The method of passing Tcl scripts this way is effective, but should be mixed with safe interpreters in production code." I set up a (rather useless) example how this can be done: ## from tkinter import * root = Tk() def copy(string): def cp(): return 666 copyfunc = (root.register(cp)) return(copyfunc) root.clipboard_clear() root.clipboard_append(copy('foobar'), type='foo') def paste(ev): clip = root.clipboard_get(type='foo') res = root.tk.call(clip) print('->', res, type(res)) root.bind('', paste) root.mainloop() # When I run this script and hit F1 I get the following output: $ python3 test5.py -> 666 So at least this primitive seems to work. Maybe you can use this technique to achieve what you want. Regards Michael .-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-. Without followers, evil cannot spread. -- Spock, "And The Children Shall Lead", stardate 5029.5 ___ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss
[Tkinter-discuss] clipboard and bytes
Hi all, I took the decision to convert my program to python3. I am stuck with the clipboard handling str vs bytes How can I get/receive bytes instead of str with the clipboard? What I was doing up to now was opening a StringIO stream dump a header and the objects as a dump from Pickler Up to now in python V2. it was working like this Copy to clilpboard: target1 = "" sio = io.StringIO() sio.write(target1) pickler = Pickler(sio) pickler.dump() root.clipboard._clear() root.clipboard_append(sio.getvalue()) Paste from clipboard: clip = root.clipboard_get(selection='CLIPBOARD') if clip.startswith(target1): pickler = Unpickler(io.StringIO(clipboard[len(target1):])) ... elif... In python3 Pickler requires a byte stream so I replaced all StringIO() to BytesIO() and the targets with bytes target1 = b"" Copying to clipboard work ok (or I believe so) Pasting, clipboard_get() returns a str not bytes and the Unpickler fails. Also If I try to encode("UTF-8") the clip data also it fails. Thanks in advance Vasilis ___ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss