简体   繁体   English

如何设置 ttk.Entry 的文本?

[英]How can I set the text of a ttk.Entry?

It appears that I cannot set the text of a ttk.Entry with a root of ttk.Label during an event:看来我无法在事件期间设置具有ttk.Entry根的ttk.Label的文本:

import tkinter
from tkinter import ttk

def modify_label_text(event):
    entry = event.widget
    newvalue = entry.get()
    label = entry.master
    label.configure(text=newvalue)
    entry.unbind("<Return>")
    entry.pack_forget()
    label.focus()

def create_entry(event):
    label = event.widget
    oldvalue = label.cget("text")
    newvalue = tkinter.StringVar()
    entry = ttk.Entry(label, textvariable=newvalue)
    '''
    entry = tkinter.Entry(label, textvariable=newvalue)
    '''
    entry.pack()
    entry.delete(0, "end")
    entry.insert(0, oldvalue)
    entry.bind("<Return>", modify_label_text)
    entry.focus()

root = tkinter.Tk()

clickme = ttk.Label(root, width=16)
clickme.pack()

clickme.bind("<Button-1>", create_entry)
clickme.focus()

root.mainloop()

When I click the empty label and enter a new value, the value is reflected in the label.当我点击空的 label 并输入一个新值时,该值反映在 label 中。 However, if I click the label again to "edit" the value, the entry field is empty again.但是,如果我再次单击 label 以“编辑”该值,则输入字段再次为空。

Furthermore, if I use tkinter.Entry rather than ttk.Entry , it appears to work.此外,如果我使用tkinter.Entry而不是ttk.Entry ,它似乎可以工作。

Why is the text of the entry only set when using tkinter.Entry ?为什么只有在使用tkinter.Entry时才设置条目的文本? How can I fix this to work with ttk.Entry ?如何解决此问题以与ttk.Entry一起使用?

I suggest you create an instance of Entry outside the function and simply pack() and pack_forget() in the function.我建议你在 function 之外创建一个 Entry 实例,然后在 function 中简单地进行pack()pack_forget() pack_forget() will not delete your widget it will only hide it from the layout. pack_forget()不会删除您的小部件,只会将其从布局中隐藏。 To delete the widget you might have to use widget.destroy() .要删除小部件,您可能必须使用widget.destroy()

import tkinter
from tkinter import ttk

def modify_label_text(event):
    newvalue = entry.get()
    clickme.configure(text=newvalue)
    entry.pack_forget()
    clickme.focus()

def create_entry(event):
    label = event.widget
    entry.pack()
    entry.focus()


root = tkinter.Tk()

newvalue = tkinter.StringVar()

clickme = ttk.Label(root, width=16)
clickme.pack()

clickme.bind("<Button-1>", create_entry)
clickme.focus()

entry = ttk.Entry(clickme, textvariable=newvalue)
entry.bind("<Return>", modify_label_text)

root.mainloop()

Edit(writing my comment as answer)编辑(写我的评论作为答案)

I suspect that it has to do something with the textvariable being set.我怀疑它必须与设置的文本变量有关。 Simply removing it or changing the newvalue to global scope seems to work.只需将其删除或将新值更改为全局 scope 似乎可行。 Also, since you don't seem to be using .set or .get methods you can simply remove it if you want.此外,由于您似乎没有使用.set.get方法,因此您可以根据需要简单地将其删除。

This may not an answer, but a bit too large for a comment .这可能不是答案,但对于评论来说有点太大了 Also could someone elaborate this behavior in a different enviorment.也有人可以在不同的环境中详细说明这种行为。 I ran that code with:我使用以下代码运行该代码:

Mashine:玛修:

Windows 10 Home; x64-base,Intel(R) Core(TM) i3-2120 @ 3.30GHz, 3300 MHz, 2Cores

with

Python 3.7.2 and tkinter 8.6

After some research I couldnt find a reason for this behavior.经过一些研究,我找不到这种行为的原因。 Neither in the docs , nor in the sometimes tricky style_map or in the default bindings .既不在文档中,也不在有时棘手的style_map默认绑定中。

Can I assume that you create the labels with the entries in a function/loop?我可以假设您使用函数/循环中的条目创建标签吗? You may want to reuse the entry, because for some reason the exact same code works if you adress the entry by winfo_children() .您可能希望重用该条目,因为由于某种原因,如果您通过winfo_children()对条目进行寻址,则完全相同的代码可以工作。 And even if I call .update_idletasks() or just for experience the evil .update() it dosent work for no reason.即使我调用.update_idletasks()或只是为了体验邪恶的.update()它也无缘无故地工作。

import tkinter
from tkinter import ttk

def modify_label_text(event):
    entry = event.widget
    newvalue = entry.get()
    label = entry.master
    label.configure(text=newvalue)
    entry.unbind("<Return>")
    entry.pack_forget()
    label.focus()

def create_entry(event):
    label = event.widget
    oldvalue = label.cget("text")
    newvalue = tkinter.StringVar()
    if len(label.winfo_children()) == 0:
        print('new')
        entry = ttk.Entry(label, textvariable=newvalue)
    '''
    entry = tkinter.Entry(label, textvariable=newvalue)
    '''
    e = label.winfo_children()[0]
    e.pack()
    e.delete(0, "end")
    e.insert(0, oldvalue+' works')
    e.bind("<Return>", modify_label_text)
    e.focus()

root = tkinter.Tk()

clickme = ttk.Label(root, width=16)
clickme.pack()

clickme.bind("<Button-1>", create_entry)
clickme.focus()

root.mainloop()

Another solution could be:另一种解决方案可能是:

def create_entry(event):
    label = event.widget
    oldvalue = label.cget("text")
    newvalue = tkinter.StringVar()
    entry = ttk.Entry(label, textvariable=newvalue)
    '''
    entry = tkinter.Entry(label, textvariable=newvalue)
    '''
    root.after(100,after_time,entry,oldvalue)

def after_time(entry,oldvalue):    
    entry.pack()
    entry.delete(0, "end")
    entry.insert(0, oldvalue)
    entry.bind("<Return>", modify_label_text)
    entry.focus()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM