I am building a GUI with tkinter where two buttons modify two text fields. One button chooses a random key from the example_dict
and displays it in text1
, and the other reveals the corresponding value in text2
. I have chosen a OOP approach to organize my code, because it seems the easiest to read.
To give a more compact overview, I have boiled the script down to my problem. In the actual script I use a pandas dataframe instead of the example_dict
, but for the purpose of this question, I wanted to maintain the possibility of copying and pasting .
import tkinter as tk
from random import randint
example_dict = {'a': "one", 'b': "two", 'c': "three"}
class MainApp:
def __init__(self, master):
self.master = master
self.reveal_button = tk.Button(master, text="reveal", command=self.reveal)
self.reveal_button.pack()
self.reveal_button.place(relx=0.5, rely=0.25, anchor=tk.CENTER)
self.random_button = tk.Button(master, text="randomize", command=self.random_word)
self.random_button.pack()
self.random_button.place(relx=0.5, rely=0.6, anchor=tk.CENTER)
# create two text fields that will display the key:value pair from the dictionary
self.text1 = tk.Text(master, height=2, width=20)
self.text1.pack()
self.text1.place(relx=0.3, rely=0.25, anchor=tk.CENTER)
self.text2 = tk.Text(master, height=2, width=20)
self.text2.pack()
self.text2.place(relx=0.7, rely=0.25, anchor=tk.CENTER)
def random_word(self):
rand_num = randint(0,2)
self.text1.delete(1.0, tk.END)
self.text2.delete(1.0, tk.END)
self.text1.insert(tk.END, list(example_dict.keys())[rand_num])
def reveal(self):
self.text2.delete(1.0, tk.END)
self.text2.insert(tk.END, list(example_dict.values())[rand_num])
root = tk.Tk()
MainApp(root)
root.mainloop()
The problem is of course that rand_num
is only defined within random_word
, resulting in a NameError when I click the reveal_button
. I am not sure where to generate the random number to be able to use the same number in both class functions.
I have tried a few things. First, I created a separate function that only generates a random integer, which I then called from both other functions. I did not expect this to work, because it generates different integers each time it is called, leading to mismatched key:value pairs. The attempt looked like this:
def random_number(self):
return randint(0,2)
def random_word(self):
rand_num = self.random_number()
self.text1.delete(1.0, tk.END)
self.text2.delete(1.0, tk.END)
self.text1.insert(tk.END, list(example_dict.keys())[rand_num])
def reveal(self):
rand_num = self.random_number()
self.text2.delete(1.0, tk.END)
self.text2.insert(tk.END, list(example_dict.values())[rand_num])
Second, I declared rand_num
as global, which works, but everytime I've seen global variables being mentioned, people say they should be avoided, leading me to believe I should avoid them too.
def random_word(self):
global rand_num
rand_num = randint(0,2)
self.text1.delete(1.0, tk.END)
self.text2.delete(1.0, tk.END)
self.text1.insert(tk.END, list(example_dict.keys())[rand_num])
Another idea I had and quickly discarded was generating the random number as an instance attribute, but that should just generate a number once, and I need it to generate a new number every time the random_button
is clicked.
How do I generate a random number every time the random_button
is clicked, that I can then use with both my functions?
Aucun commentaire:
Enregistrer un commentaire