Search code examples
python-3.xtkinterhighlight

Is there a way to make sure a highlited parent widget remains highlighted when selecting a child widget


I have a radiobutton that highlights the corresponding LabelFrame.

Each LabelFrame has an Entry widget as a child. When the Entry widget is selected to type in some input, the parent LabelFrame loses the given highlightbackground color (from cyan to gray) but keeps the same highlightthickness.

Is there a way to keep the given highlightbackground color?

(windows 7 64, pycharm 2019.2)

Thanks in advance.

from tkinter import *
from tkinter import ttk
import tkinter as tk


class doSomeStuff(Tk):
    def __init__(self):
        Tk.__init__(self)

        self.radioBtnVar = StringVar()  # radiobutton variable

        # main canvas

        pwdCanvas = tk.Canvas(self, bd=0, highlightthickness=0)
        pwdCanvas.pack()

        # choiceLabelFrame
        choiceLabelFrame = ttk.LabelFrame(pwdCanvas, text='Choice LabelFrame (ttk)')
        choiceLabelFrame.grid(column=0, row=11, columnspan=2, sticky='nsew')

        # radio button 1
        rbtn1 = ttk.Radiobutton(choiceLabelFrame, text='A', variable=self.radioBtnVar, value='PCG', command=self.colorLabels)
        rbtn1.pack(side='left')

        # radio button 2
        rbtn2 = ttk.Radiobutton(choiceLabelFrame, text='B', variable=self.radioBtnVar, value='UG', command=self.colorLabels)
        rbtn2.pack(side='right')

        # LabelFrame1, left side
        self.LabelFrame1 = tk.LabelFrame(pwdCanvas, text="LabelFrame 1 (tk)", bd=0)  # I use tk to have access to the 'highlightbackground' option
        self.LabelFrame1.grid(column=0, row=12, sticky='nsew', padx=3, pady=3)

        entry1Label = ttk.Label(self.LabelFrame1, text='Entry 1')
        entry1Label.grid(column=0, row=11, sticky='w')

        self.labelEntry1 = ttk.Entry(self.LabelFrame1, state='disabled')
        self.labelEntry1.grid(column=1, row=11, sticky='w')

        # LabelFrame2, right side
        self.LabelFrame2 = tk.LabelFrame(pwdCanvas, text="LabelFrame 2 (tk)", bd=0)
        self.LabelFrame2.grid(column=1, row=12, sticky='nw', padx=3, pady=3)

        entry2Label = ttk.Label(self.LabelFrame2, text='Entry 2')
        entry2Label.grid(column=0, row=0)

        labelEntry2 = ttk.Entry(self.LabelFrame2, state='disabled')
        labelEntry2.grid(column=1, row=0)

    def colorLabels(self):  # activates and highlights the chosen option
        if self.radioBtnVar.get() == 'PCG':
            for child in self.LabelFrame1.winfo_children():
                child.config(state='enabled')
            self.LabelFrame1.config(highlightbackground='cyan', highlightthickness=2)

            for child in self.LabelFrame2.winfo_children():
                child.config(state='disabled')
            self.LabelFrame2.config(highlightthickness=0)

        elif self.radioBtnVar.get() == 'UG':
            for child in self.LabelFrame2.winfo_children():
                child.config(state='enabled')
            self.LabelFrame2.config(highlightbackground='cyan', highlightthickness=2)

            for child in self.LabelFrame1.winfo_children():
                child.config(state='disabled')
            self.LabelFrame1.config(highlightthickness=0)


if __name__ == "__main__":
    app = doSomeStuff()
    app.mainloop()

Solution

  • I've found a way to get what I want.

        def colorLabels(self):
            if self.radioBtnVar.get() == 'PCG':
                for child in self.LabelFrame1.winfo_children():
                    child.config(state='enabled')
                self.LabelFrame1.config(highlightbackground='cyan', highlightcolor='cyan', highlightthickness=2)
    
                for child in self.LabelFrame2.winfo_children():
                    child.config(state='disabled')
                self.LabelFrame2.config(highlightthickness=0)
    
            elif self.radioBtnVar.get() == 'UG':
                for child in self.LabelFrame2.winfo_children():
                    child.config(state='enabled')
                self.LabelFrame2.config(highlightbackground='cyan', highlightcolor='cyan', highlightthickness=2)
    
                for child in self.LabelFrame1.winfo_children():
                    child.config(state='disabled')
                self.LabelFrame1.config(highlightthickness=0)
    

    I simply added 'highlightcolor='cyan''. As explained here effbot.org :

    • 'highlightbackground' is used when the widget doesn’t have focus.

    • 'highlightcolor' is used when the widget has focus.

    That way my widget keeps its highlighted contour even if it's not in focus.