简体   繁体   English

用条目小部件替换python tkinter标签小部件

[英]Replace python tkinter label widget with entry widget

I want to enable double click to edit a label. 我想启用双击来编辑标签。 Is there a way to replace the label, which user double-clicks, with entry widget without destroying it? 有没有一种方法可以用条目窗口小部件替换用户双击的标签而不破坏它? This example lists label widgets and after double-click destroys it and sets entry widget at the end: 此示例列出了标签小部件,双击销毁它,并在最后设置条目小部件:

from tkinter import *
class MainWindow:
    def __init__(self, root):
        self.root = root
        self.tasks = ['text1', 'text2', 'text3']
        self.list_tasks()
    def list_tasks(self):
        self.tasks_frame = Frame(self.root)
        for task in self.tasks:
            task_label = Label(self.tasks_frame, text=task)
            task_label.bind('<Double-Button-1>', self.replace_with_entry)
            task_label.pack()
        self.tasks_frame.pack()
    def replace_with_entry(self, event):
        widget = event.widget
        widget.destroy()
        entry_widget = Entry(self.tasks_frame)
        entry_widget.pack()
root = Tk()
main_window = MainWindow(root)
root.mainloop()

I want entry widget in exactly the same place, where label was. 我希望条目小部件位于标签所在的完全相同的位置。 I think it is possible with grid, but maybe there is a better way? 我认为使用网格是可能的,但是也许有更好的方法?

The simplest solution is not to replace it, but to instead overlay it. 最简单的解决方案不是替换它,而是覆盖它。 This is one circumstance where place is very useful. 这是一种情况,其中place是非常有用的。

For example: 例如:

def replace_with_entry(self, event):
    widget = event.widget
    entry_widget = Entry(widget)
    entry_widget.place(x=0, y=0, anchor="nw", relwidth=1.0, relheight=1.0)
    entry_widget.bind("<Return>", self.remove_entry)
    entry_widget.focus_set()

def remove_entry(self, event):
    entry = event.widget
    label = entry.place_info()["in"]
    label.configure(text=entry.get())
    entry.destroy()

Here is the grid solution. 这是网格解决方案。 I think it is acceptable, but you can wait to see if someone else provides a better solution. 我认为这是可以接受的,但是您可以等待其他人提供更好的解决方案。

from tkinter import *
from functools import partial
class MainWindow:
    def __init__(self, root):
        self.root = root
        self.tasks = ['text1', 'text2', 'text3']
        self.list_tasks()
    def list_tasks(self):
        self.tasks_frame = Frame(self.root)
        for i, task in enumerate(self.tasks):
            task_label = Label(self.tasks_frame, text=task)
            task_label.bind('<Double-Button-1>', partial(self.replace_with_entry, i))
            task_label.grid(row=i, column=0)
        self.tasks_frame.pack()
    def replace_with_entry(self, i, event):
        widget = event.widget
        widget.destroy()
        entry_widget = Entry(self.tasks_frame)
        entry_widget.grid(row=i, column=0)
root = Tk()
main_window = MainWindow(root)
root.mainloop()

I also made another version that uses tkinter variables to include the text from the label in the entry. 我还制作了另一个版本,该版本使用tkinter变量在条目中包含标签中的文本。 It could be modified to allow switching back to the label with the modified text. 可以对其进行修改以允许使用修改后的文本切换回标签。

from tkinter import *
from functools import partial
class MainWindow:
    def __init__(self, root):
        self.root = root
        self.tasks = ['text1', 'text2', 'text3']
        self.list_tasks()
    def list_tasks(self):
        self.tasks_frame = Frame(self.root)
        self.task_widgets = []
        for i, task in enumerate(self.tasks):
            textvar = StringVar()
            textvar.set(task)
            task_label = Label(self.tasks_frame, textvariable=textvar)
            task_label.bind('<Double-Button-1>', partial(self.replace_with_entry, i))
            task_label.grid(row=i, column=0)
            task_entry = Entry(self.tasks_frame, textvariable=textvar)
            self.task_widgets.append((task_label, task_entry, textvar))
        self.tasks_frame.pack()
    def replace_with_entry(self, i, event):
        widget = event.widget
        widget.grid_forget()
        self.task_widgets[i][1].grid(row=i, column=0)

root = Tk()
main_window = MainWindow(root)
root.mainloop()

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

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