Next / Previous / Contents / TCC Help System / NM Tech homepage

16.7. ColorReadout.__createWidgets()

This methods creates and grids all the widgets. For the grid plan, refer to Section 16, “class ColorReadout: Text and background color readouts”.

huey
# - - -   C o l o r R e a d o u t . _ _ c r e a t e W i d g e t s

    def __createWidgets ( self ):
        """Create and grid all internal widgets.
        """

The first row contains only a label "#RRGGBB" that helps the user interpret the background and text colors that appear aligned below it.

huey
        #-- 1 --
        # [ self.__rgbLabel  :=  a new Label added and gridded ]
        self.__rgbLabel  =  Label ( self, font=MONO_FONT,
            text="#RRGGBB" )
        rowx  =  0
        self.__rgbLabel.grid ( row=rowx, column=1, sticky=E+W )

The second row contains the radiobutton and readout for the background color.

huey
        #-- 2 --
        # [ self  :=  self with a new Radiobutton widget that sets
        #       self.__isTextVar to 0 and calls self.__radioHandler
        #       when the radiobutton is changed
        #   self.__bgRadio  :=  that Radiobutton widget ]
        self.__bgRadio  =  Radiobutton ( self,
            command=self.__radioHandler,
            font=BUTTON_FONT, text="Background color",
            value=0, variable=self.__isTextVar )
        rowx  +=  1
        self.__bgRadio.grid ( row=rowx, column=0, sticky=W )

It might seem logical to use a Label widget to display color names, but they have one drawback: the user can't use the mouse to cut the color name for pasting elsewhere. Consequently, we use an Entry widget. Here are some of the less obvious options, and why we use them:

relief=RAISED, bd=4

Make the labels look like they are sticking up. Use a four-pixel border to give some space for this 3-d effect.

exportselection=1

Allow the user to cut text from this widget.

takefocus=0

We don't want the user to be able to change the text displayed here; this option prevents the tab key from moving the input focus through this widget.

huey
        #-- 3 --
        # [ self.__bgColorName  :=  a new Entry whose text is
        #       linked to self.__bgColorVar ]
        self.__bgColorName  =  Entry ( self,
            exportselection=1, takefocus=0, width=7,
            relief=RAISED, bd=4, bg="white",
            font=MONO_FONT, textvariable=self.__bgColorVar )
        self.__bgColorName.grid ( row=rowx, column=1,
            padx=4, sticky=W )

The next row is quite similar to the previous row, but it is for the text color.

huey
        #-- 4 --
        # [ self  :=  self with a new Radiobutton widget that sets
        #       self.__isTextVar to 1 and calls self.__radioHandler
        #       when the radiobutton is changed
        #   self.__textRadio  :=  that Radiobutton widget ]
        self.__textRadio  =  Radiobutton ( self,
            command=self.__radioHandler,
            font=BUTTON_FONT, text="Text color",
            value=1, variable=self.__isTextVar )
        rowx  +=  1
        self.__textRadio.grid ( row=rowx, column=0, sticky=W )

        #-- 5 --
        # [ self.__textColorName  :=  a new Entry whose text is
        #       linked to self.__textColorVar ]
        self.__textColorName  =  Entry ( self,
            exportselection=1, takefocus=0, width=7,
            relief=RAISED, bd=4, bg="white",
            font=MONO_FONT, textvariable=self.__textColorVar )
        self.__textColorName.grid ( row=rowx, column=1,
            padx=4, sticky=W )

There is a drawback to using an Entry widget to display the color values: the user can then edit the displayed values, which would mean they no longer reflect the actual color values. One trick we tried is to set state=DISABLED in both Entry widgets. This does a fine job of preventing the user from changing the value, and in an older Tkinter version, the fix worked. However, in a newer Tkinter install, it is now impossible to use cut-and-paste on a disabled widget.

The solution is to bind all keyboard events to a little handler called Section 16.9, “ColorReadout.__fixNames(): Prevent user modification of the Entry widgets”. This event handler rewrites the values of both the names to keep them consistent with the internal colors. Here is the code that sets up that event binding.

huey
        #-- 6 --
        # [ self.__bgColorName  :=  self.__bgColorName set up so
        #       that any user keypresses cause self.__bgColorVar
        #       to be set to str(self.__bgColor)
        #   self.__textColorName  :=  self.__textColorName set up so
        #       that any user keypresses cause self.__textColorVar
        #       to be set to str(self.__textColor) ]
        self.__bgColorName.bind ( "<Any-KeyRelease>",
                                  self.__fixNames )
        self.__textColorName.bind ( "<Any-KeyRelease>",
                                  self.__fixNames )