首页 文章

如何使用Tkinter并允许我的应用程序保持焦点?

提问于
浏览
2

我有一个小应用程序,用户可以作为命令行进行交互 . 我希望用户能够复制到应用程序刚刚在屏幕上显示的Windows剪贴板信息 . 显然,用户可以手动执行此操作,但需要几个步骤:右键单击窗口,选择“标记”,选择文本矩形,然后按Enter键复制它 . 我希望允许用户通过键入“cb”或“copy”之类的简短命令自动执行此操作 .

根据this answer,获取剪贴板功能的一种简单方法是使用tkinter库 . 这确实很有效 . 但是,我发现当我的应用程序启动时,它会失去焦点 . 似乎隐藏的窗口(由 Tk() 打开,然后由 withdraw() 隐藏)有它 . 用 withdraw() 隐藏窗口的行为并未将焦点重新放回我的应用程序 . 这是不方便的,因为打开应用程序后,用户必须手动切换回它而不是只能开始键入 .

我想创建一个tkinter对象,并在隐藏新窗口后将焦点返回给我的应用程序,或者让我的应用程序首先不会失去焦点 . 我怎样才能做到这一点?

已经有各种与tkinter和焦点相关的问题,但它们似乎通常与将焦点放在tkinter本身打开的窗口有关,而我希望将注意力集中在我的应用程序的原始窗口上,并将其拒绝到tkinter窗口 .

我在Windows 8机器上工作 .

Pastebin http://pastebin.com/6jsasiNE

1 回答

  • 3

    On Windows NT, Windows Server 2003, and Windows 7+

    您根本不需要使用 Tkinter 来实现目标 .

    clip.py:

    import subprocess
    
    def write_to_clipboard(string):
        p = subprocess.Popen(['clip'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        p.communicate(input=string)
    

    此代码只调用标准的窗口 clip.exe 实用程序,粘贴 string 变量中传递的任何内容 .

    用法:

    from clip import write_to_clipboard
    try:
        while True:
            write_to_clipboard(raw_input())        
    except KeyboardInterrupt:
        pass
    

    On Windows 95, 98, ME, and XP

    这些版本的Windows没有 clip.exe ,所以这里只是一个python版本:

    clip.py:

    import subprocess
    
    def write_to_clipboard(string):
        p = subprocess.Popen(['python', __file__], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        p.communicate(input=string)
    
    if __name__ == "__main__":
        import sys
        from Tkinter import Tk
    
        r = Tk()
        r.withdraw()
        r.clipboard_clear()
        r.clipboard_append(sys.stdin.read())
        r.update()
        r.destroy()
    

    这适用于所有版本的Windows,并且可以支持任何支持 TK 的操作系统 .

    请注意,您必须在这样的单独进程中运行 Tk 代码,因为即使我们调用 r.destroy()Tk 似乎"lock"剪贴板(在此进程退出之前,没有其他进程可以访问剪贴板) .

    Reading and Writing Clipboard

    如果您希望能够从剪贴板中读取并写入,则可以使用此解决方案 .

    clip.py:

    import subprocess
    
    def write(string):
        p = subprocess.Popen(['python', __file__, 'write'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        p.communicate(input=string)
    
    def read():
        p = subprocess.Popen(['python', __file__, 'read'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        return p.communicate()[0]
    
    if __name__ == "__main__":
        import sys
        from Tkinter import Tk
    
        if len(sys.argv) != 2:
            sys.exit(1)
    
        r = Tk()
        try:
            r.withdraw()
            if sys.argv[1] == "write":
                r.clipboard_clear()
                r.clipboard_append(sys.stdin.read())
                r.update()
            elif sys.argv[1] == "read":
                sys.stdout.write(r.clipboard_get()),
            else:
                sys.exit(1)
        finally:
            r.destroy()
    

    用法:

    import clip
    print "clipboard contains: %s" % clip.read()
    

相关问题