python 3 tkinter: Window does not show with OptionMenu - python-3.x

I'm trying to add a OptionMenu to a frame. If I add the OptionMenu, the window does not open any more. Without it works fine. It works like this:
self.tmp_var = tk.StringVar(self.frm_top)
self.tmp_list = self.get_templates()
self.tmp_list.insert(0, '-- Select a template ---')
self.tmp_var.set(self.tmp_list[0])
as soon I add
self.ddTemplates = tk.OptionMenu(self.frm_top, self.tmp_var, *self.tmp_list)
the window does not open again.
If I run the script from the command line I get
Gleitkomma-Ausnahme
Get the same same effect if I use an example from the web like this:
from tkinter import *
root = Tk()
root.geometry("%dx%d+%d+%d" % (330, 80, 200, 150))
root.title("tk.Optionmenu as combobox")
var = StringVar(root)
# initial value
var.set('red')
choices = ['red', 'green', 'blue', 'yellow','white', 'magenta']
option = OptionMenu(root, var, *choices)
option.pack(side='left', padx=10, pady=10)
button = Button(root, text="check value slected")button.pack(side='left', padx=20, pady=10))

Because I declare all grid rows at one place in code, I overlooked the dynamically added row deeper down the in the code. Add the rowconfig to the grid solved the problem.

Related

"Sticky" paramter doesnt change the window at all

I am just building my first tkinter window and I am a little puzzled. I created a label and a Button and set them in them same row but different columns.
Now the placement of the button changes depending on the length of the text in the label. To fix this I wanted to "stick" the label and the button to east/west respectively and add a small amount of padding.
Now the issue, no matter what variant of "sticky" I add it doesn't affect the placement of anything at all.
Below are the two code variants that all lead to the same output window:
from tkinter import *
def Btt_ShowAll_clicked():
print("klicked")
#create the window
Main_Window = Tk()
#Modify the Window
Main_Window.title("Ressourcen Verwaltung")
Lbl_Descr_a = Label(Main_Window, text = "Einträge einsehen")#Create Label
Lbl_Descr_a.grid(column=0, row=0, padx=10) #Show Label
Btt_ShowAll_a = Button(Main_Window, text="Einträge anzeigen")
Btt_ShowAll_a.bind("<Button-1>",Btt_ShowAll_clicked)#Button click starts function
Btt_ShowAll_a.grid(column=1, row=0, padx=10, pady=10, sticky=W)
#In the line above Change "W" to "E" ord delet the "sticky = W" alltogether and nothing changes in the window
Main_Window.geometry('350x200') #Window size
#Make the windows stay (loop)
Main_Window.mainloop()
What can I do to get the desired output?
Shouldn't "sticky" stick it to the given side and then with padx I should be able to choose how close it is said side?
As far as I know, you have to type sticky='w' instead of sticky=W, should work then.

How do I place a text entry in a colored frame in python using tkinter?

I am making a wireframing tool desktop application for MacOS in python with Tkinter and I have no idea how to have a text entry bar that I can put in a frame that has a background color of black.
I looked up how to try and do this task, but had no luck. I have also tried to ask my coding class teacher if he can help me with this, but he couldn't figure it out either. Can someone try to help me with this?
Here is what I have so far:
from tkinter import *
root = Tk()
root.geometry("1430x840")
def clear_entry(entry):
entry.delete(0, END)
// here is the text entry
entry = Entry(root)
placeholder_text = 'Title'
entry.insert(0, placeholder_text)
entry.bind("<Button-1>", lambda event: clear_entry(entry))
// here is the frame which I want to put it in
frame2 = Frame(root, width=1430, height=56, bg="#292E30")
frame2.pack()
entry.pack(side=TOP, anchor=N)
root.mainloop()
the end result of what I want, this is an edited image with Preview so I can show you what I want it to look like in the end.
Just move your frame2 up and have the entry master set to frame2. To acquire a fully stretched black frame, pass a few more parameters to your pack method:
from tkinter import *
root = Tk()
root.geometry("1430x840")
frame2 = Frame(root, bg="#292E30")
frame2.pack(fill=X,ipady=15)
def clear_entry(entry):
entry.delete(0, END)
entry = Entry(frame2)
placeholder_text = 'Title'
entry.insert(0, placeholder_text)
entry.bind("<Button-1>", lambda event: clear_entry(entry))
entry.pack(side=LEFT, anchor=N)
root.mainloop()

Multiple tkinter labels in notebook tab are not expanding to full length of window

I'm trying to equally distribute three objects/widgets across one row in a ttk notebook tab, but the three objects only expand half of the window.
I'm not sure what controls the number of columns within a tab since columnsspan in tab.grid(row=0, columnspan=3) doesn't appear to change anything. I've also tried various values for rows and columns for every object with .grid. This is only an issue for notebook tabs, rather than a single window.
#!/usr/bin/env python3
from tkinter import ttk
from tkinter import *
root = Tk()
root.title('Title')
root.resizable(width=FALSE, height=FALSE)
root.geometry('{}x{}'.format(750, 750))
nb = ttk.Notebook(root)
nb.grid(row=0, column=0)
# Add first tab
tab1 = ttk.Frame(nb)
#tab1.grid(row=0, column=0)
nb.add(tab1, text='Setup')
# Add row label
lb1 = ttk.Label(tab1, text = 'Parent Directory:')
lb1.grid(row = 1, column = 1)
# Add text entry
txt1 = ttk.Entry(tab1)
txt1.grid(row = 1, column = 2)
# Add selection button
btn1 = ttk.Button(tab1, text="Select")
btn1.grid(row=1, column=3)
root.mainloop()
I'm expecting the columns to span the full length of the window, instead of half the length of the window.
In order to do this using grid you need to use the Frame.columnconfigure([column#], minsize=[minsize]) function.
If you want the text box and button to stretch to fill the space, use the sticky option. (Sticky doesn't really do anything with the label)
Code:
#!/usr/bin/env python3
from tkinter import ttk
from tkinter import *
root = Tk()
root.title('Title')
root.resizable(width=FALSE, height=FALSE)
root.geometry('{}x{}'.format(750, 750))
nb = ttk.Notebook(root, width=750)
nb.grid(row=0, column=0)
# Add first tab
tab1 = ttk.Frame(nb)
#tab1.grid(row=0, column=0)
nb.add(tab1, text='Setup')
# Change the sizes of the columns equally
tab1.columnconfigure(1, minsize=250)
tab1.columnconfigure(2, minsize=250)
tab1.columnconfigure(3, minsize=250)
# Add row label
lb1 = ttk.Label(tab1, text = 'Parent Directory:')
lb1.grid(row = 1, column = 1,sticky=(E,W))
# Add text entry
txt1 = ttk.Entry(tab1)
txt1.grid(row = 1, column = 2,sticky=(E,W))
# Add selection button
btn1 = ttk.Button(tab1, text="Select")
btn1.grid(row=1, column=3,sticky=(E,W))
root.mainloop()
Image of result

OptionMenu not working when using overridedirect on two different windows

I am using Python 3.6 on a mac, in view of creating controls for a heating system using a Raspberry Pi 3. I have created a master Tk window with a canvas in it to display graphics for on/off times. I am using an OptionMenu in a top-level popup window with overridedirect to remove the window decorations. I wish to also use overridedirect on the master Tk window, but when I use these two instances of overridedirect, my OptionMenu ceases to work(it works with just one use of overridedirect). The OptionMenu is displayed in the popup window, but does not drop down when clicked on. It is quite a long program, so I haven't included any of my code as I'm unsure what would be relevant. Any advice would be greatly appreciated!
Didn't think I could do it, which is why I didn't include code(kept getting errors), but managed it in the end!
from tkinter import *
master = Tk()
master.overrideredirect(1) # remove window border
master.geometry('800x480')
canvas_window = Canvas(master, width=800, height=305)
outer_rect = canvas_window.create_rectangle(39, 3, 760, 304, fill="BLUE")
close_button = Button(master, text="close", command=master.destroy)
close_button.pack()
def menu_sel_trg(self):
print("Menu Triggered")
def popup(*self):
popup_win = Toplevel()
popup_win.wm_overrideredirect(1) # remove window border
popup_win.geometry('250x250')
on_hrs_options = range(0, 24, 1)# sets range of list
on_hrs_variable = StringVar(popup_win)
on_hrs_variable.set(1)# menu default value
menu_on_hours = OptionMenu(popup_win, on_hrs_variable, *on_hrs_options, command=menu_sel_trg)
menu_on_hours.pack()
close_popup = Button(popup_win, text="Close", command=popup_win.destroy)
close_popup.pack()
canvas_window.tag_bind(outer_rect, '<Button-1>', popup)
canvas_window.pack()
master.mainloop()

Python 3 Radio button controlling label text

I am in the process of learning Python3 and more of a necessity, the TkInter GUI side. I was working my way through a book by James Kelly, when I encountered this problem. All his examples made a new window with just label/canvas/check box etc which seemed to work OK.
But as I wanted to experiment in a more real world scenario I put most things on one window. This where I encountered my problem. I can not get the radio button in the frame to alter the wording of a label in the parent window.
Complete code is:-
#! /usr/bin/python3
from tkinter import *
def win_pos(WL,WH,xo=0,yo=0) :
# Screen size & position procedure
# Screen size
SW = home.winfo_screenwidth()
SH = home.winfo_screenheight()
# 1/2 screen size
sw=SW/2
sh=SH/2
# 1/2 window size
wl=WL/2
wh=WH/2
# Window position
WPx=sw-wl+xo
WPy=sh-wh+yo
# Resulting string
screen_geometry=str(WL) + "x" + str(WH) + "+" + str(int(WPx)) + "+" \ + str(int(WPy))
return screen_geometry
# Create a window
home=Tk()
home.title("Radio buttons test")
# Set the main window
home.geometry(win_pos(600,150))
lab1=Label(home)
lab1.grid(row=1,column=1)
fraym1=LabelFrame(home, bd=5, bg="red",relief=SUNKEN, text="Label frame text")
fraym1.grid(row=2,column=2)
laybl1=Label(fraym1, text="This is laybl1")
laybl1.grid(row=0, column=3)
var1=IntVar()
R1=Radiobutton(fraym1, text="Apple", variable=var1, value=1)
R1.grid(row=1, column=1)
R2=Radiobutton(fraym1, text="Asus", variable=var1, value=2)
R2.grid(row=1, column=2)
R3=Radiobutton(fraym1, text="HP", variable=var1, value=3)
R3.grid(row=1, column=3)
R4=Radiobutton(fraym1, text="Lenovo", variable=var1, value=4)
R4.grid(row=1, column=4)
R5=Radiobutton(fraym1, text="Toshiba", variable=var1, value=5)
R5.grid(row=1, column=5)
# Create function used later
def sel(var) :
selection="Manufacturer: "
if var.get() > 0 :
selection=selection + str(var.get())
lab1.config(text=selection)
R1.config(command=sel(var1))
R2.config(command=sel(var1))
R3.config(command=sel(var1))
R4.config(command=sel(var1))
R5.config(command=sel(var1))
R1.select()
mainloop()
I realise that there is room for improvement using classes/functions but I need to get this resolved in my head before I move on. As it can be hopefully seen, I'm not a complete novice to programming, but this is doing my head in.
Can a solution, and reasoning behind the solution, be given?
You can modify your label's text by assigning the same variable class object, var1 as its textvariable option as well but since lab1's text is slightly different, try removing:
R1.config(command=sel(var1))
R2.config(command=sel(var1))
R3.config(command=sel(var1))
R4.config(command=sel(var1))
R5.config(command=sel(var1))
R1.select()
and modify sel to:
def sel(*args) :
selection="Manufacturer: "
selection=selection + str(var1.get())
lab1.config(text=selection)
and then call var1.trace("w", sel) somewhere before mainloop as in:
...
var1.trace("w", sel)
mainloop()
Also for a simple example:
import tkinter as tk
root = tk.Tk()
manufacturers = ["man1", "man2", "man3", "man4", "man5"]
lbl = tk.Label(root, text="Please select a manufacturer.")
lbl.pack()
# create an empty dictionary to fill with Radiobutton widgets
man_select = dict()
# create a variable class to be manipulated by radiobuttons
man_var = tk.StringVar(value="type_default_value_here_if_wanted")
# fill radiobutton dictionary with keys from manufacturers list with Radiobutton
# values assigned to corresponding manufacturer name
for man in manufacturers:
man_select[man] = tk.Radiobutton(root, text=man, variable=man_var, value=man)
#display
man_select[man].pack()
def lbl_update(*args):
selection="Manufacturer: "
selection=selection + man_var.get()
lbl['text'] = selection
#run lbl_update function every time man_var's value changes
man_var.trace('w', lbl_update)
root.mainloop()
Example with label's identical to that of radiobutton's value:
import tkinter as tk
root = tk.Tk()
# radiobutton group will the button selected with the value=1
num = tk.IntVar(value=1)
lbl = tk.Label(root, textvariable=num)
zero = tk.Radiobutton(root, text="Zero", variable=num, value=0)
one = tk.Radiobutton(root, text="One", variable=num, value=1)
#display
lbl.pack()
zero.pack()
one.pack()
root.mainloop()

Resources