python gui AND/OR programm - python

I am using python GUI. So here's the deal https://learn.digilentinc.com/Documents/Digital/BT02_03_Basic_Logic_Truth_Table/AndOrTruthTable.svg
It should be like this. For example, if the user writes 1 in entry a and 0 in entry b and he chooses "and" radio button in label c should appear 0.
I tried something but it didn't work. Can anyone help me?
This is my code that doesn't work:
from tkinter import *
root = Tk()
a = Label(root,text = "enter number a")
b = Label(root,text = "enter number b")
c = Label(root)
a.grid(row=0, sticky=E)
b.grid(row=1, sticky=E)
c.grid(row=3, sticky=E)
entry_a = Entry(root)
entry_b = Entry(root)
entry_a.grid(row=0, column=1)
entry_b.grid(row=1,column=1)
v = IntVar()
def ifvisnull(event):
if entry_a == 1 and entry_b == 1:
print(1)
else:
print(0)
def ifvisone(event):
if entry_a == 0 and entry_b == 0:
print(0)
else:
print(1)
button1 = Radiobutton(root, text="and", variable = v, value = True, command = ifvisnull())
button2 = Radiobutton(root, text="or", variable = v, value = False, command = ifvisone())
button1.grid(row=2,column=0)
button2.grid(row=2,column=1)
root.mainloop()

my name is Vikas.
So there are a few problems i your code.
in all radiobutton , in the command option you had put parenthesis-()
infront of the command which you have to remove
ex: command=ifvisnull
then in all functions you have given event argument which you need not to
until and unless you are binding the widget to an event.
So,just remove event argument
Lastly , in each function to get the value of entry box you need to use
entry.get() function/method.
Directly writing entry_a will not give you the value
And also this method will return in str type .

Related

how i can with just with the checked entry widgets

Hi,
i just wanna ask you guys, if is there any way to work with just checked chexboxes
here it my code :
from tkinter import *
window1 =Tk()
window1.geometry("400x400")
window1.resizable(False,False)
#---------------------------------------------
def test1():
if entry1['state'] == 'normal':
entry1['state'] = 'disabled'
else:
entry1['state'] = 'normal'
entry1 =Entry()
entry1.pack()
cb1 = Checkbutton(command=test1)
cb1.select()
cb1.pack()
#---------------------------------------------
def test2():
if entry2['state'] == 'normal':
entry2['state'] = 'disabled'
else:
entry2['state'] = 'normal'
entry2 =Entry()
entry2.pack()
cb2 = Checkbutton(command=test2)
cb2.select()
cb2.pack()
#---------------------------------------------
def test3():
if entry3['state'] == 'normal':
entry3['state'] = 'disabled'
else:
entry3['state'] = 'normal'
entry3 =Entry()
entry3.pack()
cb3 = Checkbutton(command=test3)
cb3.select()
cb3.pack()
#---------------------------------------------
def test4():
if entry4['state'] == 'normal':
entry4['state'] = 'disabled'
else:
entry2['state'] = 'normal'
entry4 =Entry()
entry4.pack()
cb4 = Checkbutton(command=test4)
cb4.select()
cb4.pack()
#---------------------------------------------
def message():
b = float (entry1.get())
c = float ( entry2.get())
d = float ( entry3.get())
e = float ( entry4.get())
label1 = Label(window1, text="1) here is what you wrote ma boy :"+ str(b))
label1.place(x=60,y=200)
label2 = Label(window1, text="2) here is what you wrote ma boy :"+ str(c))
label2.place(x=60,y=230)
label3 = Label(window1, text="3) here is what you wrote ma boy :"+ str(d))
label3.place(x=60,y=260)
label4 = Label(window1, text="4) here is what you wrote ma boy :"+ str(e))
label4.place(x=60,y=290)
button1 = Button(window1,text="Click", command= message, width=8)
button1.place(x=20,y=200)
window1.mainloop()
here is what i want :
i want to check the checkbox 2 and 4 for example and enter values and i want the code to execute just the second and the forth message. if i check the the first,second and the forth checkboxes,and enter values, i want the code to execute just the first, the second and the forth message. and so one . i wish u unerstand what i'm trying to say.
thank you in advance,
and i'm sorry for my bad English
if there is a tutorial that can help me in this , plz just share it.
The checkbuttons command is executed every time you click on it. The checkbutton takes additional options like variable a tkinter variable that is set to onvalue and offvalue depending on an internal state. Check your variable in the function and alter the entry as you desire.
update
You could check the variable even in a different function like your message function.
import tkinter as tk
def message():
if var.get():
print(entry.get())
entry.delete('0',tk.END)
def test():
if var.get():#check variable
entry['state'] = 'normal'
else:
entry['state'] = 'disabled'
root = tk.Tk()
entry = tk.Entry()
var = tk.BooleanVar(value=False)#tkinter variable
checkbutton = tk.Checkbutton(command=test,
onvalue=True,
offvalue=False,
variable=var)
button = tk.Button(text='Print',command=message)
checkbutton.invoke()
##checkbutton.invoke()
button.pack(side=tk.BOTTOM,fill=tk.BOTH)
entry.pack(side=tk.RIGHT)
checkbutton.pack(side=tk.LEFT)
root.mainloop()

Comparing user input in Tkinter

I have a issue with tkinter. I want to use Entry to take info from the user and then
compare it to a string if the result is true I want it to print a Label on the screen
and if false I want it to print something else. For some reason the .get does not
show for me, and I can't find a way to compare the user input in. The Entery to a simple
string that I saved as a variable.
from tkinter import *
window = Tk()
window.geometry("800x600")
window.title("Sara's chocolate balls")
def Button_Click():
test1 = "hey"
if entry1 == test1:
test2.pack()
else:test3.pack()
entry1 = Entry(window, width=30).pack()
Button1 = Button(window, text="Button", command=Button_Click).pack()
test2 = Label(window, text="Good")
test3 = Label(window, text="Bad")
window.mainloop()
So I found a solution:
entry1 = Entry(window,textvariable=var, width=30).pack()
var = StringVar()
user_input = var.get()
It works like that.

Tkinter - How to limit the space used by a Text?

I'm trying to create a factorial calculator GUI.
The program works fine, but the problem I'm having is that when there are too many numbers coming in from the output, the screen automatically increases in width. I've tried using tk.Text to create a limit to the size of the textbox and so the text continues to the next row when the columns are filled.
But when I had to input text in to the tk.Text it didn't work since the variable I used is being processed in the function that gets called when the button is pressed. I have tried googling this problem but I couldn't find anything, I did find some people explaining how to use variables that get created/processed inside of a function, but that didn't work so I think I have done something wrong in my code.
Note: I am using lambda to call my function (not sure if this is important or not).
TLDR: Text gets too long when too much information is outputted. tk.Text didn't work for me since I couldn't figure out how to use the variable that is created/processed inside of a function that is only called when the button is pressed.
Here is my entire code: https://pastebin.com/1MkdRjVE
Code for my function:
def start_calc():
output_array = ["placehold"]
start_text.set("Loading...")
i = 1
global e1
global e2
output_array.clear()
string = e1.get()
string2 = e2.get()
integr = int(string)
integr2 = int(string2)
if string == "":
error_message.set("Please enter correct numbers.")
elif string2 == "":
error_message.set("Please enter correct numbers.")
else:
while integr2 >= i:
calc = integr ** i
calcstr = (str(calc))
output_array.append(calcstr)
i += 1
start_text.set("Start!")
output_array_str = (', '.join(output_array))
output_msg.set("Output: " + output_array_str)
print(output_array_str) #This is just so I know if it's working or not in the terminal
Code for my output:
output_msg = tk.StringVar()
output_text = tk.Label(root, textvariable=output_msg, font="Raleway")
output_msg.set("Output: ")
output_text.grid(columnspan=3, column=0, row=14)
I think this is what you are looking for:
#Imports
import tkinter as tk
#Variables
root = tk.Tk()
#Tkinter GUI setup basic
canvas = tk.Canvas(root, width= 400, height=400)
canvas.grid(columnspan=3, rowspan=120)
#Title
text = tk.Label(root, text="Calculating factorials", font="Raleway")
text.grid(column=1, row=1)
#Function
def start_calc():
output_array = ["", ""]
start_text.set("Loading...")
i = 1
global e1
global e2
output_array.clear()
string = e1.get()
string2 = e2.get()
integr = int(string)
integr2 = int(string2)
if string == "":
error_message.set("Please enter correct numbers.")
elif string2 == "":
error_message.set("Please enter correct numbers.")
else:
while integr2 >= i:
calc = integr ** i
calcstr = (str(calc))
output_array.append(calcstr)
i += 1
start_text.set("Start!")
output_array_str = (', '.join(output_array))
# Change the output
output_text.config(state="normal")
# delete last output:
output_text.delete("0.0", "end")
# insert new output:
output_text.insert("end", output_array_str)
output_text.config(state="disabled")
print(output_array_str) #This is just so I know if it's working or not in the terminal
#input
tk.Label(root, text="Number :").grid(row=10)
tk.Label(root, text="Factorial :").grid(row=11)
e1 = tk.Entry(root)
e2 = tk.Entry(root)
e1.grid(row=10, column=1)
e2.grid(row=11, column=1)
#Error message if the input is invalid
error_message = tk.StringVar()
error_text = tk.Label(root, textvariable=error_message, font="Raleway")
error_message.set(" ")
error_text.grid(column=1, row=12)
#Startbutton
start_text = tk.StringVar()
start_btn = tk.Button(root, textvariable=start_text, command=start_calc, font="Raleway", bg="#20bebe", fg="white", height=2, width=15)
start_text.set("Start!")
start_btn.grid(column=1, row=13, pady=10)
#output
output_text = tk.Text(root, height=1, width=20, wrap="none", font="Raleway")
output_text.insert("end", "Output")
output_text.config(state="disabled")
output_text.grid(columnspan=3, column=0, row=14, sticky="news")
#Adding a scrollbar
scrollbar = tk.Scrollbar(root, orient="horizontal", command=output_text.xview)
scrollbar.grid(columnspan=3, column=0, row=15, sticky="news")
output_text.config(xscrollcommand=scrollbar.set)
#disclaimer message
disclaimer_text = tk.Label(root, text="Disclaimer: The factorials will be printed from 1 to the number you entered.")
disclaimer_text.grid(columnspan=3, column=0, row=110)
root.mainloop()
I used a <tkinter.Text> widget with wrap="none", height=1 and width=20 to make the output box. I disabled the entry so that the user can't change the results but can still copy it.

How do I pass arguments and get return values from a tkinter button press function?

I am trying to get the word entered in the field(exp_textbox) to be passed as an arguement to the function(definition).
This is the code below for the dictionary app.
the json file is a python dictionary of words and their meaning. Is there a way i could do this?
import tkinter
import json
import difflib
data = json.load(open('data.json'))
main_window = tkinter.Tk()
def definition(w):
w = w.lower()
match_word = difflib.get_close_matches(w, data.keys())
if w in data:
result = data[w]
return result
elif len(match_word) > 0:
answer = input(f"Did you mean '{match_word[0]}'? [Y/N]").upper()
if answer == 'Y':
result = data[match_word[0]]
return result
elif answer == 'N':
return f"'{w}' is not in my dictionary"
else:
return 'command not understood'
else:
return f"'{w}' is not in my dictionary"
# Window Title
main_window.title('Dictionary')
main_window.geometry('320x320')
# Expression Frame
exp_frame = tkinter.Frame(main_window)
exp_frame.grid(row=0, column=0, columnspan=3, sticky='new')
exp_label = tkinter.Label(exp_frame, text='Enter your Word Here: ')
exp_label.grid(row=0, column=0)
The word provided in the field below should be passed to the function(definition) as an arguement.
exp_textbox = tkinter.Entry(master=exp_frame)
exp_textbox.grid(row=0, column=1)
exp_label = tkinter.Button(exp_frame, text='Search', command=definition(exp_textbox.get()))
exp_label.grid(row=0, column=3)
# Definition Frame
def_frame = tkinter.Frame(main_window)
def_frame.grid(row=2, column=0, columnspan=3, sticky='new')
def_label = tkinter.Label(def_frame, text='Definition is : ')
def_label.grid(row=2, column=0)
The return value of the function would then be returned here for the user.
def_textbox = tkinter.StringVar()
tkinter.Entry(def_frame, textvariable=def_textbox).grid(row=2, column=1)
main_window.mainloop()
So there are a couple of problems evident.
Running the function on button press
The first issue is that when you are creating the button you immediately run the definition function, instead of only running it when the button is pressed. How to pass arguments to a Button command in Tkinter? has some solutions to this issue, but a simple addition would be:
exp_label = tkinter.Button(exp_frame, text='Search', command=lambda: definition(exp_textbox.get()))
Getting the result of running the function
The next issue is that you are returning the result of checking the definition to the point of call (to the Button object) which does not know what to do with this. A quick way to work around this would be to set the value in the textbox directly in the function itself:
Move the definition of your def_textbox Stringvar above the button
Pass the def_textbox to your button command
Instead of returning the result, use set to change the textbox
Giving final code like:
import tkinter
import json
import difflib
data = json.load(open('data.json'))
main_window = tkinter.Tk()
def definition(w, txtbox):
print(f'In definition with {w}')
w = w.lower()
match_word = difflib.get_close_matches(w, data.keys())
if w in data:
result = data[w]
txtbox.set(result)
elif len(match_word) > 0:
answer = input(f"Did you mean '{match_word[0]}'? [Y/N]").upper()
if answer == 'Y':
result = data[match_word[0]]
txtbox.set(result)
elif answer == 'N':
txtbox.set(f"'{w}' is not in my dictionary")
else:
txtbox.set('command not understood')
else:
txtbox.set(f"'{w}' is not in my dictionary")
# Window Title
main_window.title('Dictionary')
main_window.geometry('320x320')
def_textbox = tkinter.StringVar()
# Expression Frame
exp_frame = tkinter.Frame(main_window)
exp_frame.grid(row=0, column=0, columnspan=3, sticky='new')
exp_label = tkinter.Label(exp_frame, text='Enter your Word Here: ')
exp_label.grid(row=0, column=0)
exp_textbox = tkinter.Entry(master=exp_frame)
exp_textbox.grid(row=0, column=1)
exp_label = tkinter.Button(exp_frame, text='Search', command=lambda: definition(exp_textbox.get(), def_textbox))
exp_label.grid(row=0, column=3)
# Definition Frame
def_frame = tkinter.Frame(main_window)
def_frame.grid(row=2, column=0, columnspan=3, sticky='new')
def_label = tkinter.Label(def_frame, text='Definition is : ')
def_label.grid(row=2, column=0)
tkinter.Entry(def_frame, textvariable=def_textbox).grid(row=2, column=1)
main_window.mainloop()

Using python tkinter library, how to write a function that checks if a textbox is checked?

I'm trying to see what checkbox are checked and write a if/else function to do stuff. The number of check boxes depends on the number of topics I parse into the program and create a checkbox for each item.
I added:
chk_state = IntVar()
But this is only good if you are using one checkbox.
I am using a list to generate all my checkboxes:
Which generates these variables for each checkbox:
'chk0', 'chk1', 'chk2', 'chk3', 'chk4', 'chk5', 'chk6', 'chk7', 'chk8', 'chk9', 'chk10', 'chk11', 'chk12', 'chk13', 'chk14', 'chk15', 'chk16', 'chk17', 'chk18', 'chk19', 'chk20', 'chk21', 'chk22', 'chk23', 'chk24']
from tkinter import *
from tkinter import messagebox
from reader import openit
import sys
data = openit(sys.argv[1])
window = Tk()
#set size of window
window.geometry('850x400')
window.title("Chose Your ROS Topic" )
lbl = Label(window, text="Topics", font=("Arial Bold", 25))
lbl.grid(column=0,row=0)
#check checkbox value boolean
chk_state = IntVar()
#chk_state.set(0) #uncheck
#chk_state.set(1) #checked
#Looping through list and adding each one as a checked button
counter = 0
selected_list = []
for x in data.split(","):
# global selected_list
#print(x)
#print(counter)
name = "chk" + str(counter)
# appends each checkbox name to a list
selected_list.append(name)
name = Checkbutton(window, text='%s' % x , font=(15), onvalue=1, offvalue=0, variable=chk_state)
if counter == 0:
name.grid(column=1, row=1)
#print('only for counter 0')
else:
name.grid(column=1, row=1+counter -1)
#print("the rest")
counter += 1
#After selecting all the topics you want to graph
def topics_selected():
#messagebox.showinfo('Topics picked', 'graphing all your checked topics')
#for topics in
if chk_state.get():
print("some checked topics")
else:
print("Nothing is checked")
# Adding input tkinter textbox
txt = Entry(window,width=10)
txt.grid(column=1,row=0)
# Function that changes buttond
def inputcheck():
res = "Topics picked " + txt.get()
lbl.configure(text = res)
def clicked():
lbl.configure(text="Parser was clicked, checking rosbag")
# Adding button widget
btn = Button(window, text="ROS topic parser", bg="orange", fg="black", command=topics_selected)
btn.grid(column=2, row=1)
#Create a checkbox
#chk = Checkbutton(window, text='Choose')
#chk.grid(column=0, row=4)
window.mainloop()
if __name__ == "__main__":
pass
#print(data)
I want to be able to add whatever was selected to a list and push that list to another function.
You need to create a tkinter variable for each Checkbutton. Right now all you Checkbutton shares the same variable chk_state.
To make this work, simply move your definition of IntVar inside the for loop:
...
selected_list = {} #use a dict to store name/IntVar pair; can use a list also
for num, x in enumerate(data.split(",")): #use enumerate to get a num count
chk_state = IntVar() #create a new IntVar in each iteration
selected_list[num] = chk_state #save name/IntVar pair
name = Checkbutton(window, text='%s' % x , font=(15), onvalue=1, offvalue=0, variable=chk_state)
if num == 0:
name.grid(column=1, row=1)
else:
name.grid(column=1, row=1+num-1)
#After selecting all the topics you want to graph
def topics_selected():
if any(s.get() for s in selected_list.values()): #check if any checkbutton is checked
print ("some checked topics")
print ([s.get() for s in selected_list.values()])
else:
print("Nothing is checked")
You could use tk.BooleanVar for each of your check boxes, and set their values inside a for loop.
Keeping the variables in a list allows you to pass the selection to a function.
import tkinter as tk
DEFAULTS = [True, False, False, False]
def display_selected_options(options, values):
for option, value in zip(options, values):
print(f'{option}: {value.get()}')
def create_option_selectors(frame, options, option_variables) -> None:
for idx, option in enumerate(options):
option_variables[idx].set(DEFAULTS[idx])
tk.Checkbutton(frame,
variable=option_variables[idx],
onvalue=True,
offvalue=False,
text=option,
).pack(side=tk.LEFT)
root = tk.Tk()
options = ['chk0', 'chk1', 'chk2', 'chk3']
option_variables = [tk.BooleanVar(root) for _ in range(len(options))]
frame = tk.Frame(root)
create_option_selectors(frame, options, option_variables)
frame.pack()
display_options = tk.Button(root, text='validate', command=lambda options=options,
values=option_variables: display_selected_options(options, values))
display_options.pack()
root.mainloop()
Alternatively, you could use a dictionary to store the option -> value pairs:

Categories

Resources