Displaying result in tkinter interface - python

I'm trying to use only tkinter interface to display the result, knowing I use the lists in my program.
Here is the code :
NM =int(input("give the value of NM \n"))
n = int(input("give the value of n \n"))
def function(NM,n):
Z=[]
for x in range(NM):
F=float(input("give the value of F"+str(x+1)+"\n"))
H=float(input("give the value of H"+str(x+1)+"\n"))
v=F/H
Z.append(v)
s=0
for i in range(len(Z)):
s+=float(Z[i])
return (1/n)*s`

If you are trying to show something with Tkiner maybe you can try this:
from tkinter import *
#creates your root widget.
root = Tk()
#creates a label so you can show your result, .path() method makes your label always stay in the center of your widget.
Label(root, text = your_result).pack()
#allows you to see your widget.
root.mainloop()

Related

A calculator using tkinter library

I want to have a calculator with 4 buttons and 2 entry. What is my problem? I don't know how to fix that it can't multiply sequence by non-int of type str nor can't multiply entry * entry.
Also I don't know where is my output and how use that.
from tkinter import ttk
from tkinter import *
import tkinter as tk
#the environment
calc=tk.Tk()
calc.title("Calculator")
#-------------------------------------
#lables and their data entry
tk.Label(calc,text="enter your first number:").grid(row=0)
tk.Label(calc,text="enter your second number:").grid(row=1)
e1=tk.Entry(calc)
e2=tk.Entry(calc)
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
x1=e1.get()
x2=e2.get()
tk.Label(calc,text="your result is:").grid(row=3)
# a free variable for get output,is this really need?
lbl=list()
#---------------------------
#the functions but my entry are entry type
def prod():
lbl=print(x1*x2)
def div():
lbl=print(x1/x2)
def sum():
lbl=print(x1+x2)
def min():
lbl=print(x1-x2)
#-------------------------------
#buttons and function in them as a command
btn1=tk.Button(calc,text="*",command=prod()).grid(row=0,column=2)
btn2=tk.Button(calc,text="/",command=div()).grid(row=1,column=2)
btn3=tk.Button(calc,text="+",command=sum()).grid(row=2,column=2)
btn4=tk.Button(calc,text="-",command=min()).grid(row=3,column=2)
#--------------------------------------------------------------------
#The answer which i need it
print("your answer is:")
calc.mainloop()
In GUI programming, you need to get the value of widgets at the time you need them, not at the time you create them.
Also, widgets return string values. If you are doing math on them, you need to convert them to numbers first.
If you want to display the result in the window, you can update a label widget with the configure method
For example, your prod definition could look something like this:
def prod():
x1 = int(e1.get())
x2 = int(e2.get())
result = x1 * x2
result_label.configure(text=str(result))
You then need to do two other things. First, you need to create the label for the result, and store the widget in a variable. To do that you must separate the creation of the widget from the layout since calling grid would cause the variable to be set to None
result_label = tk.Label(calc,text="your result is:")
result_label.grid(row=3)
Finally, your buttons need to be given a reference to the function. What you're currently doing is calling the function and assigning the result to the command attribute.
Your button should look like the following. Notice that prod does not have () after it:
btn1 = tk.Button(calc, text="*", command=prod)
...
btn1.grid(row=0,column=2)
On a side note, I think that for all widgets with a common parent, grouping all widget creation code together and then all calls to grid or pack together makes the code easier to read, easier to maintain, and easier to visualize.
For example:
btn1 = tk.Button(...)
btn2 = tk.Button(...)
btn3 = tk.Button(...)
btn4 = tk.Button(...)
btn1.grid(row=0,column=2)
btn2.grid(row=1,column=2)
btn3.grid(row=2,column=2)
btn4.grid(row=3,column=2)

Certain label wont work with .grid() function from tkinter

It seems that I explained my problem very terribly, but I have a problem with the grid function on my label. The label does show up but, I cant change the row/column of it or do any function inside of the brackets.
I put the code of how to replicate the problem there. Putting anything inside of the .grid() brackets does nothing as stated earlier
from tkinter import *
root = Tk()
#To actually see that it does not work
root.geometry("800x600")
Var = StringVar()
Label = Label(root, textvariable=Var)
#Location of problem, adding stuff into the brackets does not change anything. For example: sticky = "ne"
Label.grid()
Var.set("Ha")
root.mainloop()
To get the label to show up on the right side, you can specify the number of columns in the grid and then place the label in the last column. For example, try adding this just after your "#Location of problem" comment:
cols = 0
while cols < 4:
root.columnconfigure(cols, weight=1)
cols += 1
Label.grid(column=3)

Tkinter Dynamic Dictionary for Matrix- Cant use .get method on entry windows

I have been working on a program which can generate a matrix of a user-defined size, and can then perform operations on the matrix. The program is divided into a few parts.
First, the user enters the rows and columns, which, when submitted, will open a tkinter window with a matrix of entry boxes.
Each of these entry boxes is a value in a dynamic entries dictionary. The lists gridrows and gridcols are used to give coordinates for the .grid method for arranging the entry boxes.
The issue I am having is assigning a command to get the user input after typing their values into the matrix. I have tried creating a function storevals which will append all matrix entries to the matrixinput list.
When I run this program, I get the the matrix entry window, and after typing in the values into each box of the matrix, I get the same error message from line 50: AttributeError:"NoneType" object has no attribute "get". It appears that the entry boxes have no type, which seems to be lost after the .grid arranging of the windows.
Is there any way to assign the user entries in these windows to a list? Any help would be hugely appreciated.
Thanks!
from matplotlib import pyplot as plt
from tkinter import *
#Take user input for matrix size and store in matrixrows and matrixcols variables as integers.
master = Tk()
master.title("Matrix Size")
Label(master, text = "Rows").grid(row=0)
Label(master, text = "Columns").grid(row=1)
def storevals():
matrixrows.append(int(rows.get()))
matrixcols.append(int(cols.get()))
master.quit()
matrixrows = []
matrixcols = []
rows = Entry(master)
cols = Entry(master)
rows.grid(row = 0, column = 1)
cols.grid(row =1, column = 1)
Button(master, text= "Enter", command = storevals).grid(row=3, column =0, sticky=W, pady=4)
mainloop()
norows = matrixrows[0]
nocols = matrixcols[0]
matrixlist =[]
for i in range(0,norows):
matrixlist.append([])
for i in range(0,norows):
for j in range(0,nocols):
matrixlist[i].append(nocols*0)
#Generate a matrix entry window with entries correpsonding to the matrix
master2 = Tk()
master2.title("Enter Matrix Values")
matrixinput=[]
def storevals():
for key in entries:
matrixinput.append(entries[key].get())
print(matrixinput)
Button(master2, text= "Submit Matrix", command = storevals).grid(row=norows+1, column =round(nocols/2), sticky=W, pady=4)
gridrows=[]
gridcols=[]
#creates two lists, gridcols and gridrows which are used to align the entry boxes in the tkinter window
for i in range(0,norows):
for j in range(0,nocols):
gridrows.append(i)
for i in range(0,norows):
for j in range(0,nocols):
gridcols.append(j)
entries ={}
for x in range(0,nocols*norows):
entries["Entrybox{0}".format(x)]=Entry(master2).grid(row=gridrows[x], column=gridcols[x])
print(entries)
mainloop()
You probably haven't looked at the content of entries, that you print just before mainloop()
entries ={}
for x in range(0,nocols*norows):
entries["Entrybox{0}".format(x)]=Entry(master2).grid(row=gridrows[x], column=gridcols[x])
print(entries)
grid(), pack() and place() all return None.
If you want to keep the widget you need to assign it to a variable and then call grid().
entries ={}
for x in range(0,nocols*norows):
widget = Entry(master2)
widget.grid(row=gridrows[x], column=gridcols[x])
entries["Entrybox{0}".format(x)] = widget
print(entries)

What is the pythonic way to display a grid?

I am learning Python and I want to display buttons in a grid. The below code produces exactly what I want, but the code for displaying the buttons by incrementing x and y does not seem very Pythonic. (I come from a procedural language background) Is there a better way? Thanks for any help.
from tkinter import *
from tkinter import ttk
root = Tk()
numberButtonsFrame = ttk.Frame(root)
numberButtonsFrame.pack()
button=[0]
for i in range(1,10):
button.append (ttk.Button(numberButtonsFrame, text = i))
x=0
y=0
for i in range(1,10):
button[i].grid(row=x,column=y)
y=y+1
if y>2:
x=x+1
y=0
root.mainloop()
When you're dealing with a grid, the solution is very often to use nested loops:
for row in in range(nrows):
for col in range(ncolumns):
buttons[row][col].grid(row=row, column=col) # You could also calculate a linear index if that's what you want
Single loop
As I noted in a comment (along with another poster), there is a way of calculating the row and column based on i (and vice versa).
row, col = divmod(i, ncolumns)
You could do this at the same time as you create each button. You could also simplify the button creation with a list comprehension.
buttons = [ttk.Button(numberButtonsFrame, text = i) for i in range(1,10)]
I assume you added the 0 at the start of your button(s) list to shift the indices: you don't have to do that. Just add 1 to i in your calculations instead.
Lastly, I would recommend using well-named variables rather than literals (eg. ncolumns). And buttonsinstead of button for the list. I'll conclude with an example (// is floor division - the div in divmod):
for i, button in enumerate(buttons):
button.grid(row=i//ncolumns, column=i%ncolumns)
Use the divmod() function to calculate each row and column from the index.
buttons_per_row = 3
for i in range(9):
button = ttk.Button(numberButtonsFrame, text = i+1)
row, col = divmod(i, buttons_per_row)
button.grid(row=row, column=col)
A different method...
Using two nested loops like others have done, you can calculate the text from the row and column simply by:
(r * 3) + c + 1
Obviously, this will return an int so str() will have to be applied -leading to a more succinct solution of:
from tkinter import *
from tkinter import ttk
root = Tk()
numberButtonsFrame = ttk.Frame(root)
numberButtonsFrame.pack()
for r in range(3):
for c in range(3):
ttk.Button(numberButtonsFrame, text=(r * 3) + c + 1).grid(row=r, column=c)
root.mainloop()

Python tkinter create buttons with loop and edit their parameters

I'm making a program with Tkinter where I'd need to use a "for i in range" loop, in order to create 81 Text Widgets named like :
Text1
Text2
Text3
...
and dispose them in a square (actually to make a grill for a sudoku game of a 9*9 size). After I created these 81 Text Widgets I need to place them (using .place() ) and entering their position parameters.
After this, I will need to collect the values that the user entered in these Text Widgets.
I'm a newbie and I don't really know how to code this.
Here is my actual code but the problem is I can't modify the parameters once the dictionnary is created and i don't know how to access to the Text Widgets parameters. Maybe using a dictionnary is not the appropriate solution to do what I want.
d = {}
Ypos = 100
for i in range(9):
Xpos = 100
for j in range(9):
d["Text{0}".format(i)]= Text(window, height=1, width=1,relief = FLAT,font=("Calibri",16))
d["Text{0}".format(i)].place(x = Xpos+,y = Ypos)
Xpos += 35
yPos += 35
Thanks for helping
Don't use a complex key for the dictionary, it makes the code more complex without adding any benefit.
Since you're creating a grid, use row and column rather than i and j. This will make your code easier to understand. Also, don't use place if you're creating a grid. Tkinter has a geometry manager specifically for creating a grid.
Since you're creating a text widget with a height of one line, it makes more sense to use an entry widget.
Here's an example:
import Tkinter as tk
root = tk.Tk()
d = {}
window = tk.Frame(root, borderwidth=2, relief="groove")
window.pack(fill="both", expand=True)
for row in range(9):
for column in range(9):
entry = tk.Entry(window, width=1, relief="flat", font=("Calibri",16))
entry.grid(row=row, column=column, sticky="nsew")
d[(row,column)] = entry
root.mainloop()
Whenever you need to access the data in a cell, you can use the row and column easily:
value = d[(3,4)].get()
print("row 3, column 4 = %s" % value)

Categories

Resources