1

When I open my GUI, I can type in it and do stuff, but the OptionMenu and Button widgets look as if the GUI is out of focus. A picture to demonstrate what I mean: (take a look at the dropdown menus and the buttons)

enter image description here

After I focus on a different app and then click on my GUI again, it has the right colors which should be there if it is in focus. Once again a picture so it is clearer what I mean:

enter image description here

So my question is, does anyone know why this is happening and what I should do so that the GUI is also visually in focus when I open it for the first time?

I know it is bad practice to upload all this code as it's better to upload a minimal reproducible example, but I figured every small detail could be important here as to why this is happening. Therefore, I decided to upload a larger piece of the code I'm using for the GUI.

from tkinter import *
from tkinter import messagebox
from tkinter import font as tkfont

root = Tk()
root.config(background='#009688')
root.title('Contractmaker')

# GUI stuff that takes care of the scrollbar
def on_configure(event):
    canvas.configure(scrollregion=canvas.bbox('all'))

def on_mousewheel(event):
    canvas.yview_scroll(int(event.delta), 'units')

# Create some fonts
bold_font = tkfont.Font(weight='bold')

# Create the actual GUI
canvas = Canvas(root, width=450, height=550)
canvas.config(background='#009688')
canvas.pack(side=RIGHT)

scrollbar = Scrollbar(root, command=canvas.yview)
# scrollbar.pack(side=RIGHT, fill='y')

canvas.configure(yscrollcommand=scrollbar.set)
canvas.bind('<Configure>', on_configure)
canvas.bind_all('<MouseWheel>', on_mousewheel)

frame = Frame(canvas)
frame.config(background='#009688')
canvas.create_window((0,0), window=frame)

labelNaamhuurder = Label(frame, text='Naam huurder', bg='#009688', font=bold_font).grid(row=0, column=0, sticky=W, padx=(30, 0), pady=(15, 0))
naamhuurderr = Entry(frame, textvariable=naamhuurder, relief=FLAT, highlightcolor='#9DCCFD')
naamhuurderr.grid(row=0, column=2, pady=(15, 0))

# All the other rows are the same as the one above so I decided to leave them out 

labelAdresapp = Label(frame, text='Adres appartement', bg='#009688', font=bold_font).grid(row=5, column=0, pady=(15, 0), sticky=W, padx=(30, 0))
appartementen = {'Slotlaan 73', 'Slotlaan 77', 'Albert Cuypstraat 22'}
adresapp.set('Slotlaan 73') # Default option
dropdownMenuhuur = OptionMenu(frame, adresapp, *appartementen)
dropdownMenuhuur.config(width=18)
dropdownMenuhuur.grid(row=5, column=2, pady=(15, 0))

labelTypekamer = Label(frame, text='Type kamer', bg='#009688', font=bold_font).grid(row=6, column=0, pady=(15, 0), sticky=W, padx=(30, 0))
typeKamers = {'Grote kamer', 'Kleine kamer', 'Grote kamer gedeeld'}
typekamer.set('Grote kamer') # Default option
dropdownMenutypekamer = OptionMenu(frame, typekamer, *typeKamers)
dropdownMenutypekamer.config(width=18)
dropdownMenutypekamer.grid(row=6, column=2, pady=(15, 0))

empty = Button(frame, text='Opnieuw', command=clear, font=bold_font)
empty.config(width=10, fg='#009688', borderwidth=0, relief=RAISED)
empty.configure(highlightbackground='#009688')
empty.grid(row=11, column=0, pady=(25, 0), padx=(80, 0))

converter = Button(frame, text='OK', command=contractupdater, font=bold_font)
converter.config(width=10, fg='#009688', borderwidth=2, relief=RAISED)
converter.configure(highlightbackground='#009688')
converter.grid(row=11, column=2, pady=(25, 0), padx=(0, 80))

root.mainloop()

For some more context: this is basically a follow-up question on this question.

Jem
  • 557
  • 9
  • 28

1 Answers1

2

I'm not sure if this is the right fix for this issue but it works. So by using root.update() I was able to solve the issue, but this leads to another issue of flashing window changing sizes from default at the start which can also be solved with this,

...
root = tk.Tk()
root.wm_withdraw()  # Hide the window (unmapped)
root.update()       # Update the window when it is hidden
...


...
# Show the window back again just before the mainloop with 1ms delay.
root.after(1, root.deiconify) 
root.mainloop()

This should solve your issue with focus at the start, let me know otherwise.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
Saad
  • 3,340
  • 2
  • 10
  • 32
  • 1
    @jem: I'm glad that worked. Basically, the point is to [update](https://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.update-method) the main window but if we update the window without `root.wm_withdraw()` it will flicker on the screen once at the start so to avoid that I first, hide the window then update the window while hidden then show the window after 1ms after `mainloop` has executed. I don't know if I've explained it well. – Saad Jun 27 '20 at 13:22
  • Ah yeah that makes some sense to a beginner like me. Correct me if I'm wrong, but there's probably a bug the first time it gets opened. So therefore, you have to withdraw that window, update it (which takes away the bug apparently) and then show it again with the root.after. Is there also a reason why you'd have to put root.after just before the maintop? Couldn't I also place it immediately after it got updated? – Jem Jun 27 '20 at 13:34
  • I tried put it after `update()` but it doesn't work, my guess is that when we add widgets to the window, the window automatically changes its size to fit them so putting after when the window knows its final size was more suited. But if you declare a fixed size for example `root.geometry("200x200")` then, in that case, we don't even need to hide the window by just using `root.update()` in the beginning should do the trick for all. – Saad Jun 27 '20 at 13:44