简体   繁体   中英

Issues figuring out how to update labels in Tkinter for my Python program

So I am writing a Python program in class that uses the Caesar cipher to take a users input and output it as cipher-text. Since i had a lot more time for this project I planned on giving it a GUI in Tkinter. But when I assign the resulted cipher-text to a label it won't display it and keeps it blank. I'm a noob to python and even more to Tkinter so I'm not too keen on being able to fix these issues myself. Here's the code:

import string
import collections
import random
import tkinter
from tkinter import *
from tkinter.ttk import *

root = Tk()
root.title("Encoder")
root.geometry("500x400")

def caesar(rotate_string, number_to_rotate_by):

    upper = collections.deque(string.ascii_uppercase)
    lower = collections.deque(string.ascii_lowercase)

    upper.rotate(number_to_rotate_by)
    lower.rotate(number_to_rotate_by)

    upper = ''.join(list(upper))

    lower = ''.join(list(lower))

    return rotate_string.translate(str.maketrans(string.ascii_uppercase, upper)).translate(str.maketrans(string.ascii_lowercase, lower))

def callback():
    print (code)

b = Button(root, text="get", width=10, command=callback)
b.pack()

var = StringVar()

e = Entry(root, textvariable = var)
e.pack()

our_string = e.get()
random_number = random.randint(1,25)
code = caesar(our_string, random_number)


l = Label(root, textvariable=code, anchor=NW, justify=LEFT, wraplength=398)
l.pack()
l.place(relx=0.5, rely=0.5, anchor=CENTER)

root.mainloop()

There are several issues with the code you've posted. First and foremost, your callback doesn't do anything besides print the code variable. You need to move your call to caesar and the associated code into the callback, like so

def callback():
    global code
    our_string = e.get()
    random_number = random.randint(1, 25)
    code.set(caesar(our_string, random_number))

The second issue that I see is that you need to use a StringVar as the textvariable argument in your Label constructor in order to get the label to update automatically. When all is said and done, my version of your code looks like

import string
import collections
import random
from tkinter import *
from tkinter.ttk import *

root = Tk()
root.title("Encoder")
root.geometry("500x400")

code = StringVar()
code.set('Hello')


def caesar(rotate_string, number_to_rotate_by):
    upper = collections.deque(string.ascii_uppercase)
    lower = collections.deque(string.ascii_lowercase)

    upper.rotate(number_to_rotate_by)
    lower.rotate(number_to_rotate_by)

    upper = ''.join(list(upper))

    lower = ''.join(list(lower))

    return rotate_string.translate(str.maketrans(string.ascii_uppercase, upper)).translate(str.maketrans(string.ascii_lowercase, lower))


def callback():
    global code
    our_string = e.get()
    random_number = random.randint(1, 25)
    code.set(caesar(our_string, random_number))

b = Button(root, text="get", width=10, command=callback)
b.pack()

var = StringVar()

e = Entry(root, textvariable=var)
e.pack()
l = Label(root, textvariable=code, anchor=NW, justify=LEFT, wraplength=398)
l.pack()
l.place(relx=0.5, rely=0.5, anchor=CENTER)

root.mainloop()

This seems to do what you'd expect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM