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

Python/Tkinter-从另一个函数中单击按钮时选择所有文本内容并将其复制到剪贴板,python,function,tkinter,reference,toplevel,Python,Function,Tkinter,Reference,Toplevel,在过去的几天里,我刚刚开始自学Python来做一些应用程序编程,并且有过使用PHP开发网站的经验。我一直在构建一个程序,该程序将解析一个信息列表,构建一个收集的变量数组,然后在一个新的Tkinter顶级窗口中加载并填充一个html模板。新窗口由根窗口中的菜单栏命令调用的函数创建。它只包含一个带有滚动条和几个按钮的文本框,用户可以选择所有文本,将其复制到剪贴板,然后关闭窗口 我遇到的问题是,我相信对于精通Python的人来说,这可能是一个简单的解决方案,那就是在从其他函数中调用select和cop

在过去的几天里,我刚刚开始自学Python来做一些应用程序编程,并且有过使用PHP开发网站的经验。我一直在构建一个程序,该程序将解析一个信息列表,构建一个收集的变量数组,然后在一个新的Tkinter顶级窗口中加载并填充一个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()
将tkinter作为tk导入
def clipit():
textpop.clipboard_clear()
textpop.event_generate(“”)
textpop.clipboard_append(textarea.get('1.0','end'))
textpop.update()
def textselect():
textpop.event_generate(“”)
textarea.tag_add('sel','1.0','end-1c'))
textpop=tk.tk()
textarea=tk.Text(textpop,wrap=“无”)
textarea.pack(side=“left”,fill=“both”,padx=20,pady=20)
插入(“1.0”,“这是一个测试-尝试全选并复制!”)
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=“全选”,command=textselect)
选择Button.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()
将tkinter作为tk导入
def clipit(父项,文本小部件):
parent.clipboard_clear()
parent.event_generate(“”)
parent.clipboard\u append(textwidget.get('1.0','end'))
parent.update()
def textselect(父级,文本小部件):
parent.event_generate(“”)
parent.textwidget.tag_add('sel','1.0','end-1c'))
def文本窗口(标题、内容):
textpop=tk.Toplevel()
textpop.title(title)
textarea=tk.Text(textpop,wrap=“无”)
textarea.pack(side=“left”,fill=“both”,padx=20,pady=20)
textarea.insert(“1.0”,内容)
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=“全选”,command=lambda:textselect(textpop,textarea))
选择Button.pack(side=“right”,padx=5,pady=(0,20))
textarea.focus()
textpop.mainloop()
window=tk.tk()
窗口名称(“主窗口”)
launchbutton=tk.Button(窗口,text=“启动窗口”,命令=lambda:textwindow(“顶级弹出窗口”,“文本区域文本”))
launchbutton.pack(padx=20,pady=20)
window.mainloop()
在我的主脚本(以及本示例代码)中,单击全选按钮将导致以下错误:

AttributeError:“Toplevel”对象没有属性“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')
def textselect(父项,textwidget):
parent.event_generate(“”)
textwidget.focus()
textwidget.tag_add('sel','1.0','end')
一旦一切正常,我也意识到选择文本无论如何都有点多余,更像是一件视觉上的事情,因为无论文本框是否高亮显示,复制功能都会复制文本框的全部内容


不是100%确定这是实现所有这一切的最佳方式,但它是有效的。如果有人有更好的方法,请随意发布

“它不再工作了”是什么意思?你有错误吗?它选错东西了吗?还有别的吗?最后一行代码是你的实际代码吗?你读过下面的内容吗?当我说它不再工作时,我的意思是它要么什么也不做(没有错误,没有文本选择),要么我得到了一个错误,因为我尝试了一些无效的语法或有一个错误的引用(通常AttributeError说我做了一个错误的引用)。这个例子是我尝试过的许多事情之一。我没有意识到命令只能接受一个引用而不传递任何内容。在我的完整脚本中更改它,然后再次尝试该示例,会得到AttributeError:“Toplevel”对象没有属性“textwidget”-我将更新示例中的命令引用。使用更完整的脚本更新了第二个示例,以便于故障排除,并包括对按钮命令的更改。