Maciek R
Maciek R

Reputation: 3

How to display a list or dictionary line by line and with formatting in text window in tkinter?

I have created a simple program in Tkinter that I want to use to mark students' tests. I give the maximum number of points and the program is supposed to count the points for a specific grade.

I'm able to produce a list or dictionary with grades and required points for these grades but I cannot display it in a way that I can do in regular python (which you can find below and I have added a line which prints the desired result). Here's what I want to get in the text window:

2 do 25 punktów
2+ do 31 punktów
3 do 32 punktów
3+ do 43 punktów
4 do 44 punktów
4+ do 51 punktów
5 do 52 punktów
5+ do 56 punktów
6 do 58 punktów

Unfortunately I cannot print it in the text output window so I'm stuck with a list or dictionary printed out. I cannot format it in a way that it looks nice. Could you help me out and tell me how to make the output text look like the text above? Ideally I would love to be able to save the result of the for loop in a result variable to use it in t1.insert(END, result).

Here's my code:

from tkinter import *

window = Tk()

grade = ["2", "2+","3","3+","4","4+","5","5+","6"]
points = [0.41,0.52,0.54,0.72,0.74,0.85,0.87,0.93,0.97]

def calculate():
    max_points = [i * float(e1_value.get()) for i in points]
    max_points = [str(round(i)) for i in max_points]
    result = dict(zip(grade, max_points))
    for key, value in result.items():
        print(f"{key} do {value} punktów")
    
    t1.delete("1.0", END)  
    t1.insert(END, result)

b1=Button(window, text="Execute", command = calculate)
b1.grid(row = 1, column = 0)

e1_value = StringVar()
e1 = Entry(window, textvariable = e1_value)
e1.grid(row = 0, column = 1)

e2 = Label(window, text = "Max points")
e2.grid(row = 0, column = 0)

t1 = Text(window, height = 15, width = 10)
t1.grid(row = 1, column = 1)

window.mainloop()

I'm sorry if what I've written isn't clear, but I've been learning python for less than a month and some things are really confusing and difficult to explain.

Upvotes: 0

Views: 530

Answers (2)

martineau
martineau

Reputation: 123393

I'm not sure exactly what else you're trying to do but you could do as @Bryan Oakley suggested and add f-string formatted data the the Text widget incrementally like this:

from tkinter import *

window = Tk()

grades = ["2", "2+","3","3+","4","4+","5","5+","6"]
points = [0.41,0.52,0.54,0.72,0.74,0.85,0.87,0.93,0.97]

def calculate():

    def get_float_value(entry):  # Helper function
        contents = entry.get()
        return 0.0 if not contents else float(contents)

    max_points = [i * get_float_value(e1_value) for i in points]
    max_points = [str(round(i)) for i in max_points]

    t1.delete("1.0", END)  # Clear widget.
    for grade, point in zip(grades, max_points):
        t1.insert(END, f"{grade} do {point} punktów\n")

b1 = Button(window, text="Execute", command=calculate)
b1.grid(row=1, column=0)

e1_value = StringVar()
e1 = Entry(window, textvariable=e1_value)
e1.grid(row=0, column=1)

e2 = Label(window, text="Max points")
e2.grid(row=0, column=0)

t1 = Text(window, height=15, width=20)
t1.grid(row=1, column=1)

window.mainloop()

If you really want to print() stuff into the Text widget, you can simulate that by doing something like the following:

# Add these imports.
from contextlib import redirect_stdout
from io import StringIO

def calculate():

    def get_float_value(entry):  # Helper function
        contents = entry.get()
        return 0.0 if not contents else float(contents)

    max_points = [i * get_float_value(e1_value) for i in points]
    max_points = [str(round(i)) for i in max_points]

    buffer = StringIO()
    with redirect_stdout(buffer):
        for grade, point in zip(grades, max_points):
            print(f"{grade} do {point} punktów")

    t1.delete("1.0", END)  # Clear widget.
    t1.insert(END, buffer.getvalue())  # Insert the stuff that was printed.

Upvotes: 1

Asdoost
Asdoost

Reputation: 394

Add this line after the result line:

result = '\n'.join([f"{key} do {value} punktów" for key, value in result.items()])

Upvotes: 1

Related Questions