0
import tkinter as tk

class App(tk.Frame):

    def __init__(self):
        super().__init__()
        self.pack()
        self.buttons = []
        self.entries = []

        for n_row in range(20):
            button = tk.Button(self, text='disable')
            button.grid(row=n_row, column=1)
            entry = tk.Entry(self)
            entry.grid(row=n_row, column=0, pady=(10,10))
            self.entries.append(entry)
            self.buttons.append(button)
#each button must activate / deactivate the entry of the same row

if __name__ == '__main__':

    root = tk.Tk()
    app = App()
    root.mainloop()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685

3 Answers3

1

You will want to use lambda here to keep the correct index value for each of the entry fields.

You can use the value of n_row to keep track of what button links to what entry.

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.entries = []
        for n_row in range(20):
            self.entries.append(tk.Entry(self))
            self.entries[-1].grid(row=n_row, column=0, pady=(10,10))
            tk.Button(self, text='disable', command=lambda i=n_row: self.disable_entry(i)).grid(row=n_row, column=1)

    def disable_entry(self, ndex):
        self.entries[ndex]['state'] = 'disabled'


if __name__ == '__main__':
    App().mainloop()

For switching between both states you can use the same method to check if the state is one thing and then change it to another.

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.entries = []
        self.buttons = []
        for n_row in range(20):
            self.entries.append(tk.Entry(self))
            self.buttons.append(tk.Button(self, text='disable', command=lambda i=n_row: self.toggle_state(i)))
            self.entries[-1].grid(row=n_row, column=0, pady=(10, 10))
            self.buttons[-1].grid(row=n_row, column=1)

    def toggle_state(self, ndex):
        if self.entries[ndex]['state'] == 'normal':
            self.entries[ndex]['state'] = 'disabled'
            self.buttons[ndex].config(text='Enable')
        else:
            self.entries[ndex]['state'] = 'normal'
            self.buttons[ndex].config(text='Disable')


if __name__ == '__main__':
    App().mainloop()
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79
1

Question: A Button that activate / deactivate the entry in the same Row

Define your own widget which combines tk.Button and tk.Entry in a own tk.Frame.
The Entry state get toggeld on every click on the Button.

enter image description here


Relevant - extend a tkinter widget using inheritance.


import tkinter as tk


class ButtonEntry(tk.Frame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)

        self.button = tk.Button(self, text='\u2327', width=1, command=self.on_clicked)
        self.button.grid(row=0, column=0)

        self.entry = tk.Entry(self)
        self.columnconfigure(1, weight=1)
        self.entry.grid(row=0, column=1, sticky='ew')

    def on_clicked(self):
        b = not self.entry['state'] == 'normal'
        state, text = {True: ('normal', '\u2327'), False: ('disabled', '\u221A')}.get(b)
        self.entry.configure(state=state)
        self.button.configure(text=text)

Usage:


class App(tk.Tk):
    def __init__(self):
        super().__init__()

        for row in range(5):
            ButtonEntry(self).grid(row=row, column=1)


if __name__ == '__main__':
    App().mainloop()

Tested with Python: 3.5 - 'TclVersion': 8.6 'TkVersion': 8.6

stovfl
  • 14,998
  • 7
  • 24
  • 51
-2

You can set the stateof a widget to 'disabled'

from tkinter import *
root = Tk()
entry = Entry(root, state = 'disabled')

To disable an individual item:

entry['state'] = 'disabled'

When you push the button, get it's location in the list, than compare that to the entry in the other list. If they match, change its state.

Nathan
  • 44
  • 1
  • 8