Python работа с буфером обмена windows

How do I read text from the (windows) clipboard with python?

asked Sep 19, 2008 at 11:09

Foo42's user avatar

Foo42Foo42

3,0544 gold badges23 silver badges17 bronze badges

2

You can use the module called win32clipboard, which is part of pywin32.

Here is an example that first sets the clipboard data then gets it:

import win32clipboard

# set clipboard data
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText('testing 123')
win32clipboard.CloseClipboard()

# get clipboard data
win32clipboard.OpenClipboard()
data = win32clipboard.GetClipboardData()
win32clipboard.CloseClipboard()
print data

An important reminder from the documentation:

When the window has finished examining or changing the clipboard,
close the clipboard by calling CloseClipboard. This enables other
windows to access the clipboard. Do not place an object on the
clipboard after calling CloseClipboard.

SuperStormer's user avatar

SuperStormer

5,1575 gold badges26 silver badges35 bronze badges

answered Sep 19, 2008 at 11:20

Sakin's user avatar

SakinSakin

3,3973 gold badges24 silver badges27 bronze badges

5

you can easily get this done through the built-in module Tkinter which is basically a GUI library. This code creates a blank widget to get the clipboard content from OS.

from tkinter import Tk  # Python 3
#from Tkinter import Tk # for Python 2.x
Tk().clipboard_get()

answered May 24, 2014 at 11:58

kmonsoor's user avatar

kmonsoorkmonsoor

7,6407 gold badges41 silver badges55 bronze badges

2

I found pyperclip to be the easiest way to get access to the clipboard from python:

  1. Install pyperclip:
    pip install pyperclip

  2. Usage:

import pyperclip
    
s = pyperclip.paste()
pyperclip.copy(s)
    
# the type of s is string

Pyperclip supports Windows, Linux and Mac, and seems to work with non-ASCII characters, too.
Tested characters include ±°©©αβγθΔΨΦåäö

answered Jul 3, 2016 at 15:54

Niko Fohr's user avatar

Niko FohrNiko Fohr

28.7k10 gold badges95 silver badges98 bronze badges

6

If you don’t want to install extra packages, ctypes can get the job done as well.

import ctypes

CF_TEXT = 1

kernel32 = ctypes.windll.kernel32
kernel32.GlobalLock.argtypes = [ctypes.c_void_p]
kernel32.GlobalLock.restype = ctypes.c_void_p
kernel32.GlobalUnlock.argtypes = [ctypes.c_void_p]
user32 = ctypes.windll.user32
user32.GetClipboardData.restype = ctypes.c_void_p

def get_clipboard_text():
    user32.OpenClipboard(0)
    try:
        if user32.IsClipboardFormatAvailable(CF_TEXT):
            data = user32.GetClipboardData(CF_TEXT)
            data_locked = kernel32.GlobalLock(data)
            text = ctypes.c_char_p(data_locked)
            value = text.value
            kernel32.GlobalUnlock(data_locked)
            return value
    finally:
        user32.CloseClipboard()

print(get_clipboard_text())

answered Apr 25, 2014 at 5:54

kichik's user avatar

kichikkichik

33.4k7 gold badges95 silver badges114 bronze badges

5

The most upvoted answer above is weird in a way that it simply clears the Clipboard and then gets the content (which is then empty). One could clear the clipboard to be sure that some clipboard content type like «formated text» does not «cover» your plain text content you want to save in the clipboard.

The following piece of code replaces all newlines in the clipboard by spaces, then removes all double spaces and finally saves the content back to the clipboard:

import win32clipboard

win32clipboard.OpenClipboard()
c = win32clipboard.GetClipboardData()
win32clipboard.EmptyClipboard()
c = c.replace('\n', ' ')
c = c.replace('\r', ' ')
while c.find('  ') != -1:
    c = c.replace('  ', ' ')
win32clipboard.SetClipboardText(c)
win32clipboard.CloseClipboard()

answered Jun 19, 2012 at 8:00

born's user avatar

bornborn

6561 gold badge6 silver badges21 bronze badges

The python standard library does it…

try:
    # Python3
    import tkinter as tk
except ImportError:
    # Python2
    import Tkinter as tk

def getClipboardText():
    root = tk.Tk()
    # keep the window from showing
    root.withdraw()
    return root.clipboard_get()

ankostis's user avatar

ankostis

8,5893 gold badges47 silver badges63 bronze badges

answered Apr 4, 2018 at 8:42

Paul Sumpner's user avatar

2

For my console program the answers with tkinter above did not quite work for me because the .destroy() always gave an error,:

can’t invoke «event» command: application has been destroyed while executing…

or when using .withdraw() the console window did not get the focus back.

To solve this you also have to call .update() before the .destroy(). Example:

# Python 3
import tkinter

r = tkinter.Tk()
text = r.clipboard_get()
r.withdraw()
r.update()
r.destroy()

The r.withdraw() prevents the frame from showing for a milisecond, and then it will be destroyed giving the focus back to the console.

answered Jan 17, 2015 at 1:08

user136036's user avatar

user136036user136036

11.3k6 gold badges46 silver badges46 bronze badges

Use Pythons library Clipboard

Its simply used like this:

import clipboard
clipboard.copy("this text is now in the clipboard")
print clipboard.paste()  

answered Apr 27, 2016 at 10:19

Dan's user avatar

DanDan

1471 silver badge4 bronze badges

5

import pandas as pd
df = pd.read_clipboard()

answered Dec 7, 2021 at 4:21

Athii's user avatar

AthiiAthii

1302 silver badges11 bronze badges

1

After whole 12 years, I have a solution and you can use it without installing any package.

from tkinter import Tk, TclError
from time import sleep

while True:
    try:
        clipboard = Tk().clipboard_get()
        print(clipboard)
        sleep(5)
    except TclError:
        print("Clipboard is empty.")
        sleep(5)

answered Apr 29, 2021 at 19:17

kirgizmustafa17's user avatar

Why not try calling powershell?

import subprocess

def getClipboard():
    ret = subprocess.getoutput("powershell.exe -Command Get-Clipboard")
    return ret

answered Feb 18, 2022 at 5:36

东临碣石's user avatar

1

A not very direct trick:

Use pyautogui hotkey:

Import pyautogui
pyautogui.hotkey('ctrl', 'v')

Therefore, you can paste the clipboard data as you like.

answered Jul 9, 2019 at 7:06

see2's user avatar

1

For users of Anaconda: distributions don’t come with pyperclip, but they do come with pandas which redistributes pyperclip:

>>> from pandas.io.clipboard import clipboard_get, clipboard_set
>>> clipboard_get()
'from pandas.io.clipboard import clipboard_get, clipboard_set'
>>> clipboard_set("Hello clipboard!")
>>> clipboard_get()
'Hello clipboard!'

I find this easier to use than pywin32 (which is also included in distributions).

answered Dec 6, 2021 at 16:14

asdf101's user avatar

asdf101asdf101

5695 silver badges18 bronze badges

I was looking for ways to listen to the clipboard and get called for updates as its content changes.
I found a couple of ways to achieve this in Python. Some solutions poll for changes, others use ctypes and Win32 APIs.

Working with C bindings in Python is frustrating. The debugger doesn’t work well with pointers and C types. You have to build your own C structs to unpack a pointer. Win32 APIs are no exception, as they’re written in C/C++ and Python is probably not the best language to use them. But still, it works well enough for our purposes.

We’ll explore how do to it in Python using Win32 APIs, or alternatively integrating a utility I’ve written in C# that retrieves clipboard contents or streams updates to it. I had written this earlier when I didn’t know much about Win32 APIs or how to use them, but it still functions well, so I’m leaving it here in this post as reference.

To make working with Win32 APIs easier, we need to install pywin32 package which provides most of the primitives and types for Win32 APIs, though it’s not a strict dependency.

Monitoring clipboard updates

Windows provides a couple of methods for data exchange between applications. Clipboard is one of them. All applications have access to it. But we first need to create a primitive «application» that Windows recognizes. We subscribe it for the clipboard updates.

Windows uses windows (hah!) as the building block of applications. I’ve written about how windows and messaging works on Windows in another post where I explored USB hotplugging events, which might be worth reading.

Let’s create a window, and set print function as its window procedure:

import win32api, win32gui

def create_window() -> int:
    """
    Create a window for listening to messages
    :return: window hwnd
    """
    wc = win32gui.WNDCLASS()
    wc.lpfnWndProc = print
    wc.lpszClassName = 'demo'
    wc.hInstance = win32api.GetModuleHandle(None)
    class_atom = win32gui.RegisterClass(wc)
    return win32gui.CreateWindow(class_atom, 'demo', 0, 0, 0, 0, 0, 0, 0, wc.hInstance, None)

if __name__ == '__main__':
    hwnd = create_window()
    win32gui.PumpMessages()

When we run it doesn’t do much except to dump messages sent by Windows to console. We receive the first message WM_DWMNCRENDERINGCHANGED, which doesn’t concern us.

We need to register this window as a «clipboard format listener» using AddClipboardFormatListener API, to get notified by Windows whenever the contents of the clipboard change.

import ctypes
# ...

if __name__ == '__main__':
    hwnd = create_window()
    ctypes.windll.user32.AddClipboardFormatListener(hwnd)
    win32gui.PumpMessages()

Now when we run this, it still prints the previous message, but when you copy something to the clipboard it receives another message:

2033456 799 1 0
2033456 797 8 0

Decoding the second message:

Value Hex Message
797 0x031D WM_CLIPBOARDUPDATE 🥳

We’ve received a WM_CLIPBOARDUPDATE message notifying us that the clipboard content has changed. Now we can build our script around it.

import threading
import ctypes
import win32api, win32gui

class Clipboard:
    def _create_window(self) -> int:
        """
        Create a window for listening to messages
        :return: window hwnd
        """
        wc = win32gui.WNDCLASS()
        wc.lpfnWndProc = self._process_message
        wc.lpszClassName = self.__class__.__name__
        wc.hInstance = win32api.GetModuleHandle(None)
        class_atom = win32gui.RegisterClass(wc)
        return win32gui.CreateWindow(class_atom, self.__class__.__name__, 0, 0, 0, 0, 0, 0, 0, wc.hInstance, None)

    def _process_message(self, hwnd: int, msg: int, wparam: int, lparam: int):
        WM_CLIPBOARDUPDATE = 0x031D
        if msg == WM_CLIPBOARDUPDATE:
            print('clipboard updated!')
        return 0

    def listen(self):
        def runner():
            hwnd = self._create_window()
            ctypes.windll.user32.AddClipboardFormatListener(hwnd)
            win32gui.PumpMessages()

        th = threading.Thread(target=runner, daemon=True)
        th.start()
        while th.is_alive():
            th.join(0.25)

if __name__ == '__main__':
    clipboard = Clipboard()
    clipboard.listen()

One thing we need to watch out for is that because win32gui.PumpMessages() is blocking, we cannot stop the script using Ctrl + C. So we run it inside a thread, which lets KeyboardInterrupt to bubble up and terminate the script.

When we run it, and copy something (text, files) and check the console, we can see it prints clipboard updated!.

Now that we have the notification working, let’s retrieve the what’s actually in the clipboard.

Getting clipboard contents

Windows clipboard has a concept called «clipboard format». When you copy something, (depending on application) the payload is also attached a bunch of metadata, allowing it to be used in various contexts. For example, when you copy a table from a webpage, you have the option to paste it as plain text, or paste it in Excel and have it formatted as a table. You can copy files, images, screenshots into the clipboard and each payload gets stored formatted (again, depending on how the application sets the clipboard content).

Therefore, if we want to get the clipboard contents, we need to specify which format we want in. For now, we’ll be dealing with:

Format Value Description
CF_UNICODETEXT 13 Unicode text format
CF_TEXT 1 Text format for ANSI text
CF_HDROP 15 List of files
CF_BITMAP 2 Images e.g. screenshots

To read the clipboard, we’ll use OpenClipboard to set a lock first. This ensures other programs can’t modify the clipboard while we’re trying to read it. We need to release the lock with CloseClipboard once we’re done.

Then we’ll call IsClipboardFormatAvailable to query a format, then get its contents using GetClipboardData, or fallback to other formats.

from pathlib import Path
from dataclasses import dataclass
from typing import Union, List, Optional

import win32clipboard, win32con

@dataclass
class Clip:
    type: str
    value: Union[str, List[Path]]
    
def read_clipboard() -> Optional[Clip]:
    try:
        win32clipboard.OpenClipboard()
        if win32clipboard.IsClipboardFormatAvailable(win32con.CF_HDROP):
            data: tuple = win32clipboard.GetClipboardData(win32con.CF_HDROP)
            return Clip('files', [Path(f) for f in data])
        elif win32clipboard.IsClipboardFormatAvailable(win32con.CF_UNICODETEXT):
            data: str = win32clipboard.GetClipboardData(win32con.CF_UNICODETEXT)
            return Clip('text', data)
        elif win32clipboard.IsClipboardFormatAvailable(win32con.CF_TEXT):
            data: bytes = win32clipboard.GetClipboardData(win32con.CF_TEXT)
            return Clip('text', data.decode())
        elif win32clipboard.IsClipboardFormatAvailable(win32con.CF_BITMAP):
            # TODO: handle screenshots
            pass
        return None
    finally:
        win32clipboard.CloseClipboard()

if __name__ == '__main__':
    print(read_clipboard())

When we run it, and try copying some text or files, it prints the contents to the console:

Clip(type='text', value='read_clipboard')
Clip(type='files', value=[WindowsPath('C:/Python39/vcruntime140_1.dll'), WindowsPath('C:/Python39/python.exe')])

Now let’s bring it all together:

Clipboard listener in Python

I’ve placed read_clipboard inside Clipboard class, which creates a window and subscribes to clipboard updates. When the clipboard content changes, it triggers suitable callbacks with the parsed content.

For convenience, you can enable trigger_at_start to trigger callbacks with the current clipboard content immediately after listening.

import ctypes
import threading
from dataclasses import dataclass
from pathlib import Path
from typing import Callable, Union, List, Optional

import win32api, win32clipboard, win32con, win32gui

class Clipboard:
    @dataclass
    class Clip:
        type: str
        value: Union[str, List[Path]]

    def __init__(
            self,
            trigger_at_start: bool = False,
            on_text: Callable[[str], None] = None,
            on_update: Callable[[Clip], None] = None,
            on_files: Callable[[str], None] = None,
    ):
        self._trigger_at_start = trigger_at_start
        self._on_update = on_update
        self._on_files = on_files
        self._on_text = on_text

    def _create_window(self) -> int:
        """
        Create a window for listening to messages
        :return: window hwnd
        """
        wc = win32gui.WNDCLASS()
        wc.lpfnWndProc = self._process_message
        wc.lpszClassName = self.__class__.__name__
        wc.hInstance = win32api.GetModuleHandle(None)
        class_atom = win32gui.RegisterClass(wc)
        return win32gui.CreateWindow(class_atom, self.__class__.__name__, 0, 0, 0, 0, 0, 0, 0, wc.hInstance, None)

    def _process_message(self, hwnd: int, msg: int, wparam: int, lparam: int):
        WM_CLIPBOARDUPDATE = 0x031D
        if msg == WM_CLIPBOARDUPDATE:
            self._process_clip()
        return 0

    def _process_clip(self):
        clip = self.read_clipboard()
        if not clip:
            return

        if self._on_update:
            self._on_update(clip)
        if clip.type == 'text' and self._on_text:
            self._on_text(clip.value)
        elif clip.type == 'files' and self._on_text:
            self._on_files(clip.value)
    
    @staticmethod
    def read_clipboard() -> Optional[Clip]:
        try:
            win32clipboard.OpenClipboard()

            def get_formatted(fmt):
                if win32clipboard.IsClipboardFormatAvailable(fmt):
                    return win32clipboard.GetClipboardData(fmt)
                return None

            if files := get_formatted(win32con.CF_HDROP):
                return Clipboard.Clip('files', [Path(f) for f in files])
            elif text := get_formatted(win32con.CF_UNICODETEXT):
                return Clipboard.Clip('text', text)
            elif text_bytes := get_formatted(win32con.CF_TEXT):
                return Clipboard.Clip('text', text_bytes.decode())
            elif bitmap_handle := get_formatted(win32con.CF_BITMAP):
                # TODO: handle screenshots
                pass

            return None
        finally:
            win32clipboard.CloseClipboard()

    def listen(self):
        if self._trigger_at_start:
            self._process_clip()

        def runner():
            hwnd = self._create_window()
            ctypes.windll.user32.AddClipboardFormatListener(hwnd)
            win32gui.PumpMessages()

        th = threading.Thread(target=runner, daemon=True)
        th.start()
        while th.is_alive():
            th.join(0.25)


if __name__ == '__main__':
    clipboard = Clipboard(on_update=print, trigger_at_start=True)
    clipboard.listen()

When we run it and copy some text, or some files, it dumps the clipboard content just as we want it.

Clipboard.Clip(type='text', value='Clipboard')
Clipboard.Clip(type='files', value=[WindowsPath('C:/Python39/python.exe')])

I haven’t managed to retrieve bitmap from the clipboard when taking a screenshot yet, though it shouldn’t be too difficult.

It should prove useful for the use case where when you take a screenshot, you can save it automatically as PNG, upload it and copy its URL to clipboard, ready for pasting.

Using dumpclip: polling for changes

Before I could navigate around Win32 APIs easily, I used higher level APIs provided in C# to listen to the clipboard. On that end, I created a mini utility called dumpclip that prints the clipboard content to console as JSON or streams clipboard updates.

The first version of dumpclip had a single function: dumping the clipboard content to console as JSON.

> dumpclip.v1.exe
{"text":"monitor"}

Calling it from Python is quite straightforward using subprocess module. But that also meant polling for changes every second.

import json
import subprocess
import threading
from time import sleep
from typing import Callable


def get_clipboard() -> dict:
    proc = subprocess.run(
        ["dumpclip.v1.exe"],
        stdout=subprocess.PIPE,
        text=True,
    )
    if proc.returncode != 0:
        return {}
    return json.loads(proc.stdout)


def monitor_clipboard(on_change: Callable[[dict], None]) -> None:
    def monitor():
        old = None
        while True:
            new = get_clipboard()
            if old != new:
                on_change(new)
                old = new
            sleep(1)

    th = threading.Thread(target=monitor)
    th.start()

    th.join()


if __name__ == "__main__":
    monitor_clipboard(on_change=print)

It’s functional, but we can do better.

Using dumpclip: streaming clipboard updates

The second iteration of dumpclip involved using Win32 APIs. I’ve used AddClipboardFormatListener to register a callback for clipboard changes in C#, then retrieved & dumped its content as the new content came in.

> dumpclip.v2.exe --listen
{"text":"ClipboardChanged"}
{"text":"monitor"}
{"files":["D:\\path\\to\\file.ext"]}
...

This worked much better. I can process its stdout stream, and trigger a callback directly, instead of polling for changes. But dumpclip launched in listener mode never terminates. We need to read its stdout in real-time.

To stream stdout of a process, we need to launch it with subprocess.Popen and pipe its output to subprocess.PIPE.
Then we can read its stdout in a separate thread. Because, the main thread that launches the process will be waiting for the process to terminate (although it never will).

import json
import subprocess
import threading
from typing import Callable

def monitor_clipboard(on_change: Callable[[dict], None]) -> None:
    def read_stdout(proc: subprocess.Popen):
        for line in iter(proc.stdout.readline, ""):
            if line.strip():
                payload = json.loads(line)
                on_change(payload)

    proc = subprocess.Popen(
        ["dumpclip.v2.exe", "--listen"],
        text=True,
        stdout=subprocess.PIPE,
    )
    th = threading.Thread(
        target=read_stdout,
        args=(proc,),
    )
    th.start()
    try:
        proc.wait()
    except KeyboardInterrupt:
        proc.kill()
        raise

if __name__ == "__main__":
    monitor_clipboard(on_change=print)

Because the process doesn’t terminate, the thread that consumes its output doesn’t stop, either.
It keeps processing the output as new content comes in, and idles if there’s nothing to consume, as proc.stdout.readline() call is blocking.
When the process gets killed, proc.stdout stops blocking and the thread terminates.

To prevent blocking interrupt signal and to allow the script and the process terminate, we need to .wait() the subprocess. This allows KeyboardInterrupt to bubble up and terminate the script (and its subprocesses) when we hit Ctrl + C.

Using dumpclip: async workflow

Just for kicks, I wanted to implement the same operation in async. It turned out to be more straightforward to write and consume. One caveat is that you have to create a wrapper async function to use async/await keywords, so I had to add a main function to do that.

import asyncio
import json
from pathlib import Path
from typing import AsyncIterable

async def monitor_clipboard() -> AsyncIterable[dict]:
    proc = await asyncio.subprocess.create_subprocess_exec(
        "dumpclip.exe",
        "--listen",
        cwd=str(Path(__file__).parent.resolve()),
        stdout=asyncio.subprocess.PIPE,
    )

    while True:
        if raw_bytes := await proc.stdout.readline():
            text = raw_bytes.decode().strip()
            if text:
                yield json.loads(text)

if __name__ == "__main__":
    async def main():
        async for clip in monitor_clipboard():
            print(clip)

    asyncio.get_event_loop().run_until_complete(main())

That’s it.
Cheers ✌

If you’ve found this post useful, consider sharing it.

I just need a python script that copies text to the clipboard.

After the script gets executed i need the output of the text to be pasted to another source.
Is it possible to write a python script that does this job?

M. A. Kishawy's user avatar

asked Jun 16, 2012 at 12:32

iamsiva11's user avatar

3

See Pyperclip. Example (taken from Pyperclip site):

import pyperclip
pyperclip.copy('The text to be copied to the clipboard.')
spam = pyperclip.paste()

Also, see Xerox. But it appears to have more dependencies.

vauhochzett's user avatar

vauhochzett

2,8572 gold badges17 silver badges43 bronze badges

answered Jun 16, 2012 at 12:35

robert's user avatar

robertrobert

33.4k8 gold badges53 silver badges74 bronze badges

5

On macOS, use subprocess.run to pipe your text to pbcopy:

import subprocess 
data = "hello world"
subprocess.run("pbcopy", text=True, input=data)

It will copy «hello world» to the clipboard.

Laszlo Treszkai's user avatar

answered Jun 28, 2013 at 18:27

kyle k's user avatar

kyle kkyle k

5,16410 gold badges31 silver badges45 bronze badges

6

To use native Python directories, use:

import subprocess

def copy2clip(txt):
    cmd='echo '+txt.strip()+'|clip'
    return subprocess.check_call(cmd, shell=True)

on Mac, instead:

import subprocess

def copy2clip(txt):
    cmd='echo '+txt.strip()+'|pbcopy'
    return subprocess.check_call(cmd, shell=True)

Then use:

copy2clip('This is on my clipboard!')

to call the function.

Community's user avatar

answered Dec 8, 2016 at 0:47

Binyamin's user avatar

BinyaminBinyamin

6678 silver badges17 bronze badges

11

PyQt5:

from PyQt5.QtWidgets import QApplication
import sys

def main():
    app = QApplication(sys.argv)
    cb = QApplication.clipboard()
    cb.clear(mode=cb.Clipboard )
    cb.setText("Copy to ClipBoard", mode=cb.Clipboard)
    # Text is now already in the clipboard, no need for further actions.
    sys.exit()

if __name__ == "__main__":
    main()

Community's user avatar

answered Nov 9, 2015 at 11:00

Akshay's user avatar

AkshayAkshay

4636 silver badges15 bronze badges

2

GTK3:

#!/usr/bin/python3

from gi.repository import Gtk, Gdk


class Hello(Gtk.Window):

    def __init__(self):
        super(Hello, self).__init__()
        clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
        clipboard.set_text("hello world", -1)
        Gtk.main_quit()


def main():
    Hello()
    Gtk.main()

if __name__ == "__main__":
    main()

answered Feb 25, 2015 at 15:29

Martin Thoma's user avatar

Martin ThomaMartin Thoma

126k159 gold badges621 silver badges961 bronze badges

1

I try this clipboard 0.0.4 and it works well.

https://pypi.python.org/pypi/clipboard/0.0.4

import clipboard
clipboard.copy("abc")  # now the clipboard content will be string "abc"
text = clipboard.paste()  # text will have the content of clipboard

answered Jun 28, 2016 at 6:34

Du Peng's user avatar

Du PengDu Peng

3513 silver badges3 bronze badges

2

One more answer to improve on:
https://stackoverflow.com/a/4203897/2804197
and https://stackoverflow.com/a/25476462/1338797 (Tkinter).

Tkinter is nice, because it’s either included with Python (Windows) or easy to install (Linux), and thus requires little dependencies for the end user.

Here I have a «full-blown» example, which copies the arguments or the standard input, to clipboard, and — when not on Windows — waits for the user to close the application:

import sys

try:
    from Tkinter import Tk
except ImportError:
    # welcome to Python3
    from tkinter import Tk
    raw_input = input

r = Tk()
r.withdraw()
r.clipboard_clear()

if len(sys.argv) < 2:
    data = sys.stdin.read()
else:
    data = ' '.join(sys.argv[1:])

r.clipboard_append(data)

if sys.platform != 'win32':
    if len(sys.argv) > 1:
        raw_input('Data was copied into clipboard. Paste and press ENTER to exit...')
    else:
        # stdin already read; use GUI to exit
        print('Data was copied into clipboard. Paste, then close popup to exit...')
        r.deiconify()
        r.mainloop()
else:
    r.destroy()

This showcases:

  • importing Tk across Py2 and Py3
  • raw_input and print() compatibility
  • «unhiding» Tk root window when needed
  • waiting for exit on Linux in two different ways.

Community's user avatar

answered Nov 4, 2015 at 13:35

Tomasz Gandor's user avatar

Tomasz GandorTomasz Gandor

8,2452 gold badges60 silver badges55 bronze badges

3

This is an altered version of @Martin Thoma’s answer for GTK3. I found that the original solution resulted in the process never ending and my terminal hung when I called the script. Changing the script to the following resolved the issue for me.

#!/usr/bin/python3

from gi.repository import Gtk, Gdk
import sys
from time import sleep

class Hello(Gtk.Window):

    def __init__(self):
        super(Hello, self).__init__()
        
        clipboardText = sys.argv[1]
        clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
        clipboard.set_text(clipboardText, -1)
        clipboard.store()


def main():
    Hello()
    
    

if __name__ == "__main__":
    main()

You will probably want to change what clipboardText gets assigned to, in this script it is assigned to the parameter that the script is called with.

On a fresh ubuntu 16.04 installation, I found that I had to install the python-gobject package for it to work without a module import error.

Neuron's user avatar

Neuron

5,1875 gold badges38 silver badges60 bronze badges

answered Apr 25, 2016 at 11:34

Programster's user avatar

ProgramsterProgramster

12.3k9 gold badges49 silver badges55 bronze badges

Буфер обмена – важный инструмент в операционной системе Windows, позволяющий хранить информацию во время копирования или вырезания файлов, текстового контента или изображений. Python, один из самых популярных языков программирования в мире, предоставляет мощные возможности для работы с буфером обмена.

Библиотека pyperclip является отличным инструментом для работы с буфером обмена в Python. Она обеспечивает простой и интуитивно понятный интерфейс для копирования, вставки и получения данных из буфера обмена. Благодаря этой библиотеке можно легко автоматизировать рутинные задачи и повысить производительность своей работы.

Пример использования библиотеки pyperclip:

import pyperclip

# Копирование данных в буфер обмена

text = "Пример текста для копирования"

pyperclip.copy(text)

# Получение данных из буфера обмена

data = pyperclip.paste()

print(data) # Вывод: Пример текста для копирования

Кроме того, библиотеку pyperclip можно использовать для манипулирования текстовыми данными, сокращая время и усилия, затрачиваемые на ввод и форматирование. Например, можно создать сценарий, который автоматически копирует и вставляет введенный текст, предварительно удаляя из него лишние пробелы и символы пунктуации.

Необходимость использования буфера обмена может возникнуть во многих сценариях программирования на Python. Например, можно использовать его для обмена данными между различными приложениями, создания скриптов для парсинга и анализа данных, автоматизации процессов и многого другого. Библиотека pyperclip поможет вам легко управлять операциями копирования, вставки и получения данных из буфера обмена.

Содержание

  1. Примеры использования буфера обмена Python Windows
  2. Основные возможности буфера обмена Python Windows
  3. Получение данных из буфера обмена Python Windows
  4. Запись данных в буфер обмена Python Windows

Примеры использования буфера обмена Python Windows

Вот несколько примеров использования буфера обмена в Python:

1. Копирование текста в буфер обмена:


import pyperclip
text = "Пример текста для копирования"
pyperclip.copy(text)

В этом примере мы используем функцию copy из модуля pyperclip для копирования текста в буфер обмена. После выполнения этого кода, текст будет доступен для вставки в других приложениях.

2. Получение текста из буфера обмена:


import pyperclip
text = pyperclip.paste()
print(text)

В этом примере мы используем функцию paste из модуля pyperclip для получения текста из буфера обмена. После выполнения этого кода, текст, сохраненный в буфере обмена, будет выведен на экран.

3. Использование буфера обмена для обмена данными между разными приложениями:


import pyperclip
import time
text = "Пример текста для обмена данными"
# Скопировать текст в буфер обмена
pyperclip.copy(text)
# Ожидание перед вставкой текста
time.sleep(5)
# Вставить текст из буфера обмена
pyperclip.paste()

В данном примере мы копируем текст в буфер обмена с помощью функции copy и ожидаем 5 секунд. Затем мы получаем текст из буфера обмена с помощью функции paste. Таким образом, мы можем обмениваться данными между разными приложениями, используя буфер обмена.

Это лишь небольшой пример возможностей использования буфера обмена в Python при работе с операционной системой Windows. В зависимости от задачи, можно использовать другие функции и методы, предоставляемые модулем pyperclip, чтобы эффективно обрабатывать данные в буфере обмена.

Использование буфера обмена позволяет упростить работу с текстом и данными в Windows, и язык программирования Python с модулем pyperclip делает этот процесс еще более гибким и удобным.

Основные возможности буфера обмена Python Windows

Возможность Описание
Копирование текста Буфер обмена Python Windows позволяет копировать текст из одного приложения и вставлять его в другое. Это полезно, например, при редактировании текста или работы с таблицами.
Копирование изображений Не только текст, но и изображения могут быть скопированы и вставлены с помощью буфера обмена Python Windows. Это позволяет, например, передавать снимки экрана или другие графические данные между различными приложениями.
Обмен данными Буфер обмена Python Windows позволяет обмениваться данными между приложениями, даже если они разработаны на разных языках программирования или работают под различными операционными системами. Это позволяет синхронизировать данные и упрощает совместную работу.
Передача файлов С помощью буфера обмена Python Windows можно передавать файлы между приложениями. Например, можно скопировать файл из проводника Windows и вставить его в редактор кода для дальнейшей работы.
Автоматизация операций Буфер обмена Python Windows позволяет автоматизировать определенные операции, связанные с обменом данными. Например, можно скопировать текст из одного приложения, обработать его с помощью Python и вставить результат в другое приложение.

Это лишь некоторые из основных возможностей, которыми обладает буфер обмена Python Windows. Он предоставляет широкие возможности для обмена данными и повышения эффективности работы с различными приложениями.

Получение данных из буфера обмена Python Windows

Для работы с буфером обмена в Python Windows используется библиотека win32clipboard. Она предоставляет набор функций для работы с буфером обмена, включая получение текста, изображений и других типов данных.

Пример получения текста из буфера обмена в Python Windows:

«`python

import win32clipboard

def get_clipboard_text():

win32clipboard.OpenClipboard()

clipboard_data = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT)

win32clipboard.CloseClipboard()

return clipboard_data.decode(‘utf-8’)

clipboard_text = get_clipboard_text()

print(clipboard_text)

Пример функции get_clipboard_text открывает буфер обмена, получает данные в формате текста с помощью функции win32clipboard.GetClipboardData и закрывает буфер обмена с помощью функции win32clipboard.CloseClipboard. Затем данные декодируются из байтовой строки в текстовую.

Таким образом, использование библиотеки win32clipboard позволяет получать данные из буфера обмена в Python Windows, что открывает возможности для автоматизации действий с данными между различными приложениями.

Запись данных в буфер обмена Python Windows

Один из способов записи данных в буфер обмена — использование модуля winsound. Модуль winsound позволяет проигрывать звуки и также может использоваться для записи текста в буфер обмена. Для записи данных в буфер обмена с помощью модуля winsound, необходимо выполнить следующие шаги:

Шаг Код
1 import winsound
2 winsound.OpenClipboard()
3 winsound.EmptyClipboard()
4 winsound.SetClipboardData(winsound.CF_UNICODETEXT, "Текст для записи в буфер обмена")
5 winsound.CloseClipboard()

В этом примере мы импортируем модуль winsound, открываем буфер обмена с помощью winsound.OpenClipboard(), очищаем его с помощью winsound.EmptyClipboard(), записываем данные в буфер обмена с помощью winsound.SetClipboardData(), указывая тип данных (в данном случае winsound.CF_UNICODETEXT) и сам текст, а затем закрываем буфер обмена с помощью winsound.CloseClipboard().

Также существует другой способ записи данных в буфер обмена с помощью стандартной библиотеки Python — модуля ctypes. Модуль ctypes позволяет взаимодействовать с библиотеками операционной системы прямо из Python. Для записи данных в буфер обмена с помощью модуля ctypes, необходимо выполнить следующие шаги:

Шаг Код
1 import ctypes
2 ctypes.windll.user32.OpenClipboard(0)
3 ctypes.windll.user32.EmptyClipboard()
4 ctypes.windll.user32.SetClipboardData(13, ctypes.c_wchar_p("Текст для записи в буфер обмена"))
5 ctypes.windll.user32.CloseClipboard()

В этом примере мы импортируем модуль ctypes, открываем буфер обмена с помощью ctypes.windll.user32.OpenClipboard(0), очищаем его с помощью ctypes.windll.user32.EmptyClipboard(), записываем данные в буфер обмена с помощью ctypes.windll.user32.SetClipboardData(), указывая тип данных (в данном случае 13, что соответствует типу Unicode текста) и сам текст, а затем закрываем буфер обмена с помощью ctypes.windll.user32.CloseClipboard().

Оба этих метода позволяют записывать данные в буфер обмена в Python для Windows и выбор конкретного метода зависит от ваших предпочтений и требований к проекту

7 / 6 / 7

Регистрация: 10.08.2015

Сообщений: 63

1

27.08.2015, 11:01. Показов 72161. Ответов 10


Студворк — интернет-сервис помощи студентам

Возникла необходимость написать программу работающую с буфером обмена Windows. Поиск в гугле по схожим запросам практически не дал результатов. Только о Clipboard в Tkinter, но без подробных описаний или примеров.
Какие есть методы/функции для работы с буфером обмена в Python? Где найти информацию о нём?

P.S. Желательны ресурсы на русском языке.



0



ВАСИЛЕВС

561 / 484 / 168

Регистрация: 14.02.2012

Сообщений: 1,561

27.08.2015, 11:18

2

Я нашел модуль pyperclip
Пример работы

Python
1
2
3
4
>>> import pyperclip
>>> pyperclip.copy('The text to be copied to the clipboard.')
>>> pyperclip.paste()
'The text to be copied to the clipboard.'



2



7 / 6 / 7

Регистрация: 10.08.2015

Сообщений: 63

27.08.2015, 11:45

 [ТС]

3

Подобное я тоже находил. Но paste/copy маловато для моей программы.
Необходимо что бы при нажатии клавиш(любых ctrl+c к примеру) питон копировал к себе в переменную, выполнял с содержимым действия и возвращал в буфер изменённое значение.

К примеру я выделяю в браузере «100» нажимаю ctrL+c. Значение 100 записывается в переменную x. Происходит действие x+50. И при нажатии ctrl+v возвращал «150»



0



Эксперт Python

4614 / 2035 / 359

Регистрация: 17.03.2012

Сообщений: 10,102

Записей в блоге: 6

27.08.2015, 11:46

4

В PyQT есть QClipboard.



0



akzo

71 / 67 / 6

Регистрация: 08.08.2013

Сообщений: 286

Записей в блоге: 8

27.08.2015, 11:59

5

Лучший ответ Сообщение было отмечено Protos73 как решение

Решение

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# -*- coding:utf-8 -*-
from Tkinter import *
 
 
#окно
tk=Tk()
tk.geometry("300x200+100+100")
 
#функция читающая буфер
def read(e):
    
    bufer_data['text'] = tk.clipboard_get()
 
#функция записывающая в буфер   
def write(e):
    tk.clipboard_clear()
    tk.clipboard_append('akzo rulez:)')
 
#текст с содержанием буфера
bufer_data = Label(tk,text="No Data")
bufer_data.pack(expand='YES')
 
#кнопка вызывающая фкнуцию для чтения
button = Button(tk, text="Read Bufer Data")
button.pack(expand='YES')
button.bind("<Button-1>",read)
 
#кнопка для записи
button = Button(tk, text="Write Bufer Data")
button.pack(expand='YES')
button.bind("<Button-1>",write)
 
 
tk.mainloop()

Это простая программа в процедурном стиле, к этому добавляете еще знания отсюда: http://ehow.kurortmag.net/page… aad37.html
Немножко додумываете и радуетесь жизни



1



1518 / 488 / 57

Регистрация: 10.04.2009

Сообщений: 8,230

23.02.2021, 13:36

6

здравствуйте гугл по запросу
питон из буфера обмена поместить в переменную
привёл меня сюда-есть пример попроще? без Tkinter-типа инпута? спс



0



Garry Galler

Эксперт Python

5412 / 3836 / 1214

Регистрация: 28.10.2013

Сообщений: 9,554

Записей в блоге: 1

23.02.2021, 14:25

7

Цитата
Сообщение от Ципихович Эндрю
Посмотреть сообщение

есть пример попроще?

Ты как всегда решил сначала спросить и только потом попробовать?

Python
1
2
3
4
5
6
>>> import pyperclip
>>> # сейчас это в буфере обмена так как я туда скопировал
>>> x = pyperclip.paste()
>>> print(x)
# сейчас это в буфере обмена так как я туда скопировал
>>>



1



Ципихович Эндрю

1518 / 488 / 57

Регистрация: 10.04.2009

Сообщений: 8,230

23.02.2021, 14:41

8

нет нужно по аналогии

Python
1
n = int(input('Введите количество строк, и нажмите Enter'))
Python
1
print('Скопируйте нужный текст, и нажмите Enter')

и после того как скопировали и нажали ОК в переменную
inpt = попадает скопированное



0



Garry Galler

Эксперт Python

5412 / 3836 / 1214

Регистрация: 28.10.2013

Сообщений: 9,554

Записей в блоге: 1

23.02.2021, 16:59

9

Цитата
Сообщение от Ципихович Эндрю
Посмотреть сообщение

нет нужно по аналогии

Не понимаю твоей аналогии.
pyperclip это инструмент для работы с буфером обмена. Все прочие работают аналогично.
Если тебе нужно что-то иное — пиши сам.

Добавлено через 51 минуту
Или ты сам не понял своей же аналогии.
У буфера обмена есть ровно две функции: copy (скопировать что-то), paste (вставить из буфера в другое место):

Python
1
2
3
4
5
>>> pyperclip.copy("# сейчас это в буфере обмена так как я туда скопировал")
>>> x= pyperclip.paste()
>>> print(x)
# сейчас это в буфере обмена так как я туда скопировал
>>>

А всякого рода нажатия OK или Enter никакого отношения к работе буфера не имеют.
Он работает только с Ctrl-C и Ctrl-V.



2



1518 / 488 / 57

Регистрация: 10.04.2009

Сообщений: 8,230

23.02.2021, 17:10

10

Цитата
Сообщение от Garry Galler
Посмотреть сообщение

А всякого рода нажатия OK или Enter никакого отношения к работе буфера не имеют.
Он работает только с Ctrl-C и Ctrl-V.

я это уже вспомнил, есть инструменты для уточнения последнего\предпоследнего и других по счёту элементов — что в буфере находятся?

Добавлено через 1 минуту

Цитата
Сообщение от Garry Galler
Посмотреть сообщение

ровно две функции: copy (скопировать что-то), paste (вставить из буфера в другое место)

ну так и скопировать что-то и залетать в значение переменной



0



Эксперт Python

5412 / 3836 / 1214

Регистрация: 28.10.2013

Сообщений: 9,554

Записей в блоге: 1

23.02.2021, 17:22

11

Цитата
Сообщение от Ципихович Эндрю
Посмотреть сообщение

что в буфере находятся

В буфере находится ровно один элемент (не считая того, что он может быть одновременно в нескольких форматах). Нет никаких первых-последних.
Что туда положил\скопировал, то там сейчас и лежит. Каждое новое копирование замещает предыдущее.
У системного буфера нет никакой истории. Историю копирований сохраняют только специальные программы имитирующие такой буфер — clipdiary, например.
Или буфер MS Office и т.д.



1



  • Python активация виртуального окружения windows
  • Python pip not found windows
  • Python windows set python path
  • Python windows path to string
  • Python path переменная среда windows 10