Tkinter keyboard buttons add letters to Entry [duplicate] - python

This question already has answers here:
tkinter creating buttons in for loop passing command arguments
(3 answers)
Closed 5 years ago.
I'm trying to write a code for my GUI. I want a keyboard that adds a letter to the Entry widget. I'm close to it but the problem is that its adding to the entry only the letter 'a' when clicking on the buttons .
As you see in my code i added 'a' to the command. command=lambda: set_text('a')
Ofcourse is this the reason why its printing 'a' only. But if i take letter from the forloop and make set_text(letter) its showing only H in the Entry widget.
I try'd also to remove the second loop change it to set_text(lst[count])
All buttons are adding now 'A' to the Entry.
Any idea what i'm doing wrong?
my code:
from tkinter import *
from ttk import *
def maakbuttons():
count = 0
lst = []
if count <= 7:
for letter in 'ABCDEFGH':
lst.append(letter)
for letter in lst:
Buttons = Button(master=root, text=letter, command=lambda: set_text('a'))
Buttons.place(x=20, y=30 +50 * count)
count+=1
def set_text(text):
a = e.get() + text
e.delete(0, len(e.get()))
e.insert(0, a)
def remove_letter():
last = len(e.get())-1
if last >= 0:
e.delete(last)
root= Tk()
a = root.wm_attributes('-fullscreen', 1)
e = Entry(root,width=10)
e.place(x=500, y=500)
maakbuttons()
root.mainloop()

Repalce your line with:
Buttons = Button(master=root, text=letter, command=lambda x=letter: set_text(x))
Also:
for letter in 'ABCDEFGH':
lst.append(letter)
for letter in lst:
...
Seems to be redundant.

Related

How to create a keyboard from tkinter buttons that stores the entered letter?

I am writing a python hangman code with tkinter interactive window, which includes a keyboard. I have created the keyboard, however I cannot figure out how to find out which keyboard key was pressed by the user and how to store it as a letter in a variable. I will be really grateful for any help!
klavesnice = Tk()
klavesnice.geometry("800x700+120+100")
buttons = []
buttons = [
'q','w','e','r','t','y','u','i','o','p',
'a','s','d','f','g','h','j','k','l',
'z','x','c','v','b','n','m'
]
radek=3 #row
sloupec=0 #column
for button in buttons:
command=lambda x=button: select(x)
if button!='Space':
Button(klavesnice,text=button,width=5,font=("arial",14,"bold"),bg='powder blue',command=command,padx=3.5,pady=3.5,bd=5).grid(row=radek,column=sloupec)
if button=='Space':
Button(klavesnice,text=button,command=command).grid(row=5,column=sloupec)
sloupec+=1
#určení rozložení klávesnice
if sloupec>9 and radek==3:
sloupec=0
radek+=1
if sloupec>8 and radek==4:
sloupec=0
radek+=1
The code above is what displays the keyboard and the code below is the only thing I was able to come up with, which does not save the clicked key to a variable.
zadane=""
entry=Text(zadane_rm,width=43,height=3)
entry.grid(row=1,columnspan=40)
def select(value):
if value=='Space':
entry.insert(END,'')
else:
entry.insert(END, value)
I would like to store the clicked letter in a string variable called zadane.
To do what you want only requires modifying the select() function so it appends the current value argument to the global zadane string variable. Note I have reformatted your code to follow the PEP 8 - Style Guide for Python Code guidelines more closely to make it more readable.
import tkinter as tk # Avoid `import *`
klavesnice = tk.Tk()
klavesnice.geometry("800x700+120+100")
buttons = [
'q','w','e','r','t','y','u','i','o','p',
'a','s','d','f','g','h','j','k','l',
'z','x','c','v','b','n','m'
]
zadane = ''
entry = tk.Text(klavesnice, width=43, height=3)
entry.grid(row=1, columnspan=40)
def select(value):
global zadane
if value == 'Space':
entry.insert('end', ' ')
else:
entry.insert('end', value)
zadane = zadane + value
print(f'{zadane=!r}')
radek = 3 #row
sloupec = 0 #column
for button in buttons:
command = lambda x=button: select(x)
if button != 'Space':
tk.Button(klavesnice, text=button, width=5, font=("arial", 14, "bold"),
bg='powder blue', command=command, padx=3.5, pady=3.5, bd=5
).grid(row=radek, column=sloupec)
if button == 'Space':
tk.Button(klavesnice, text=button, command=command).grid(row=5, column=sloupec)
sloupec += 1
# Specify the keyboard layout
if sloupec > 9 and radek == 3:
sloupec = 0
radek += 1
if sloupec > 8 and radek == 4:
sloupec = 0
radek += 1
klavesnice.mainloop()

Add together numbers from Comboboxes tkinter python

i want to add multiple values that the user select from different comboboxes. I then want to add together the values and display the total value next to the boxes. The problem seems to be that the "values" from the comboboxes are strings, and can therefore not be added together.
If you wanna run the program, just comment out the variable "totalvalues before the last for loop. (i know it looks wierd, i just tried to make a new program to show my problem)
import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext
win=tk.Tk() #window
win.title("Moskalkylator")
antalcomboboxes=4
mighty=ttk.LabelFrame(win,text='Welcome')
mighty.grid(column=0,row=0,padx=8 ,pady=4)
Items=['Wood','Iron','Plastic','Glass']
def click():
calculate = ttk.Label(win, text="Your total number of items is : " + totalvalues.get()) # See row 27
calculate.grid(column=1, row=0)
buttons_frame=ttk.LabelFrame(mighty)
buttons_frame.grid(column=1,row=8, padx=3, pady=3,sticky=tk.W)
calculate=ttk.Button(buttons_frame,text='Count', command=click).grid(column=1,row=8)
#Creates combobox 1
list1=list(range(11))
number_chosen1= ttk.Combobox(mighty,values=list1, state="readonly") #The number you pick in the combobox
number_chosen1.grid(column=1,row=1,sticky=tk.W)
#Creates combobox 2
list2=list(range(11))
number_chosen2= ttk.Combobox(mighty,values=list2, state="readonly")
number_chosen2.grid(column=1,row=3,sticky=tk.W)
###############
totalvalues=number_chosen1+number_chosen2 #This does not work! COMMENT THIS
###############
#Loop to get the names of the items above combobox
Items_order=0
row_move_loop2=0
for element in Items:
article = ttk.Label(mighty, text=Items[Items_order])
article.grid(column=1, row=row_move_loop2)
Items_order=Items_order+1
row_move_loop2=row_move_loop2+2
win.mainloop()
You have to use the get() method to get the values from combobox and convert them to integers. Also, don't keep creating new label everytime you want to display the count instead create the label once and use configure method to change the text.
Here is your corrected code:
import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext
win=tk.Tk() #window
win.title("Moskalkylator")
antalcomboboxes=4
mighty=ttk.LabelFrame(win,text='Welcome')
mighty.grid(column=0,row=0,padx=8 ,pady=4)
Items=['Wood','Iron','Plastic','Glass']
def click():
global totalvalues
if number_chosen1.get() != '' and number_chosen2.get() != '':
totalvalues= int(number_chosen1.get()) + int(number_chosen2.get())
calculate.configure(text="Your total number of items is : " + str(totalvalues))
buttons_frame=ttk.LabelFrame(mighty)
buttons_frame.grid(column=1,row=8, padx=3, pady=3,sticky=tk.W)
calculate=ttk.Button(buttons_frame,text='Count', command=click).grid(column=1,row=8)
#Creates combobox 1
list1=list(range(11))
number_chosen1= ttk.Combobox(mighty,values=list1, state="readonly") #The number you pick in the combobox
number_chosen1.grid(column=1,row=1,sticky=tk.W)
#Creates combobox 2
list2=list(range(11))
number_chosen2= ttk.Combobox(mighty,values=list2, state="readonly")
number_chosen2.grid(column=1,row=3,sticky=tk.W)
###############
print(number_chosen1.get())
totalvalues = 'None'
calculate = ttk.Label(win) # See row 27
calculate.grid(column=1, row=0)
###############
#Loop to get the names of the items above combobox
Items_order=0
row_move_loop2=0
for element in Items:
article = ttk.Label(mighty, text=Items[Items_order])
article.grid(column=1, row=row_move_loop2)
Items_order=Items_order+1
row_move_loop2=row_move_loop2+2
win.mainloop()
when u retrieve values as a string u need to convert them.
totalvalues=int(number_chosen1)+int(number_chosen2)
or
totalvalues=float(number_chosen1)+float(number_chosen2)

TKinter buttons and function syntax [duplicate]

This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 3 years ago.
I'm playing around with TKinter trying to make a number generator.
I can't figure out why a new number doesn't get generated when I use this code:
roll = Button(window, text = 'Roll!', command = num())
But it works if I remove the brackets:
roll = Button(window, text = 'Roll!', command = num)
Thanks guys!
Rest of the code:
from tkinter import *
import random
def num():
number = random.randint(1, 6)
num1.configure(text = number)
return
window = Tk()
window.geometry('300x200')
window.title('Dice')
num1 = Label(window, text = 0)
num1.grid(column = 0, row = 0)
roll = Button(window, text = 'Roll!', command = num)
roll.grid(column = 0, row = 1)
window.mainloop()
When you write num() with the parentheses, you're calling the function immediately, and passing its return value as the argument to Button. When you just name the function, you're passing the function object itself as the argument to Button, and it will call the function later (when the button is clicked).

Python TKinter: How do I achieve the same effect as input() in the GUI?

I started learning python a month and a half ago. So please forgive my lack of everything.
I'm making a text based adventure game. The game has been written and playable in terminal. I'm now adding a GUI as an after thought.
In one file, I have:
class Parser():
def __init__(self):
self.commands = CommandWords()
def get_command(self):
# Initialise word1 and word2 to <None>
word1 = None
word2 = None
input_line = input( "> " )
tokens = input_line.strip().split( " " )
if len( tokens ) > 0:
word1 = tokens[0]
if len( tokens ) > 1:
word2 = tokens[1]
This is called whenever the user is expected to enter text, it will then call another function to compare the input with known commands to move the game along.
However, when I tried to replace the input() with entry_widget.get(), it doesn't recognise entry_widget.
so I imported my file containing the GUI script, which is a circular importing error.
I tried to store the input as a string variable, but the program doesn't stop and wait for the user input, so it gets stuck the moment the program start to run not knowing what to do with the empty variable. (that is assuming input() stops the program and wait for user input? )
Any solutions? Or better ways of doing this?
Thanks.
import tkinter as tk
To create an Entry widget: entry = tk.Entry(root)
After you have that, you can get the text at any time: text = entry.get()
To make the program wait you need to create a tkinter variable: wait_var = tk.IntVar()
and then create a button that changes the value of the variable when pressed: button = tk.Button(root, text="Enter", command=lambda: wait_var.set(1))
Now you can tell tkinter to wait until the variable changes:button.wait_variable(wait_var)
Simple example:
import tkinter as tk
def callback():
print(entry.get())
wait_var.set(1)
root = tk.Tk()
wait_var = tk.IntVar()
entry = tk.Entry(root)
button = tk.Button(root, text="Enter", command=callback)
entry.pack()
button.pack()
print("Waiting for button press...")
button.wait_variable(wait_var)
print("Button pressed!")
root.mainloop()

Trying to put drop down list on a code using Tkinter

I'm tring to put some drop down list on a graphic interface I'm building.
I've found the following code for a drop down list, but I'm not able to adapt it to my code.
from Tkinter import *
def print_it(event):
print var.get()
root = Tk()
var = StringVar()
var.set("a")
OptionMenu(root, var, "a","b","c", command=print_it).pack()
root.mainloop()
This is my code, it's quite simple what I've done so far. A menu shows up, it asks for how many (n) components does the users want to enter, and it shows n options to entry. The code above shows 'blank' entrys after you put the desired number of components. I want to replace those three blank entrys with three drop down list.
It's marked when I want to put those dropdown lists.
from Tkinter import *
import Image
import ImageTk
import tkFileDialog
class Planificador:
def __init__(self,master):
master.title("Planificador")
self.frameOne = Frame(master)
self.frameOne.grid(row=0,column=0)
# Logo
self.imgLabel = Label(self.frameOne, image = None)
self.imgLabel.grid(row=0,column=0)
self.img = ImageTk.PhotoImage(file = "logo.png")
self.imgLabel["image"] = self.img
self.botones()
def botones(self):
self.piezastext = Label(self.frameOne, text = " number of components ", justify="center")
self.piezastext.grid(row=1, column=0)
self.entrypiezas = Entry(self.frameOne,width=5)
self.entrypiezas.grid(row=2, column=0)
self.aceptarnumpiezas = Button(self.frameOne,text="Aceptar", command=self.aceptar_piezas,width=8)
self.aceptarnumpiezas.grid(row=6, column=0)
def aceptar_piezas(self):
num_piezas = self.entrypiezas.get()
print num_piezas
self.piezastext.grid_remove()
self.entrypiezas.grid_remove()
self.aceptarnumpiezas.grid_remove()
n = 1;
while n <= int(num_piezas):
self.textopieza = Label(self.frameOne, text = "Pieza", justify="left")
self.textopieza.grid(row=n, column=0)
// INSTEAD THESE 'n' BLANK ENTRYS, I WANT TO PUT 'n' DROP DOWN LISTS
self.entrypiezas = Entry(self.frameOne,width=5)
self.entrypiezas.grid(row=n, column=1)
self.aceptarpiezas = Button(self.frameOne,text="Aceptar",width=8)
self.aceptarpiezas.grid(row=int(num_piezas)+1, column=0)
n += 1
# Main
if __name__ == "__main__":
# create interfacE
root = Tk()
movieApp = Planificador(root)
root.mainloop()
So I want to know how can I put that drop down list on a given frame, frameOnein my case, instead of a full window. Thanks in advance.
I modified your aceptar_piezas function to do what I think you want:
def aceptar_piezas(self):
num_piezas = self.entrypiezas.get()
print num_piezas
self.piezastext.grid_remove()
self.entrypiezas.grid_remove()
self.aceptarnumpiezas.grid_remove()
# Create a list of tuples to hold the dynamically created Optionmenus
# The first item in the tuple is the menu, the second is its variable
self.optionmenus = list()
n = 1
while n <= int(num_piezas):
self.textopieza = Label(self.frameOne, text = "Pieza", justify="left")
self.textopieza.grid(row=n, column=0)
# Variable for the Optionmenu
var = StringVar()
# The menu
menu = OptionMenu(self.frameOne, var, "a","b","c")
menu.grid(row=n, column=1)
# Set the variable to "a" as default
var.set("a")
# Add the menu to the list of Optionmenus
self.optionmenus.append((menu, var))
n += 1
def clicked():
"""This function was made just to demonstrate. It is hooked up to the button"""
for optionmenu in self.optionmenus:
print optionmenu[1].get()
print self.optionmenus
# This button doesn't need to be in the while loop
self.aceptarpiezas = Button(self.frameOne, text="Aceptar", command=clicked, width=8)
self.aceptarpiezas.grid(row=int(num_piezas)+1, column=0)
The tuples in the list are in the order that the Optionmenus were created. So, the first tuple contains the data for the first Optionmenu, the second for the second, and so forth.

Categories

Resources