Python / Tkinter - Select 并在从另一个函数单击按钮时将所有文本内容复制到剪贴板

Python / Tkinter - Select and copy all Text contents to clipboard on Button click from another function

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

我遇到的问题是我不知道如何在调用 Python 时正确引用所有内容=32=] 并从其他函数中复制函数。如果我剥离代码,就好像我只用了一个 window,一切都按预期工作:

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()

在我的主脚本(和这个示例代码)中,单击 Select All 按钮会导致以下错误:

AttributeError: 'Toplevel' object has no attribute 'textwidget'

是否因为我是该语言的新手而缺少一些简单的东西?

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

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

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% 确定这是完成这一切的最佳方式,但它确实有效。如果谁有更好的方法,欢迎post分享!