I'm trying to create a GUI to collect three inputs from a user, where the first input has two options (based on a Listbox), like the image below (where the option "NACA" is selected):
The problem is with the Listbox. I guess the options are overlapping each other. For example, If I select the NACA option (image above), and then I select the .txt option, some part of the NACA label remains:
And of course, just the labels are appearing, not the entry_boxes to type inside (if I delete the part of the listBox, the entry_boxes of the last two input appers, so I really guess the problem is with the ListBox)
import tkinter as tk
root = tk.Tk()
root.geometry('400x300')
root.resizable(0, 0)
menu_inicial = tk.Canvas(root, width = 400, height = 300)
menu_inicial.pack()
def naca_box():
naca_entry_box = tk.Entry(menu_inicial)
menu_inicial.create_window(200, 30, window=naca_entry_box)
naca_label = tk.Label(root, text="Enter NACA:")
naca_label.pack()
naca_label.place(x=50, y = 50)
def txt_box():
txt_entry_box = tk.Entry(menu_inicial)
menu_inicial.create_window(200, 30, window=txt_entry_box)
txt_label = tk.Label(root, text="Enter .txt:")
txt_label.pack()
txt_label.place(x=50, y = 50)
def aoa_box():
aoa_entry_box = tk.Entry(root)
menu_inicial.create_window(200, 60, window=aoa_entry_box)
aoa_label = tk.Label(root, text="Enter AoA (º):")
aoa_label.pack()
aoa_label.place(x=50, y = 80)
def panel_box():
panel_entry_box = tk.Entry(root)
menu_inicial.create_window(200, 90, window=panel_entry_box)
panel_label = tk.Label(root, text="Enter Nº Panels:")
panel_label.pack()
panel_label.place(x=40, y = 110)
def update_box(*args):
selection = box_list.curselection()
lb_value.set(options[selection[0]] )
if selection[0] == 0:
naca_box()
else:
txt_box()
options = ['NACA', '.txt']
listCon = tk.StringVar(value=options)
box_list = tk.Listbox(menu_inicial, listvariable=listCon, width=10, height=2, selectmode=tk.SINGLE)
box_list.grid(row=0, column=0)
box_list.bind('<<ListboxSelect>>', update_box)
lb_value=tk.StringVar()
aoa_box()
panel_box()
root.mainloop()
How can I proceed with this? Is a problem with the "IF" statement to choose the options ? (I don't know if this is the best what to do this...)
The problem is that while you clicking button each time,
you are creating label each time,
if you want to change the text in the label you created,use 'config()'
change your code like this,
sample_label=tk.Label(root)
sample_label.place(x=50, y = 50)
def naca_box():
naca_entry_box = tk.Entry(menu_inicial)
menu_inicial.create_window(200, 30, window=naca_entry_box)
sample_label.config(text="Enter NACA:")
def txt_box():
txt_entry_box = tk.Entry(menu_inicial)
menu_inicial.create_window(200, 30, window=txt_entry_box)
sample_label.config(text="Enter .txt:")
Related
I made this program in Tkinter in python where a small window pops up when the code is run and a start button would pop up and make the window full screen and show the content after. I want to make the button destroy itself after I press it so it makes a fullscreen and removes the button. I am still a beginner and would like the answer to be simple. The solution I am looking for is to maybe destroy the button completely(preferred) or move it way out of sight in the fullscreen window. Here is the code:
import Tkinter as w
from Tkinter import *
w = Tk()
w.geometry("150x50+680+350")
def w1():
w.attributes("-fullscreen", True)
l1 = Label(w, text = "Loaded!", height = 6, width = 8).pack()
global b1
b1.place(x = -10000, y = -10000)
b1 = Button(w, text = "Start", height = 3, width = 20, command = w1).place(x = 0, y = 10)
b2 = Button(w, text = "Exit", command = w.destroy).place(x = 1506, y = 0)
w.mainloop()
As you can see I want to make button one destroy itself.
Try this:
import tkinter as tk # Use `import Tkinter as tk` for Python 2
root = tk.Tk()
root.geometry("150x50+680+350")
def function():
global button_start
root.attributes("-fullscreen", True)
label = tk.Label(root, text="Loaded!", height=6, width=8)
label.pack()
button_start.place_forget() # You can also use `button_start.destroy()`
button_start = tk.Button(root, text="Start", height=3, width=20, command=function)
button_start.place(x = 0, y = 10)
button_exit = tk.Button(root, text="Exit", command=root.destroy)
button_exit.place(x=1506, y=0)
root.mainloop()
PS: Please read this.
Try:
b1.place_forget()
This will essentially "forget" about the button and hide it from view.
Edit:
If you are getting the error that b1 is None try:
b1 = Button(w, text = "Start", height = 3, width = 20, command = w1)
b1.place(x = 0, y = 10)
You need to add the b1.place() option at the bottom for this to work
thanks a lot for your time. I'm currently stuck at the following point: I have developed a GUI with Tkinter with about 200 entries. (For simplification I have only included a small section below). But these 200 entries are seldom filled in at once. Normally 50 entries are filled in every start of the program. When the program is closed, these filled in values are deleted and have to be filled in again after the program is started again. Is there a way to prevent this?
I do not want to lose the values entered in jobNameA_entry and jobNameB_entry when closing the program.
Many thanks in any case.
import tkinter as tk
class Win1:
def __init__(self, master):
self.master = master
self.master.title("Gap Assessment")
self.topFrame = tk.Frame(self.master)
self.topFrame.grid(row=0, column=0, sticky='news', ipady = 5)
self.A_GapFrame = tk.Frame(self.master)
self.B_GapFrame = tk.Frame(self.master)
self.subframe_AGap()
self.subframe_BGap()
# Create a Tkinter variable
self.gapType = tk.StringVar(self.master)
# Dictionary with optionsverschwinden
self.choiceGap = ['AFrame','BFrame']
# self.choiceGap = sorted(self.choiceGap)
self.gapType.set('') # set the default option
self.ctngMenu = tk.OptionMenu(self.topFrame, self.gapType, *self.choiceGap, command=self.chioseGap_handle)
self.ctngMenu.grid(row = 1, column =2)
def chioseGap_handle(self, selected):
if selected == 'AFrame':
self.A_GapFrame.tkraise()
# self.subframe_AGap()
self.A_GapFrame.place(x=20, y=30, width = 210)
self.B_GapFrame.place_forget()
if selected == 'BFrame':
self.B_GapFrame.tkraise()
# self.subframe_BGap()
self.B_GapFrame.place(x=30, y=70, width = 210)
self.A_GapFrame.place_forget()
def subframe_AGap(self):
self.jobNameA_text = tk.StringVar()
self.jobNameA_entry = tk.Entry(self.A_GapFrame, textvariable = self.jobNameA_text)
self.jobNameA_entry.grid(row=1, column=0, sticky='news')
self.jobNameA_text = tk.StringVar()
self.jobNameA_entry = tk.Entry(self.A_GapFrame, textvariable = self.jobNameA_text)
def subframe_BGap(self):
self.jobNameB_text = tk.StringVar()
self.jobNameB_entry = tk.Entry(self.B_GapFrame, textvariable = self.jobNameB_text)
self.jobNameB_entry.grid(row=2, column=0, sticky='news')
self.jobNameB_text = tk.StringVar()
self.jobNameB_entry = tk.Entry(self.B_GapFrame, textvariable = self.jobNameB_text)
root = tk.Tk()
root.geometry("200x300+50+50")
app = Win1(root)
root.mainloop()
Just like the famous example of having Continent names in one dropdown and display country names related to selected Continent. How to achieve this using Tkinter?
I have Continent list in first dropdown and list of all countries related to continents in the list. I would like to display country_11,country_12 when continent_1 is selected, similarly for other continents.
Here is the piece of code am working on -
import tkinter as tk
from tkinter import ttk
from tkinter import *
root = tk.Tk()
root.geometry('500x500')
#Label to Continent
label_1 = tk.Label(root, text="Select the Continent", font = (8), bg = '#ffe1c4')
label_1.place(x = 120, y = 220)
# Continent selection - drop down
optionList1 = ["Continent1", "Continent2","Continent3"]
dropVar1 = StringVar()
dropMenu1 = ttk.OptionMenu(root, dropVar1 , *optionList1)
dropMenu1.place(x = 300, y = 220)
#Label to Select Country
label_2 = tk.Label(root, text="Select the Country ", font = (8), bg = '#ffe1c4')
label_2.place(x = 120, y = 250)
# Country name selection - drop down
optionList2 = ["Country_11", "Country_12", "Country_21","Country_22","Country_31","Country_32"]
dropVar2 = StringVar()
dropMenu2 = ttk.OptionMenu(root, dropVar2, *optionList2)
dropMenu2.place(x = 300, y = 250)
root.mainloop()
Would be great to have a solution to this as am not aware of all the attributes OptionMenu can have in Tkinter.
Thanks in advance!!
If your mean is to create two OptionMenu and it will show the different value when select different value in the first dropdown menu.
You can try this:
import tkinter as tk
from tkinter import ttk
from tkinter import *
def func(selected_value): # the selected_value is the value you selected in the first drop down menu.
dropMenu2.set_menu(*optionList2.get(selected_value))
root = tk.Tk()
root.geometry('500x500')
#Label to Continent
label_1 = tk.Label(root, text="Select the Continent", font = (8), bg = '#ffe1c4')
label_1.place(x = 120, y = 220)
# Continent selection - drop down
optionList1 = ["-","Continent1", "Continent2","Continent3"]
dropVar1 = StringVar()
dropMenu1 = ttk.OptionMenu(root, dropVar1 , *optionList1,command=func) # bind a command for the first dropmenu
dropMenu1.place(x = 300, y = 220)
#Label to Select Country
label_2 = tk.Label(root, text="Select the Country ", font = (8), bg = '#ffe1c4')
label_2.place(x = 120, y = 250)
# Country name selection - drop down
optionList2 = { # when select different value,show the list.
"Continent1": ["Country_11", "Country_12"],
"Continent2": ["Country_21", "Country_22"],
"Continent3": ["Country_31", "Country_32"]
}
dropVar2 = StringVar()
dropMenu2 = ttk.OptionMenu(root, dropVar2, "-")
dropMenu2.place(x = 300, y = 250)
root.mainloop()
Now it is:
When select another value:
(A suggestion:ttk.Combobox is prettier than OptionMenu,and using from tkinter import * is not a good practice.)
If you mean menu inside a menu then it is possible and very simple to do because the menu used in OptionMenu() is a tkinter Menu(), See the documentation of tkinter Menu.
We can access the Menu like so
Op = OptionMenu(root, var, 'Hello', 'HI', 'YOO')
# Op_Menu is the Menu() class used for OptionMenu
Op_Menu = Op['menu']
Here is a small example of nested menus in an option menu. When you select any of the countries inside any continent the text of optionmenu won't change so to fix that I used command argument and in each command argument of country I'm changing the value of the StringVar that is assigned to the optionmenu.
import tkinter as tk
root = tk.Tk()
svar = tk.StringVar()
svar.set('Antarctica')
Op = tk.OptionMenu(root, svar, svar.get())
OpMenu = Op['menu']
Op.pack()
Menu1 = tk.Menu(OpMenu)
OpMenu.add_cascade(label='Africa', menu= Menu1)
Menu1.add_command(label='Algeria', command=lambda: svar.set('Africa - Algeria'))
Menu1.add_command(label='Benin', command=lambda: svar.set('Africa - Benin'))
Menu2 = tk.Menu(Op['menu'])
OpMenu.add_cascade(label='Asia', menu= Menu2)
Menu2.add_command(label='China', command=lambda: svar.set('Asia - China'))
Menu2.add_command(label='India', command=lambda: svar.set('Asia - India'))
root.mainloop()
Hope you find this helpful.
I am new in creating GUI. I am doing it in Python with Tkinter. In my program I calculate following characteristics
def my_myfunction():
my code ...
print("Centroid:", centroid_x, centroid_y)
print("Area:", area)
print("Angle:", angle)
I would like to ask for any help/tips how to display those values in GUI window or how to save them in .txt file so that I can call them in my GUI
Thanks in advance
Tkinter is easy and an easy way to do a GUI, but sometimes it can be frustrating. But you should have read the docs before.
However, you can do in this way.
from tkinter import *
yourData = "My text here"
root = Tk()
frame = Frame(root, width=100, height=100)
frame.pack()
lab = Label(frame,text=yourData)
lab.pack()
root.mainloop()
There are several ways to display the results of any operation in tkiner.
You can use Label, Entry, Text, or even pop up messages boxes. There are some other options but these will probably be what you are looking for.
Take a look at the below example.
I have a simple adding program that will take 2 numbers and add them together. It will display the results in each kind of field you can use as an output in tkinter.
import tkinter as tk
from tkinter import messagebox
class App(tk.Frame):
def __init__(self, master):
self.master = master
lbl1 = tk.Label(self.master, text = "Enter 2 numbers to be added \ntogether and click submit")
lbl1.grid(row = 0, column = 0, columnspan = 3)
self.entry1 = tk.Entry(self.master, width = 5)
self.entry1.grid(row = 1, column = 0)
self.lbl2 = tk.Label(self.master, text = "+")
self.lbl2.grid(row = 1, column = 1)
self.entry2 = tk.Entry(self.master, width = 5)
self.entry2.grid(row = 1, column = 2)
btn1 = tk.Button(self.master, text = "Submit", command = self.add_numbers)
btn1.grid(row = 2, column = 1)
self.lbl3 = tk.Label(self.master, text = "Sum = ")
self.lbl3.grid(row = 3, column = 1)
self.entry3 = tk.Entry(self.master, width = 10)
self.entry3.grid(row = 4, column = 1)
self.text1 = tk.Text(self.master, height = 1, width = 10)
self.text1.grid(row = 5, column = 1)
def add_numbers(self):
x = self.entry1.get()
y = self.entry2.get()
if x != "" and y != "":
sumxy = int(x) + int(y)
self.lbl3.config(text = "Sum = {}".format(sumxy))
self.entry3.delete(0, "end")
self.entry3.insert(0, sumxy)
self.text1.delete(1.0, "end")
self.text1.insert(1.0, sumxy)
messagebox.showinfo("Sum of {} and {}".format(x,y),
"Sum of {} and {} = {}".format(x, y, sumxy))
if __name__ == "__main__":
root = tk.Tk()
myapp = App(root)
root.mainloop()
I am trying to set up validation on text entry boxes. Three of the boxes need to only accept integers and one text as a postcode. I am not sure whether to do this in a function previously defined or when the entry boxes are created. Also how would i make the values from the text entry boxes be accessable in the function QuoteCreation. All my code is below.
from tkinter import *
class quote():
def __init__(self, master):
self.master=master
self.master.title("Quote Screen")
self.master.geometry("2100x1400")
self.master.configure(background = "white")
self.Borras = PhotoImage(file = "Borras.Logo.2.gif") #sets up image
self.Borras.image = self.Borras
self.BorrasLabel = Label(self.master, image = self.Borras, bg = "white")#puts image onto label
self.BorrasLabel.place(anchor=NW)
self.Title = Label(self.master, text = "New Quote", font = ("calibri", 20), bg = "White")
self.Title.place(x=650, y = 10)
self.SubmitButton = PhotoImage(file = "Submit.Button.gif") #sets up image
self.SubmitButton.image = self.SubmitButton
self.SubmitButtonLabel = Button(self.master, image = self.SubmitButton, bg = "white", command= self.QuoteCreation)#puts image onto a button
self.SubmitButtonLabel.place(x=900, y=290)
PostCodeVar = StringVar()
PostCodeEntry = Entry(master,width=50, font=20, textvariable=PostCodeVar)
PostCodeEntry.place(x = 20, y = 150)
PostCodeVar.set("Please enter the Post Code")
PostCodeValue = PostCodeVar.get()
HeightVar = StringVar()
HeightEntry = Entry(master, width=50, font=20, textvariable=HeightVar)
HeightEntry.place(x = 20, y = 220)
HeightVar.set("Please enter the Height")
HeightValue = HeightVar.get()
LengthVar = StringVar()
LengthEntry = Entry(master, width=50, font=20, textvariable=LengthVar)
LengthEntry.place(x = 20, y = 290)
LengthVar.set("Please enter the Length")
LengthValue = LengthVar.get()
PitchVar = StringVar()
PitchEntry = Entry(master, width=50, font=20, textvariable=PitchVar)
PitchEntry.place(x = 20, y = 360)
PitchVar.set("Please enter the Pitch")
PitchValue = PitchVar.get()
RiseVar = StringVar()
RiseEntry = Entry(master, width=50, font=20, textvariable=RiseVar)
RiseEntry.place(x = 20, y = 430)
RiseVar.set("Please enter the Rise")
RiseValue = RiseVar.get()
self.SubmitButton = PhotoImage(file = "Submit.Button.gif")
self.SubmitButton.image = self.SubmitButton
self.SubmitButtonLabel = Button(self.master, image = self.SubmitButton, bg = "white", command= self.QuoteCreation)#puts image onto a button
self.SubmitButtonLabel.place(x=900, y=290)
def on_button(self):
print(self.entry.get())
def QuoteCreation(self):
print(' ')
def quitWindow(self):
self.master.destroy()
def backToWelcome(self):
self.master.destroy()
You would set up separate functions to deal with the validation, when the submit button is pressed.
So, as an example, your submit button may look a bit like this:
submitButton = Button(master, text="Submit", command=validation)
The validation, in your case would then want to carry out these checks:
def validation():
postcode = PostCodeVar.get()
length = LengthVar.get()
pitch = PitchVar.get()
rise = RiseVar.get()
if postcodeCheck(postcode) == True and length.isdigit() == True and pitch.isdigit() == True and rise.isdigit() == True:
#carry out chosen process
In your case, you can try setting the postcode, length, pitch and height variables before calling the function, and setting them as global. The postcode should be created, and if it is okay, the function should then:
return True
...so it matches the outcome of the if statement.
I hope this is what you were looking for, and can adapt the example to your specific problem!