0

I want to change a number from a matrix and then display it in the same tk window, but I find it hard to work with variables from an input. The r[][] should be the matrix formed with the user's input. And after all I have to display the matrix with the modification: r[0][1] += 5, in the same tk window.

from tkinter import *
import numpy as np

root = Tk()

def process():
    values = [e1.get(),e2.get(),e3.get(),e4.get()]

    a = np.zeros((2,2),dtype=np.int64)

    for i in range(2):
        for j in range(2):
                a[i][j] = values[i*2+j]
    print(a)

e1 = Entry(root)
e2 = Entry(root)
e3 = Entry(root)
e4 = Entry(root)

e1.grid(row=0,column=0,padx=10,pady=10)
e2.grid(row=0,column=1)
e3.grid(row=1,column=0,padx=10,pady=10)
e4.grid(row=1,column=1)

b = Button(root,text='Process',command=process)
b.grid(row=2,column=0,columnspan=4,sticky=E+W)

root.mainloop()

r=[[e1.get(),e2.get()],[e3.get(),e4.get()]]
r[0][1] += 5 
martineau
  • 119,623
  • 25
  • 170
  • 301

2 Answers2

1

Tkinter GUI programs are event-driven which requires using a different programming paradigm than the one you're probably familiar with which is called imperative programming. In other words, just about everything that happens is done in response to something the user has done, like typing on the keyboard, clicking on a graphical button, moving the mouse, etc.

I think the code below will give you a good idea of how to do what you want in a framework like that. It creates a StringVar for each Entry widget, which has the advantage what's displayed in each Entry will automatically be updated whenever the corresponding StringVar is changed (make that more-or-less automatic).

To determine which StringVar is associated with a given Entry, a separate dictionary is created which maps the internal tkinter variable name to corresponding Python variable. The internal tkinter variable name is obtained by using the universal cget() widget method.

import tkinter as tk
from tkinter.constants import *

ROWS, COLS = 2, 2

def process(entry_widgets, row, col):
    var_name = entry_widgets[row][col].cget('textvariable')
    var = root.variables[var_name]
    try:
        value = float(var.get())
    except ValueError:  # Something invalid (or nothing) was entered.
        value = 0
    var.set(value+5)  # Update value.


root = tk.Tk()

# Create a grid of Entry widgets.
entries = []
root.variables = {}  # To track StringVars.

for x in range(COLS):
    row = []
    for y in range(ROWS):
        var = tk.StringVar(master=root)  # Create variable.
        root.variables[str(var)] = var  # Track them by name.
        entry = tk.Entry(root, textvariable=var)
        entry.grid(row=x, column=y)
        row.append(entry)
    entries.append(row)


btn = tk.Button(root, text='Process', command=lambda: process(entries, 0, 1))
btn.grid(row=2, column=0, columnspan=COLS, sticky=E+W)

root.mainloop()

martineau
  • 119,623
  • 25
  • 170
  • 301
  • 1
    Is it necessary to use `StringVar` here? – Delrius Euphoria Oct 26 '21 at 05:31
  • 1
    @Cool: It's not essential, but I find using them in conjunction with an `Entry` widget often makes it easier to update their contents, which is a slightly more involved than simply calling the Variable's `set()` method — see [How to set the text/value/content of an `Entry` widget using a button in tkinter](https://stackoverflow.com/questions/16373887/how-to-set-the-text-value-content-of-an-entry-widget-using-a-button-in-tkinter). – martineau Oct 26 '21 at 18:22
-2

Would this be what you're looking for? I deleted a bunch of code that seems to do nothing in context -- you just want to replace the text in the corner box right?

from tkinter import *

def process():
    replace(e4)

def replace(entry_loc):
    temp = int(entry_loc.get())
    temp += 5
    entry_loc.delete(0,500)
    entry_loc.insert(0, temp)
    
root = Tk()

var_e1 = StringVar
var_e2 = StringVar
var_e3 = StringVar
var_e4 = StringVar
e1 = Entry(root, textvariable=var_e1)
e2 = Entry(root, textvariable=var_e2)
e3 = Entry(root, textvariable=var_e3)
e4 = Entry(root, textvariable=var_e4)

e1.grid(row=0, column=0, padx=10, pady=10)
e2.grid(row=0, column=1)
e3.grid(row=1, column=0, padx=10, pady=10)
e4.grid(row=1, column=1)

b = Button(root, text='Process', command=process)
b.grid(row=2, column=0, columnspan=4, sticky=E + W)

root.mainloop()
  • 2
    `var_e1 = StringVar` doesn't do what you think it does. It needs to be `var_e1 = StringVar()`. Though, the use of `StringVar` is completely useless in this code. – Bryan Oakley Oct 25 '21 at 20:09