I'm trying to select random names from a list to display on a textbox in a tkinter GUI, with a button and need new draws to display in tkinter script each time I click the button.
Here's my code so far:
from tkinter import *
from random import sample
root = Tk()
root.title('Name Picker')
root.iconbitmap('c:/myguipython/table.ico')
root.geometry("400x400")
def pick():
# 5 entries
entries = ["1st name","2nd name","3rd name","4th name","5th name"]
# convert to a set
entries_set = set(entries)
# convert back to a list
unique_entries = list(entries_set)
number_of_items = 2
rando = sample(unique_entries, number_of_items)
rando1 = sample(unique_entries, number_of_items)
my_text = Text(root, width=40, height=10, font=("Helvetica", 18))
my_text.pack(pady=10)
if len(my_text.get(1.0, END)) != 0:
my_text.delete(1.0, END)
my_text.insert(INSERT, rando + rando1)
my_text.pack(expand= 1, fill= BOTH)
topLabel = Label(root, text="Picked Names", font=("Helvetica", 24))
topLabel.pack(pady=20)
winButton = Button(root,
text="pick names",
font=("Helvetica", 24), command=pick)
winButton.pack(pady=20)
root.mainloop()
I need several subsets of random draws (I'm using rando and rando1 values as example above).
When I click the button the 1st time it does display the names strings as expected, but when I click again nothing changes (the names remain the same).
What I need is for new draws to display each time I click the button.
I thought of clearing the textbox if not empty and populating back when clicking again on empty textbox (with the delete and insert statements above). But that's not working.
After some research I found this snippet:
# Import package and it's modules
from tkinter import *
# text_update function
def text_updation(language):
text.delete(0, END)
text.insert(0, language)
# create root window
root = Tk()
# root window title and dimension
root.title("GeekForGeeks")
# Set geometry (widthxheight)
root.geometry('400x400')
# Entry Box
text = Entry(root, width=30, bg='White')
text.pack(pady=10)
# create buttons
button_dict = {}
words = ["Python", "Java", "R", "JavaScript"]
for lang in words:
# pass each button's text to a function
def action(x = lang):
return text_updation(x)
# create the buttons
button_dict[lang] = Button(root, text = lang,
command = action)
button_dict[lang].pack(pady=10)
# Execute Tkinter
root.mainloop()
It seems it's close to what I need but the dictionary use seems incompatible with my conversion to a set and then back to a list and then the sampling before the displaying in the textbox of my code.
How could I use the given snippet to solve this issue? Or lese if it's not possible with this snippet, what other other solution of insight to look for would you suggest? Your help is appreciated.
In your code you are calling the widget constructor for the Text widget every time you press the button. What you should do is create the widget outside of the function and use the function just to update the widget's contents. There is also quite a bit of erroneous code as well.
For example:
from tkinter import *
from random import sample
root = Tk()
root.title('Name Picker')
root.iconbitmap('c:/myguipython/table.ico')
root.geometry("400x400")
def pick():
entries = ["1st name","2nd name","3rd name","4th name","5th name"]
number_of_items = 2
rando = sample(entries, number_of_items)
rando1 = sample(entries, number_of_items)
my_text.delete(1.0, END)
my_text.insert(INSERT, rando + rando1)
topLabel = Label(root, text="Picked Names", font=("Helvetica", 24))
topLabel.pack(pady=20)
winButton = Button(root, text="pick names", font=("Helvetica", 24), command=pick)
winButton.pack(pady=20)
my_text = Text(root, width=40, height=10, font=("Helvetica", 18))
my_text.pack(pady=10)
root.mainloop()
Related
I am trying to create a Tkinter window with a button which when clicked will provide with a new window. The new window has a checkbox and I want some actions to be done based on the checkbox value.
from tkinter import *
from tkinter import messagebox
def my_command():
def run():
pass
def cb_command():
f1 = fname1.get()
messagebox.showinfo("First Name", f1)
if cbVar.get() == 1:
messagebox.showinfo(cbVar.get())
my_button['state'] = 'active'
else:
messagebox.showinfo("Not found!")
my_button['state'] = 'disabled'
root = Tk()
root.geometry("200x200")
fname = Label(root, text="First Name")
fname.grid(row= 0, column = 0, sticky = "news", padx=5, pady=5)
fname1 = Entry(root, width = 10)
fname1.grid(row =0, column = 1, sticky = "news", padx=5, pady=5)
cbVar = IntVar()
cb1 = Checkbutton(root, text="Please check this", variable=cbVar, onvalue=1, offvalue=0, command=cb_command)
cb1.grid(row = 1, column = 0)
my_button = Button(root, text = "Run", bg = '#333333', fg='#ffffff', font = 'Helvetica', command = run, state='disable')
my_button.grid(row = 2, column = 0)
root.mainloop()
window = Tk()
window.geometry("200x200")
button1 = Button(window, text = "Run", command = my_command)
button1.pack()
window.mainloop()
I wrote this simple code which works fine with all other entry widgets. However, the checkbutton in the new window does not work. Can someone suggest any alternative?
Update:
Sorry, that I didn't clarify what actions to be done. I want the checkbox when clicked impact the state of the "Run" button in the toplevel window. The actual actions are based on the "Run" button.
Thank you Thingamabobs for suggesting a very simple solution. Just replaced one instance of Tk with Toplevel and it works.
from tkinter import *
def new_window():
second_window = Toplevel()
def checkbutton_checked():
# If you just want to take some action, once the checkbutton has been checked, you could do this here
# Alternatively you could also add a button to the toplevel and on click check the value of
# the checkbutton and perform actions based on that...
cb1.configure(text="Checkbutton checked")
cb1 = Checkbutton(second_window, text="Check here", command=checkbutton_checked)
cb1.pack()
window = Tk()
b1 = Button(window, text="Open new window", command=new_window)
b1.pack()
window.mainloop()
I hope this provides some help and you can solve your problem, if not let me know please.
Further details about the purpose of the checkbutton would also help me.
When I watched ecnerwala videos on competitive programming, I found something interesting in his video.
This running text
ecnerwala running text
Here is the link of the video
https://www.youtube.com/watch?v=ExmrrXi04vI&t=1030s
So I tried to create something like that running text using tkinter.text widget in python.
I create a window, add text object to it, and bind all keyboard keys to the window. I insert those keys into the text object when any key is pressed. I also make sure that even if I press the enter button, I don't insert it as a newline to the text widget but as the word 'Return' instead
Of course, there is a possibility that the length of all characters I insert into the text is longer than the length of the text widget could fit in one sentence. That's why I want to make the text widget to "always" see the characters from index END-(the number of character the widget could fit) until END
Here is my code
from tkinter import *
def handle(event):
text.config(state = NORMAL)
text.insert(END, event.keysym)
text.config(state = DISABLED)
# Things to be fix
text.doSomethingToMakeItBehaveLikeEntryWidget()
window = Tk()
window.geometry('500x500')
text = Text(window, font = ('Arial', 20), height = 1)
entry = Entry(window, font = ('Arial', 20))
text.config(state = DISABLED)
text.pack()
entry.pack()
window.bind('<Key>', handle)
window.mainloop()
Is there any solution for this problem? Even if I have to use another widget instead of text widget to solve it? Thanks for the help
Given that you use only one line in the text widget, you can use an entry in read-only mode instead.
No matter whether you use an entry or a text widget, you can use the method text.xview_moveto(<fraction>) to set which part of the content is visible, <fraction> being the relative portion of the widget's content which is hidden on the left. If you set this fraction to 1, it will ensure that the last character is visible.
from tkinter import *
def handle(event):
text.config(state=NORMAL)
text.insert(END, event.keysym)
text.config(state="readonly")
text.xview_moveto(1)
window = Tk()
window.geometry('500x500')
text = Entry(window, font = ('Arial', 20), state="readonly", readonlybackground="white")
entry = Entry(window, font = ('Arial', 20))
text.config(state = DISABLED)
text.pack()
entry.pack()
window.bind('<Key>', handle)
window.mainloop()
Try this.
from tkinter import *
from tkinter.scrolledtext import ScrolledText
def handle(event):
text.config(state = NORMAL)
text.insert(END, event.keysym)
text.config(state = DISABLED)
t = text.get('1.0','end-1c')
length= len(t)
width =text.winfo_width()
max_char = int((35/500)*width)
if max_char < length:
a = length-max_char
text.config(state = NORMAL)
text.delete(1.0,END)
text.insert(1.0,t[a:])
text.config(state = DISABLED)
window = Tk()
window.geometry('500x500')
text = Text(window, font = ('Arial', 20), height = 1)
entry = Entry(window, font = ('Arial', 20))
text.config(state = DISABLED)
text.pack()
entry.pack()
window.bind('<Key>', handle)
window.mainloop()
I want to create a column of 10 buttons and have them numbered in order.
Is there a simpler way to do it using for loops that I can add the text to these buttons rather than coding out each button line by line?
This is what I have but it only puts the the number 10 text in each button?
I want each button numbered starting from 1 thru 10.
from tkinter import *
root = Tk()
#Create Buttons
def create_buttons():
number_text = []
for nums in range(0,10):
number_text.append(str(nums))
for col in range(10):
for num in number_text:
buttons = Button(root, font=30, text = num, padx=15, pady=10)
buttons.grid(row=0, column=col)
create_buttons()
root.mainloop()
This is my solution for your problem,
from tkinter import *
root = Tk()
#Create Buttons
def create_buttons():
for num in range(1,11):
buttons = Button(root, font=30, text =str(num), padx=15, pady=10)
buttons.grid(row=0, column=num)
create_buttons()
root.mainloop()
Actually, you can solve this one easily. Every time you should try to reduce the complexity of the program. Don't think much. So I supposed this code much easier to solve your problem. Here I using only one loop and that loop I use for the given name for the button and also the given column number. You using the same parameters for the Button widget and grid manipulation. When we use another name for the button you should want to create a list. That code example is given below,
from tkinter import *
root = Tk()
button_name=[f'number_{i}' for i in range(10)]
#Create Buttons
def create_buttons():
for num in range(1,11):
buttons = Button(root, font=30, text =str(button_name[num-1]), padx=15, pady=10)
buttons.grid(row=0, column=num)
create_buttons()
root.mainloop()
It might be because the 1st button gets overlapped by 2nd ... so on to 9th button. So, you see 9 on top, which hides other buttons.
Try a different way -
from tkinter import *
root = Tk()
#Create Buttons
def create_buttons():
number_text = [*range(1,10+1)] # Or you could just do this in your way
for col in range(10):
buttons = Button(root, font=30, text = number_text[col] , padx=15, pady=10)
buttons.grid(row=0, column=col)
create_buttons()
root.mainloop()
This will take the index number_text[col] and show the buttons.
I am essentially trying to have my entry box display the entered text on the screen as a label, expect after each time the button is pressed (the button that displays the text), the newly entered data is displayed somewhere else on the screen. Essentially multiple labels from one entry box and button.
def writelabel():
labelentrval = Label(master, font = ("Helvetica", 15), text="" + str(entryvalue.get()))
labelentrval.place(x=645,y=621)
entryvalue.delete(first=0,last=22)
()
entryvalue = Entry(master)
entryvalue.place(x=700, y=515)
buttonpressy = Button(master,text="Enter", command=writelabel)
buttonpressy.place(x=845,y=510)
Code is above, and so far when I enter something into my entry box and press the button it displays it on the screen as a label. But how would I keep displaying my entries over and over in different places?
Thank you
You want to create a new label for every button press:
from tkinter import *
root = Tk()
def clicked():
text = e.get()
newLabel = Label(root, text=text)
newLabel.pack()
e = Entry(root)
e.pack()
b = Button(root, text='click', command=clicked)
b.pack()
root.mainloop()
I would like a text box to ask for input in a tkinter window, then use that input as a parameter to call a function that draws a Sierpinski triangle. My buttons work but my input box does not. I keep trying to fix my code but it is not working, any help would be appreciated.
import tkinter as tk
from tkinter import *
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
root.title('Fractals') #titles the button box
top_frame = tk.Frame()
mid_frame = tk.Frame()
prompt_label = tk.Label(top_frame, \
text='Enter a number of iterations (more is better):')
iterations = tk.Entry(root,bd=1)
itr=iterations.get()
itr=int(itr)
button = tk.Button(frame,
text="QUIT",
fg="red",
command=quit)
button.pack(side=tk.LEFT)
sTriangle = tk.Button(frame,
text="Triangle",
command=lambda: sierpinski(fred, (-500,-500), (500,-500),
(0,500),itr))
sTriangle.pack(side=tk.LEFT)
fsquare = tk.Button(frame,
text="Square",
command=fractalsquare(fred,(-500,-500),(500,-500),
(500,500),(-500,500),itr))
fsquare.pack(side=tk.LEFT)
root.mainloop()
There are several issues:
1) Choose one way to import tkinter or confusion will result
2) You should provide a master for your Frames and then pack them. Pay attention on where the frames appear and what they contain.
3) It's usual to assign a textvariable to the Entry which will contain what you enter into it. The textvariable should be a tk.StringVar.
4) If a Button has a callback function, it must be defined before you create the button.
5) The variable fred is not defined.
Example of how you can write it:
import tkinter as tk
root = tk.Tk()
root.title('Fractals') #titles the button box
# Create the Label at the top
top_frame = tk.Frame(root) # Top Frame for
top_frame.pack()
prompt_label = tk.Label(top_frame,
text='Enter a number of iterations (more is better):')
prompt_label.pack()
# Create the Entry in the middle
mid_frame = tk.Frame(root)
mid_frame.pack()
itr_string = tk.StringVar()
iterations = tk.Entry(mid_frame,textvariable=itr_string)
iterations.pack()
fred=None # Was not defined...
# Create Buttons at the bottom
bot_frame = tk.Frame(root)
bot_frame.pack()
button = tk.Button(bot_frame, text="QUIT", fg="red", command=quit)
button.pack(side=tk.LEFT)
def sierpinski(*args): # sTriangle button callback function
itr = int(itr_string.get()) # How to get text from Entry
# if Entry does not contain an integer this will throw an exception
sTriangle = tk.Button(bot_frame, text="Triangle",
command=lambda: sierpinski(fred, (-500,-500), (500,-500),(0,500),itr_string))
sTriangle.pack(side=tk.LEFT)
def fractalsquare(*args): pass # fsquare button callback function
fsquare = tk.Button(bot_frame, text="Square", command=fractalsquare(fred,
(-500,-500),(500,-500),(500,500),(-500,500),itr_string))
fsquare.pack(side=tk.LEFT)
root.mainloop()
You should seriously study a basic tkinter tutorial. Try this one: An Introduction To Tkinter