How do I copy a string to the clipboard on Windows using Python?

后端 未结 23 2832
温柔的废话
温柔的废话 2020-11-22 03:13

I\'m trying to make a basic Windows application that builds a string out of user input and then adds it to the clipboard. How do I copy a string to the clipboard using Pytho

相关标签:
23条回答
  • 2020-11-22 03:42

    Here's the most easy and reliable way I found if you're okay depending on Pandas. However I don't think this is officially part of the Pandas API so it may break with future updates. It works as of 0.25.3

    from pandas.io import clipboard
    clipboard.copy("test")
    
    0 讨论(0)
  • 2020-11-22 03:46

    I've tried various solutions, but this is the simplest one that passes my test:

    #coding=utf-8
    
    import win32clipboard  # http://sourceforge.net/projects/pywin32/
    
    def copy(text):
        win32clipboard.OpenClipboard()
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardText(text, win32clipboard.CF_UNICODETEXT)
        win32clipboard.CloseClipboard()
    def paste():
        win32clipboard.OpenClipboard()
        data = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT)
        win32clipboard.CloseClipboard()
        return data
    
    if __name__ == "__main__":  
        text = "Testing\nthe “clip—board”:                                                                     
    0 讨论(0)
  • 2020-11-22 03:47

    You can also use ctypes to tap into the Windows API and avoid the massive pywin32 package. This is what I use (excuse the poor style, but the idea is there):

    import ctypes
    
    # Get required functions, strcpy..
    strcpy = ctypes.cdll.msvcrt.strcpy
    ocb = ctypes.windll.user32.OpenClipboard    # Basic clipboard functions
    ecb = ctypes.windll.user32.EmptyClipboard
    gcd = ctypes.windll.user32.GetClipboardData
    scd = ctypes.windll.user32.SetClipboardData
    ccb = ctypes.windll.user32.CloseClipboard
    ga = ctypes.windll.kernel32.GlobalAlloc    # Global memory allocation
    gl = ctypes.windll.kernel32.GlobalLock     # Global memory Locking
    gul = ctypes.windll.kernel32.GlobalUnlock
    GMEM_DDESHARE = 0x2000
    
    def Get():
      ocb(None) # Open Clip, Default task
    
      pcontents = gcd(1) # 1 means CF_TEXT.. too lazy to get the token thingy...
    
      data = ctypes.c_char_p(pcontents).value
    
      #gul(pcontents) ?
      ccb()
    
      return data
    
    def Paste(data):
      ocb(None) # Open Clip, Default task
    
      ecb()
    
      hCd = ga(GMEM_DDESHARE, len(bytes(data,"ascii")) + 1)
    
      pchData = gl(hCd)
    
      strcpy(ctypes.c_char_p(pchData), bytes(data, "ascii"))
    
      gul(hCd)
    
      scd(1, hCd)
    
      ccb()
    
    0 讨论(0)
  • 2020-11-22 03:47
    import wx
    
    def ctc(text):
    
        if not wx.TheClipboard.IsOpened():
            wx.TheClipboard.Open()
            data = wx.TextDataObject()
            data.SetText(text)
            wx.TheClipboard.SetData(data)
        wx.TheClipboard.Close()
    
    ctc(text)
    
    0 讨论(0)
  • 2020-11-22 03:48

    In addition to Mark Ransom's answer using ctypes: This does not work for (all?) x64 systems since the handles seem to be truncated to int-size. Explicitly defining args and return values helps to overcomes this problem.

    import ctypes
    import ctypes.wintypes as w
    
    CF_UNICODETEXT = 13
    
    u32 = ctypes.WinDLL('user32')
    k32 = ctypes.WinDLL('kernel32')
    
    OpenClipboard = u32.OpenClipboard
    OpenClipboard.argtypes = w.HWND,
    OpenClipboard.restype = w.BOOL
    
    GetClipboardData = u32.GetClipboardData
    GetClipboardData.argtypes = w.UINT,
    GetClipboardData.restype = w.HANDLE
    
    EmptyClipboard = u32.EmptyClipboard
    EmptyClipboard.restype = w.BOOL
    
    SetClipboardData = u32.SetClipboardData
    SetClipboardData.argtypes = w.UINT, w.HANDLE,
    SetClipboardData.restype = w.HANDLE
    
    CloseClipboard = u32.CloseClipboard
    CloseClipboard.argtypes = None
    CloseClipboard.restype = w.BOOL
    
    GHND = 0x0042
    
    GlobalAlloc = k32.GlobalAlloc
    GlobalAlloc.argtypes = w.UINT, w.ctypes.c_size_t,
    GlobalAlloc.restype = w.HGLOBAL
    
    GlobalLock = k32.GlobalLock
    GlobalLock.argtypes = w.HGLOBAL,
    GlobalLock.restype = w.LPVOID
    
    GlobalUnlock = k32.GlobalUnlock
    GlobalUnlock.argtypes = w.HGLOBAL,
    GlobalUnlock.restype = w.BOOL
    
    GlobalSize = k32.GlobalSize
    GlobalSize.argtypes = w.HGLOBAL,
    GlobalSize.restype = w.ctypes.c_size_t
    
    unicode_type = type(u'')
    
    def get():
        text = None
        OpenClipboard(None)
        handle = GetClipboardData(CF_UNICODETEXT)
        pcontents = GlobalLock(handle)
        size = GlobalSize(handle)
        if pcontents and size:
            raw_data = ctypes.create_string_buffer(size)
            ctypes.memmove(raw_data, pcontents, size)
            text = raw_data.raw.decode('utf-16le').rstrip(u'\0')
        GlobalUnlock(handle)
        CloseClipboard()
        return text
    
    def put(s):
        if not isinstance(s, unicode_type):
            s = s.decode('mbcs')
        data = s.encode('utf-16le')
        OpenClipboard(None)
        EmptyClipboard()
        handle = GlobalAlloc(GHND, len(data) + 2)
        pcontents = GlobalLock(handle)
        ctypes.memmove(pcontents, data, len(data))
        GlobalUnlock(handle)
        SetClipboardData(CF_UNICODETEXT, handle)
        CloseClipboard()
    
    #Test run
    paste = get
    copy = put
    copy("Hello World!")
    print(paste())
    
    0 讨论(0)
提交回复
热议问题