【问题标题】:Python / Tkinter - Select and copy all Text contents to clipboard on Button click from another functionPython / Tkinter - 从另一个功能单击按钮时选择所有文本内容并将其复制到剪贴板
【发布时间】:2021-01-22 20:46:34
【问题描述】:

在过去的几天里,我刚开始自学 Python 以进行一些应用程序编程,并且之前有使用 PHP 开发网站的经验。我一直在构建一个程序,它将解析信息列表,构建收集的变量数组,然后在新的 Tkinter Toplevel 窗口中加载并使用这些变量填充 html 模板。新窗口由根窗口中的菜单栏命令调用的函数创建。它只包含一个带有滚动条和几个按钮的文本框,应该允许用户选择所有文本,将其复制到剪贴板,然后关闭窗口。

我遇到的问题,我敢肯定这对于精通 Python 的人来说可能是一个简单的解决方法,就是我不知道在从其他函数中调用 select 和 copy 函数时如何正确引用所有内容职能。如果我像只在一个窗口外工作一样剥离代码,一切都会按预期工作:

import tkinter as tk

def clipit():
    textpop.clipboard_clear()
    textpop.event_generate("<<TextModified>>")
    textpop.clipboard_append(textarea.get('1.0', 'end'))
    textpop.update()
    
def textselect():
    textpop.event_generate("<<TextModified>>")
    textarea.tag_add('sel', "1.0", 'end-1c')

textpop = tk.Tk()
textarea = tk.Text(textpop, wrap="none")
textarea.pack(side="left", fill="both", padx=20, pady=20)
textarea.insert("1.0", "This is a test - Try to select all and copy!")
exitbutton = tk.Button(textpop, text="Close", command = textpop.destroy)
exitbutton.pack(side="right", padx=(5,20), pady=(0,20))
copybutton = tk.Button(textpop, text="Copy", command = clipit)
copybutton.pack(side="right",padx=5, pady=(0,20))
selectbutton = tk.Button(textpop, text="Select All", command = textselect)
selectbutton.pack(side="right",padx=5, pady=(0,20))
textarea.focus()
textpop.mainloop()

如果我尝试做同样的事情,但在一个函数内(其中 textpop = tk.Toplevel()),它就不再起作用了。我尝试传递对函数(父、小部件等)的各种引用并相应地修改函数代码,但没有任何运气让它工作。例如:

import tkinter as tk

def clipit(parent,textwidget):
    parent.clipboard_clear()
    parent.event_generate("<<TextModified>>")
    parent.clipboard_append(textwidget.get('1.0', 'end'))
    parent.update()
    
def textselect(parent,textwidget):
    parent.event_generate("<<TextModified>>")
    parent.textwidget.tag_add('sel', "1.0", 'end-1c')

def textwindow(title,content):
    textpop = tk.Toplevel()
    textpop.title(title)
    textarea = tk.Text(textpop, wrap="none")
    textarea.pack(side="left", fill="both", padx=20, pady=20)
    textarea.insert("1.0", content)
    exitbutton = tk.Button(textpop, text="Close", command = textpop.destroy)
    exitbutton.pack(side="right", padx=(5,20), pady=(0,20))
    copybutton = tk.Button(textpop, text="Copy", command = lambda: clipit(textpop,textarea))
    copybutton.pack(side="right",padx=5, pady=(0,20))
    selectbutton = tk.Button(textpop, text="Select All", command = lambda: textselect(textpop,textarea))
    selectbutton.pack(side="right",padx=5, pady=(0,20))
    textarea.focus()
    textpop.mainloop()

window = tk.Tk()
window.title("Main Window")
launchbutton = tk.Button(window, text = "Launch Window", command = lambda: textwindow("Toplevel Popup", "Text Area Text"))
launchbutton.pack(padx=20,pady=20)
window.mainloop()

在我的主脚本(和此示例代码)中,单击全选按钮会导致以下错误:

AttributeError: 'Toplevel' 对象没有属性 'textwidget'

是否有一些简单的东西我只是因为我是语言新手而错过了?

编辑:为了清楚起见,根据 Bryan 的评论修改了第二个示例。

【问题讨论】:

  • 什么是" 它不再起作用了。" 是什么意思?你有错误吗?它会选择错误的东西吗?还有什么?最后一行代码是您的实际代码吗?你读过以下内容吗? stackoverflow.com/q/5767228/7432
  • 当我说它不再起作用时,我的意思是它要么什么都不做(没有错误,没有文本选择),要么我得到一个错误,因为我尝试了一些无效的东西语法或有不正确的参考(通常 AttributeError 说我做了一个错误的参考)。这个例子是我尝试过的许多事情之一。没有意识到这个命令只能接受一个引用而不传递任何东西。在我的完整脚本中更改它并再次尝试该示例会给我 AttributeError: 'Toplevel' object has no attribute 'textwidget' - 我将更新示例中的命令参考。
  • 用更完整的脚本更新了第二个示例,以便于故障排除,并包含对按钮命令的更改。

标签: python function tkinter reference toplevel


【解决方案1】:

在构建功能示例脚本以帮助人们为我解决此问题的过程中,我想我找到了罪魁祸首:

parent.textwidget.tag_add('sel', '1.0', 'end-1c')

看起来我的引用可能有点过于具体,因为删除尝试的父引用修复了选择 textwidget 内容的问题。我还必须为 textwidget 添加一个焦点调用以使其工作,我也将其放入函数中:

def textselect(parent,textwidget):
    parent.event_generate("<<TextModified>>")
    textwidget.focus()
    textwidget.tag_add('sel', '1.0', 'end')

一旦我完成了所有工作,我也意识到选择文本无论如何都是多余的,更多的是视觉上的事情,因为复制功能将复制文本框的全部内容,无论它是否突出显示。

不是 100% 确定这是完成这一切的最佳方式,但它确实有效。如果有人有更好的方法,欢迎留言!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-26
    • 2014-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多