On this code I'm trying to get working a Settings program, in which you can disable or enable the log. This code renders a Window, with a Settings button, when you press that button, it opens a new window with two Radio Button's (Enable/Disable), and the program should determine the current status of the setting, but I can't get it to work, because the variable (X) determines what option should be selected by default, according to the current status, but it doesn't work. Please help me!.
from msilib.schema import RadioButton
from tkinter import *
import tkinter as asset1
import tkinter
settings = {"overrideAdminReq" : True} # DEFAULT SETTING.
def showLogSettingToFalse(): # WHEN DISABLE BUTTON IS PRESSED.
settings["overrideAdminReq"] = False # SET SETTING TO FALSE.
print("Log was disabled")
def showLogSettingToTrue(): # WHEN ENABLE BUTTON IS PRESSED.
settings["overrideAdminReq"] = True # SET SETTING TO TRUE.
print("Log was enabled")
def showSettings(asset1): # WHEN SETTINGS BUTTON IS PRESSED.
settingsWindow = Tk() # NEW WINDOW
settingsWindow.title("Settings")
settingsWindowGrid = asset1.Frame(settingsWindow, padx=2)
settingsWindowGrid.pack()
x = IntVar() # DEFINES THE VARIABLE
if settings["overrideAdminReq"] == True: y=1 # IF SETTING IS TRUE, DEFINES Y = 1
else: y=2 # IF SETTING IS FALSE, DEFINES Y = 2
x.set(value=y) # SETS THE VALUE OF X WITH Y
print("Log status: "+str(settings["overrideAdminReq"]))
Label(settingsWindowGrid, text="Log Functionality:").grid(row=1,column=0) # TITLE LABEL.
enableFunct = Radiobutton(settingsWindowGrid, # ENABLE OPTION.
text="Enable",
value=1, # OPTION VALUE
variable=x,
command=lambda: showLogSettingToTrue())
enableFunct.grid(row=1,column=1)
disableFunct = Radiobutton(settingsWindowGrid, # DISABLE OPTION.
text="Disable",
value=2, #OPTIONE VALUE
variable=x, #VARIABLE
command=lambda: showLogSettingToFalse())
disableFunct.grid(row=2,column=1)
settingsWindow.mainloop()
w1 = Tk()
button_1 = tkinter.Button(w1, text='Settings', padx=30, pady=5, command=lambda: showSettings(asset1), borderwidth=5)
button_1.grid(row=1, column=0, pady=2)
w1.mainloop()
Related
I am new to tkinter application. The below code is working fine. Please help how to implement mentioned features.
The dynamic value should be displayed above clear button or below the combo box ( Used pack is bottom )- Now working
Clear the label value on combo box selection.
import tkinter as tk
from tkinter import ttk
from tkinter import *
from datetime import datetime
# root window
root = tk.Tk()
root.geometry("500x350")
root.resizable(False, False)
root.title('Test')
# Log Generator in frame
Generator = tk.Frame(root)
Generator.pack(padx=10, pady=10, fill='x', expand=True)
def clear():
combo.set('')
# Function to print the index of selected option
# in Combobox
def get_log_file_name(*arg):
date_Value = datetime.now().strftime("%Y_%m_%d_%I%M%S")
output_file_name_value = "Log_"+date_Value
if var.get() == "apple":
Label(Generator, text="The value at index: "+output_file_name_value+".txt", font=('Helvetica 12')).pack()
else:
Label(Generator, text="The value at index: "+output_file_name_value+".html", font=('Helvetica 12')).pack()
# Define Tuple of months
months = ('apple','banana')
# Create a Combobox widget
label = ttk.Label(Generator, text="Selection_Option:",font=('Helvetica', 10, 'bold'))
label.pack(fill='x', expand=True)
var = StringVar()
combo = ttk.Combobox(Generator, textvariable=var)
combo['values'] = months
combo['state'] = 'readonly'
combo.pack(padx=5, pady=5)
# Set the tracing for the given variable
var.trace('w', get_log_file_name)
# Create a button to clear the selected combobox
# text value
button = Button(Generator, text="Clear", command=clear)
button.pack(side=left)
# Make infinite loop for displaying app on
# the screen
Generator.mainloop()
Clear the label value on combo box selection.
You need to capture the ComboboxSelect event to do that and the function to execute if captured
the function should be like this
What you want to do here, is to capture the combobox event, and then, do the label configuration when capturing it,
Below is the code to do the thing. and you can add code there.
def comboboxEventCapture(e=None):
label.configure(text='')
# Your code after resetting variables!
Here's the event capturing part
combo.bind("<<ComboboxSelect>>", comboboxEventCapture)
You can name the function whatever you want though.
Note that the arguement e is needed because if the event is captured, the event itself is passed as a parameter into the function, that is of no use here (unless you are going to do something with it, then use e.objname)
The dynamic value should be displayed above clear button
The second label could be outside of get_log_file_name() function.
And also configure inside function. So you don't do duplicate Label widget, naming Label2
Also the pack() must be split to prevent an error.
To clear Label2 use .configure(text='')
We will be using ttk. So don't do this from tkinter import *
Code:
import tkinter as tk
from tkinter import ttk
from datetime import datetime
root = tk.Tk()
root.geometry("500x350")
root.resizable(False, False)
root.title('Test')
Generator = tk.Frame(root)
Generator.pack(padx=10, pady=10, fill='x', expand=True)
def clear():
label2.configure(text='')
def get_log_file_name(*arg):
date_Value = datetime.now().strftime("%Y_%m_%d_%I%M%S")
output_file_name_value = "Log_"+date_Value
if var.get() == "apple":
label2.configure(text="The value at index: "+output_file_name_value+".txt", font=('Helvetica 12'))
else:
label2.configure(text="The value at index: "+output_file_name_value+".html", font=('Helvetica 12'))
# Define Tuple of months
months = ('apple','banana')
# Create a Combobox widget
label2 = ttk.Label(Generator)
label2.pack()
label = ttk.Label(Generator, text="Selection_Option:",font=('Helvetica', 10, 'bold'))
label.pack(fill='x', expand=True)
var = tk.StringVar()
combo = ttk.Combobox(Generator, textvariable=var)
combo['values'] = months
combo['state'] = 'readonly'
combo.pack(padx=5, pady=5)
# Set the tracing for the given variable
var.trace('w', get_log_file_name)
# Create a button to clear the selected combobox
# text value
button = ttk.Button(Generator, text="Clear", command=clear)
button.pack(side='left')
# Make infinite loop for displaying app on
# the screen
Generator.mainloop()
Screenshot for apple:
Screenshot for banana:
Screenshot to clear Label2:
Working on a project in which I use Tkinter in order to create a GUI that gives a list of software in a drop-down and when a particular software is chosen, it takes you to a separate window where a user's name will be entered and they would be added to a database. With the code I have so far, I am able to link a "submit" button on the second window to a function that prints a confirmation message as a test to make sure the button works. My issue now is trying to get the input from the entry field and link the input to the "Submit" button but I can't seem to find a way to do so. I was wondering if I could get some advice on how to go about this. Would classes need to be used in order to make it work? or can I stick with functions and keep the code relatively simple?
I have added the code for my program below.
import tkinter as tk
from tkinter import *
from tkinter import ttk
root = tk.Tk() # Main window
root.title("Software Licences")
root.geometry("300x300")
frame = ttk.Frame(root, padding="50 0 50 50")
frame.pack(fill=tk.BOTH, expand=True)
tkvar = StringVar()
choices = ['Imagenow', # Dropdown menu with software options
'FileMakerPro',
'Acrobat',
'Office',
'Lotus Notes']
tkvar.set('Acrobat') # Shows default dropdown menu option when program is opened
popupMenu = OptionMenu(frame, tkvar, *sorted(choices))
popupLabel = ttk.Label(frame, text="Choose Software")
popupLabel.pack()
popupMenu.pack()
def software_pages(): # In this function is the 2nd window with for each individual software
top = Toplevel()
top.title("Software Licences")
top.geometry("300x300")
myLabel = Label(top, text=tkvar.get()).pack()
employee_entrylbl = Label(top, text="Employee name").pack()
employee_entry = Entry(top, width=25, textvariable=tk.StringVar) # Entry field for adding user's name
employee_entry.pack() # Entry field is displayed
if tkvar.get() == "Acrobat": # for each if statement, button command is link to the functions
# defined below
button = ttk.Button(top, text="Submit", command=add_to_acrobat).pack()
elif tkvar.get() == "Imagenow":
button = ttk.Button(top, text="Submit", command=add_to_imagenow).pack()
elif tkvar.get() == "FileMakerPro":
button = ttk.Button(top, text="Submit", command=add_to_filemakerpro).pack()
elif tkvar.get() == "Office":
button = ttk.Button(top, text="Submit", command=add_to_office).pack()
else:
button = ttk.Button(top, text="Submit", command=add_to_lotusnotes).pack()
exit_button = ttk.Button(top, text="Exit", command=top.destroy).pack() # Exit button for second window
add_emp_button = ttk.Button(frame, text="Next", command=software_pages) # "Next" button in the main window takes the
# user to the second window
add_emp_button.pack()
# Functions below are linked to the button commands of each software in the second window function defined earlier.
# They print out specified messages that confirm the user had been added
def add_to_acrobat():
return print("User added to Acrobat")
def add_to_lotusnotes():
print("User added to IBM")
def add_to_imagenow():
print("User added to imagenow")
def add_to_office():
print("User added to 365")
def add_to_filemakerpro():
print("User added to FMP")
def click_button(): # Function for Exit button for main window
root.destroy()
exit_button = ttk.Button(frame, text="Exit", command=click_button) # Exit button for main window
exit_button.pack()
root.mainloop()
You can pass parameters to the command of tkinter.command using partial from the functools module.
in your case:
button = ttk.Button(top, text="Submit", command=partial(add_to_acrobat, employee_entry)).pack()
in the above line, I send the employee_entry(Which holds your desired text) to the add_to_acrobat function
and the add_acrobat function should look like this:
def add_to_acrobat(e):
print(e.get())
return print("User added to Acrobat")
Hope it helps
I am trying to figure out how to use tkinter radio-buttons properly.
I have used this question as a guideline: Radio button values in Python Tkinter
For some reason I can't figure out how to return a variable that is indicative of what the user selected.
Code:
def quit_loop():
global selection
selection = option.get()
root.quit()
return selection
def createWindow():
root = Tk()
root.geometry=('400x400')
option = StringVar()
option.set('none')
R1 = Radiobutton(root, text='Compile', value = 'Compile', var=option)
R2 = Radiobutton(root, text='Create', value = 'Create', var=option)
button = Button(root, text='ok', command=quit_loop)
R1.pack()
R2.pack()
button.pack()
root.mainloop()
when I call createWindow() I would expect the radio-button box to pop up, and after making my selection and pressing 'ok' I expected it to return me a variable selection which relates to the selected button. Any advice? Tkinter stuff is particularly challenging to me because it seems so temperamental.
You need to make option global if you want to access outside of createWindow
Here's an example of your code that will print out the value of the selected radiobutton and then quit when you click the button. I simply had to declare root and options as global:
from tkinter import *
def quit_loop():
global selection
selection = option.get()
root.quit()
return selection
def createWindow():
global option, root
root = Tk()
root.geometry=('400x400')
option = StringVar()
option.set('none')
R1 = Radiobutton(root, text='Compile', value = 'Compile', var=option)
R2 = Radiobutton(root, text='Create', value = 'Create', var=option)
button = Button(root, text='ok', command=quit_loop)
R1.pack()
R2.pack()
button.pack()
root.mainloop()
createWindow()
As far as I know one needs to do two things to communicate with tkinter
widgets: pass a variable, and pass a command. When user interacts with
widgets, tkinter will do two things: update value of variable and call the
function passed in as command. It is up to us to access the value of the
variable inside the command function.
import tkinter as tk
from tkinter import StringVar, Radiobutton
def handle_radio():
print(option.get())
root = tk.Tk()
option = StringVar()
option.set('none')
R1 = Radiobutton(root, text='Compile', value = 'Compile', var=option, command=handle_radio)
R2 = Radiobutton(root, text='Create', value = 'Create', var=option, comman=handle_radio)
R1.pack()
R2.pack()
root.mainloop()
The code prints 'Create' and 'Compile' when user selects the appropriate
radio option.
Hope this helps.
Regards,
Prasanth
I'm trying to make a button like a switch, so if I click the disable button
it will disable the "Button" (that works). And if I press it again, it will enable it again.
I tried things like if, else but didn't get it to work.
Here's an example:
from tkinter import *
fenster = Tk()
fenster.title("Window")
def switch():
b1["state"] = DISABLED
#--Buttons
b1=Button(fenster, text="Button")
b1.config(height = 5, width = 7)
b1.grid(row=0, column=0)
b2 = Button(text="disable", command=switch)
b2.grid(row=0,column=1)
fenster.mainloop()
A Tkinter Button has three states : active, normal, disabled.
You set the state option to disabled to gray out the button and make it unresponsive. It has the value active when the mouse is over it and the default is normal.
Using this you can check for the state of the button and take the required action. Here is the working code.
from tkinter import *
fenster = Tk()
fenster.title("Window")
def switch():
if b1["state"] == "normal":
b1["state"] = "disabled"
b2["text"] = "enable"
else:
b1["state"] = "normal"
b2["text"] = "disable"
#--Buttons
b1 = Button(fenster, text="Button", height=5, width=7)
b1.grid(row=0, column=0)
b2 = Button(text="disable", command=switch)
b2.grid(row=0, column=1)
fenster.mainloop()
The problem is in your switch function.
def switch():
b1["state"] = DISABLED
When you click the button, switch is being called each time. For a toggle behaviour, you need to tell it to switch back to the NORMAL state.
def switch():
if b1["state"] == NORMAL:
b1["state"] = DISABLED
else:
b1["state"] = NORMAL
Am trying to make GUI app which compulsory you have to select one of predict button before the number entered will be printed to the terminal,if none of predictbutton is selected the should print outselect predict button to proceed.
In pseudecode something like:
def check:
now = new.get()
if no lotto_button is selected:
print("select predict button to proceed")
else:
print(now)
But having challenges:
1:when i select one predict button both buttons raised.
2:How to make the predict compulsory to be selected before the content in the entry will be printed.
import tkinter as tk
def terminal():
now = new.get()
print(now)
def start_func():
lotto_button.configure(relief=tk.SUNKEN, state=tk.DISABLED)
lotto_button1.configure(relief=tk.SUNKEN, state=tk.DISABLED)
def stop_func():
lotto_button.configure(relief=tk.RAISED, state=tk.ACTIVE)
lotto_button1.configure(relief=tk.RAISED, state=tk.ACTIVE)
root = tk.Tk()
root.geometry("400x400")
new = tk.StringVar()
en = tk.Entry(root, textvariable=new).pack()
lotto_button = tk.Button(root, text="predict one", command=start_func)
lotto_button.pack(side="left")
lotto_button1 = tk.Button(root, text="predict two", command=start_func)
lotto_button1.pack()
tk.Button(root, text="print number", command=lambda :[stop_func(),
terminal()]).place(x=150, y=300)
root.mainloop()
Thank you and your advice to do is welcome.
As for making it compulsory for picking, you can define a flag in outermost scope (in same level as root = tk.Tk()) so that you can see in your functions if it's set or not like:
isPredicted = False
And as for disabling each button when one is picked, you can define your your start_func such that it takes button object (lotto_button or lotto_button1) as argument:
def start_func(button_object):
global isPredicted
isPredicted = True
button_object.configure(relief=tk.SUNKEN, state=tk.DISABLED)
To be able to use this function, you need to configure your buttons in the following way, so that they pass themselves as the argument:
lotto_button.configure(command=lambda button_object=lotto_button: start_func(button_object))
lotto_button1.configure(command=lambda button_object=lotto_button1: start_func(button_object))
You should have isPredicted flag in your stop_func as well so that it unsets it:
def stop_func():
global isPredicted
isPredicted = False
lotto_button.configure(relief=tk.RAISED, state=tk.ACTIVE)
lotto_button1.configure(relief=tk.RAISED, state=tk.ACTIVE)
As for your terminal function, you'd want to act based on the state of isPredicted so it needs to be defined as:
def terminal():
global isPredicted
if isPredicted:
now = new.get()
print(now)
else:
print("select predict button to proceed")
finally in your "print number" button you need to swap the order of the functions in lambda or isPredicted is always False as far as that button's command is concerned:
tk.Button(root, text="print number", command=lambda :[terminal(),
stop_func()]).place(x=150, y=300)
Your final code should look like:
import tkinter as tk
from tkinter import messagebox
def terminal():
global isPredicted
if isPredicted:
now = new.get()
print(now)
else:
print("select predict button to proceed")
def start_func(button_object):
global isPredicted
isPredicted = True
button_object.configure(relief=tk.SUNKEN, state=tk.DISABLED)
def stop_func():
global isPredicted
isPredicted = False
lotto_button.configure(relief=tk.RAISED, state=tk.ACTIVE)
lotto_button1.configure(relief=tk.RAISED, state=tk.ACTIVE)
root = tk.Tk()
root.geometry("400x400")
new = tk.StringVar()
en = tk.Entry(root, textvariable=new).pack()
isPredicted = False
lotto_button = tk.Button(root, text="predict one")
lotto_button.configure(command=lambda button_object=lotto_button: start_func(button_object))
lotto_button.pack(side="left")
lotto_button1 = tk.Button(root, text="predict two")
lotto_button1.configure(command=lambda button_object=lotto_button1: start_func(button_object))
lotto_button1.pack()
tk.Button(root, text="print number", command=lambda :[terminal(),
stop_func()]).place(x=150, y=300)
root.mainloop()
When you're clicking on one of the button prediction, both are raised because in your function start_func, you're configuring both.
Instead of configuring both of them you can bind an event click and getting the widget in start_func like this:
lotto_button = tk.Button(root, text="predict one")
lotto_button.bind('<1>', start_func)
lotto_button.pack(side="left")
And then in your start_func :
def start_func(event):
w = event.widget
w.configure(relief=tk.SUNKEN, state=tk.DISABLED)
About your second point, I'm not sure to understand what you mean.
Using Radiobutton widgets tends to be better for this sort of multiple choice processing.
Radiobuttons belong to "groups" which means that you can set them up so that one always needs to be selected by default. This means that you don't need to have any kind of error catching or display any sort of instruction to the user, it just intuitively works.
from tkinter import *
root = Tk()
def command(v, entry):
print(v.get(), entry.get())
v = StringVar()
v.set(1)
entry = Entry(root)
rb1 = Radiobutton(root, text="Predict One", variable=v, value=1, indicatoron=0)
rb2 = Radiobutton(root, text="Predict Two", variable=v, value=2, indicatoron=0)
button = Button(root, text="Print Number", command=lambda:command(v, entry))
entry.pack()
rb1.pack()
rb2.pack()
button.pack()
root.mainloop()
So we create a StringVar() which we use to define which Radiobutton widgets should be linked together and then we set it's value to 1 which is the value of the "Predict One" button. If the user presses the other Radiobutton then the value changes to 2 which means the first button "unpresses" and the value of the StringVar() is changed to 2.