在我的 tkinter 專案中,我使用for回圈為行串列中的每一行創建了一個條目、一個標簽和兩個按鈕。創建時,我還將它們保存在串列中。
現在我的問題是如何訪問它們?例如:如果單擊第 12 行的編輯按鈕,那么我希望能夠獲取第 12 個條目的條目值,或者如果我的用戶單擊串列中第 3 行的洗掉按鈕,那么只有條目,應洗掉所選行的標簽和兩個按鈕。
這是我的代碼:
self.line_loop = []
for line in self.line_list:
self.row_count = 1
self.n_entry = tk.Entry(self.list_frame, justify="center", width=4)
self.n_entry.grid(row=self.row_count, column=0, pady=10, padx=10, ipady=3)
self.text_label = tk.Label(self.list_frame, text=line, anchor="w", justify="left",
wraplengt=701)
self.text_label.grid(row=self.row_count, column=1, pady=10, padx=10, sticky="w")
self.edit_button = tk.Button(self.list_frame, text="Edit", command=self.edit)
self.edit_button.grid(row=self.row_count, column=2, pady=10, padx=10)
self.delete_button = tk.Button(self.list_frame, text="Delete", command=self.edit)
self.delete_button.grid(row=self.row_count, column=3, pady=10, padx=10)
self.line_loop.append(self.n_entry)
self.line_loop.append(self.text_label)
self.line_loop.append(self.edit_button)
self.line_loop.append(self.delete_button)
編輯:這是功能的例子。該代碼應僅適用于單擊的按鈕和鏈接的小部件
def delete(self):
self.n_entry.destroy()
self.text_label.destroy()
self.edit_button.destroy()
self.delete_button.destroy()
def edit(self):
for entry in self.line_loop:
print(entry.get())
我該怎么做?
uj5u.com熱心網友回復:
你的問題在細節上有點粗略,但這里是如何做你想做的事。它利用了您正在使用 tkintergrid幾何管理器這一事實,該管理器跟蹤其控制下的所有小部件的行和列位置。這意味著您可以從中獲取所需的資訊,而不是自己跟蹤。即不需要像self.line_loop串列這樣的東西以及您手動創建的許多其他實體屬性(盡管一般來說,如果做得好,這也是一種可行的方法)。
在回圈中創建小部件時,重要的是要確保傳遞給回呼函式的任何變數的值不在改變回圈每次迭代的變數中,因為它不起作用(請參閱tkinter 在 for 回圈傳遞命令中創建按鈕論據)。
避免該問題的一種常見方法是使用lambda具有已賦予默認值的引數的函式作為“捕獲”回圈變數的當前值的一種方式。在這種情況下,還需要Button分兩步設定小部件的選項,以便將按鈕本身傳遞給關聯的command=回呼函式。
這是一個基于您的問題中的代碼的可運行示例:
import tkinter as tk
class ListEditor:
def __init__(self, list_frame, lines):
self.list_frame = list_frame
self.line_list = lines.splitlines()
self.create_widgets()
def create_widgets(self):
for row, line in enumerate(self.line_list):
entry = tk.Entry(self.list_frame, justify="center", width=4)
entry.grid(row=row, column=0, pady=10, padx=10, ipady=3)
text_label = tk.Label(self.list_frame, text=line, anchor="w",
justify="left", wraplength=701)
text_label.grid(row=row, column=1, pady=10, padx=10, sticky="w")
edit_button = tk.Button(self.list_frame, text="Edit")
edit_button.config(command=lambda widget=edit_button: self.edit(widget))
edit_button.grid(row=row, column=2, pady=10, padx=10)
delete_button = tk.Button(self.list_frame, text="Delete")
delete_button.config(command=lambda widget=delete_button: self.delete(widget))
delete_button.grid(row=row, column=3, pady=10, padx=10)
def _get_widgets_on_same_row(self, widget):
"""Return list of all widgets on same row as given one in column order."""
row = widget.grid_info()['row']
return sorted(widget.master.grid_slaves(row=row),
key=lambda w: w.grid_info()['column'])
def delete(self, widget):
row = widget.grid_info()['row']
widgets = self._get_widgets_on_same_row(widget)
for widget in widgets: # Get rid of associated widgets.
widget.grid_remove()
self.line_list[row] = None # Indicate line was deleted.
def edit(self, widget):
row = widget.grid_info()['row']
entry,text_label,edit_button,delete_button = self._get_widgets_on_same_row(widget)
pass # Whatever you want to do with the linked widgets (and instance data)...
if __name__ == '__main__':
from textwrap import dedent
lines = dedent('''\
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Vivamus et leo id felis faucibus varius quis et risus.
Ut nec felis ut enim tincidunt maximus.
Sed at nunc eleifend, vestibulum dolor nec, dictum tellus.
Aliquam et lorem tincidunt, rhoncus libero sed, molestie massa.
Duis quis nunc maximus, semper justo placerat, posuere turpis.
''')
root = tk.Tk()
list_frame = tk.Frame(root)
list_frame.pack()
editor = ListEditor(list_frame, lines)
root.mainloop()
uj5u.com熱心網友回復:
您必須使用name為小部件創建一個名稱,以便我們以后可以訪問它。
您可以使用root.nametowidget在創建小部件時通過指定的名稱獲取小部件的參考。
編輯:
通過索引的幫助,您將能夠跟蹤單擊該特定按鈕時必須洗掉哪些按鈕和條目。
from tkinter import *
root=Tk()
for i in range(4):
Entry(name=f'entry{str(i)}').pack()
Button(text='get', command=lambda temp=i:edit(temp),name=f'e_button{str(i)}').pack()
Button(text='delete', command=lambda temp=i:delete(temp),name=f'd_button{str(i)}').pack()
def edit(num):
Label(text=root.nametowidget(f'.entry{num}').get()).pack()
def delete(num):
root.nametowidget(f'entry{num}').destroy()
root.nametowidget(f'.e_button{num}').destroy()
root.nametowidget(f'.d_button{num}').destroy()
print('deleted',num)
root.mainloop()
uj5u.com熱心網友回復:
您沒有提供有關您的編輯或洗掉功能的任何詳細資訊,但我猜如果您獲得相應的按鈕來為該功能提供其索引,則該功能可以索引到self.line_list:
self.line_loop = []
for index, line in enumerate(self.line_list):
self.row_count = 1
n_entry = tk.Entry(self.list_frame, justify="center", width=4)
n_entry.grid(row=self.row_count, column=0, pady=10, padx=10, ipady=3)
text_label = tk.Label(self.list_frame, text=line, anchor="w", justify="left", wraplengt=701)
text_label.grid(row=self.row_count, column=1, pady=10, padx=10, sticky="w")
edit_button = tk.Button(self.list_frame, text="Edit", command=lambda x=index: self.edit(x))
edit_button.grid(row=self.row_count, column=2, pady=10, padx=10)
delete_button = tk.Button(self.list_frame, text="Delete", command=lambda x=index: self.delete(x))
delete_button.grid(row=self.row_count, column=3, pady=10, padx=10)
self.line_loop.append((n_entry, text_label, edit_button, delete_button))
def edit(self, index):
n_entry, text_label, edit_button, delete_button = self.line_loop[index]
line = self.line_list[index]
...
我曾經為示例方法enumerate()提供索引self.line_list并使用command=lambda慣用語為示例edit()方法提供索引引數。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/462087.html
