Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question - How can i set a Input border color and it would show WITHOUT it being focused #4979

Closed
K9Developer opened this issue Nov 25, 2021 · 12 comments
Labels
Port - TK PySimpleGUI question Further information is requested

Comments

@K9Developer
Copy link

K9Developer commented Nov 25, 2021

Type of Issue (Enhancement, Error, Bug, Question)

Question


Operating System

Windows

PySimpleGUI Port (tkinter, Qt, Wx, Web)

tkinter


Versions

Python version: 3.9.8 (tags/v3.9.8:bb3fdcf, Nov 5 2021, 20:48:33) [MSC v.1929 64 bit (AMD64)]
port: tkinter
tkinter version: 8.6.9
PySimpleGUI version: 4.55.1


Troubleshooting

These items may solve your problem. Please check those you've done by changing - [ ] to - [X]

  • [x ] Searched main docs for your problem www.PySimpleGUI.org
  • [x ] Looked for Demo Programs that are similar to your goal Demos.PySimpleGUI.org
  • [x ] If not tkinter - looked for Demo Programs for specific port
  • [x ] For non tkinter - Looked at readme for your specific port if not PySimpleGUI (Qt, WX, Remi)
  • [x ] Run your program outside of your debugger (from a command line)
  • [x ] Searched through Issues (open and closed) to see if already reported Issues.PySimpleGUI.org
  • [x ] Tried using the PySimpleGUI.py file on GitHub. Your problem may have already been fixed but not released

Detailed Description

I'm trying to have a red border for an Input and I need it to change dynamically... so I tried
window['-IN-'].Widget.configure(highlightcolor='red4', highlightthickness=2)
but it would only show the red when the Input is focused... So how can I set a border color even if I'm not focused?
if possible I would like it to be with the element itself and not a frame but if there's no other way then I'd like you to show me how I can update the color of the frame and the border thickness

Example of how the code should look:

from PySimpleGUI import *
layout = [
    [Input(default_text='test', key='IN')],
    [Button('RED', key='RED'), Button('GREEN', key='GREEN'), Button('RESET COLOR', key='RESET')]
]
window = Window('test', layout)
while True:
    event, values = window.read()
    if event == 'RED':
        window['IN'].border(color='red', width=1)
    elif event == 'GREEN':
        window['IN'].border(color='green', width=1)
    elif event == 'RESET':
        window['IN'].border(color='green', width=0)
@PySimpleGUI
Copy link
Owner

Can you make a short PySimpleGUI program?

Are you talking about a Text element?

The key you've provided looks like an Input element. Try using just PySimpleGUI terms and I'll catch on quicker I think. I need the problem/question with a small bit of code more than the solutions you've tried.

@K9Developer
Copy link
Author

Can you make a short PySimpleGUI program?

Are you talking about a Text element?

The key you've provided looks like an Input element. Try using just PySimpleGUI terms and I'll catch on quicker I think. I need the problem/question with a small bit of code more than the solutions you've tried.

Updated. is that ok?

@PySimpleGUI
Copy link
Owner

Updated. is that ok?

Yes! Much. Thank you... now I know what we're working with.

In PySimpleGUI, this kind of call is highly unlikely to work:

window['IN'].border(color='red', width=1)

Take a look at the SDK Call Reference to find the methods you can call and the settings you can change for each element:
https://pysimplegui.readthedocs.io/en/latest/call%20reference/#input-element

The important things to check there are the init and the update methods.

I don't have an immediate answer just yet for you... but want to thank you for updating your question.

@PySimpleGUI
Copy link
Owner

PySimpleGUI commented Nov 25, 2021

If you want a colored border around an Input element, the way to achieve it will be to place it into a Column element and set a color for the column background. I'll write a little example. I think this will likely be the closest to what you're after, especially if you want control of the color.

EDIT - Oh.... I spoke too soon about changing the color. The Column update method doesn't have the provision to change the background color... but, that doesn't mean it can't be done... :-)

@PySimpleGUI
Copy link
Owner

Here's the effect I am talking about:

import PySimpleGUI as sg

layout = [  [sg.Text('My Window')],
            [sg.Column([[sg.Input(key='-IN-')]], k='-COL-', background_color='red')],
            [sg.Text(size=(12,1), key='-OUT-')],
            [sg.Button('Red'), sg.B('Green'), sg.B('Reset'), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout)

while True:
    event, values = window.read()
    print(event, values)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break

window.close()

image

@PySimpleGUI
Copy link
Owner

import PySimpleGUI as sg

layout = [  [sg.Text('My Window')],
            [sg.Column([[sg.Input(key='-IN-')]], k='-COL-', background_color='blue')],
            [sg.Text(size=(12,1), key='-OUT-')],
            [sg.Button('Red'), sg.B('Green'), sg.B('Reset'), sg.Button('Exit')]  ]

window = sg.Window('Window Title', layout)

while True:
    event, values = window.read(timeout=200)
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    elif event == 'Green':
        window['-IN-'].ParentRowFrame.config(background='green')
    elif event == 'Red':
        window['-IN-'].ParentRowFrame.config(background='red')
    elif event == 'Reset':
        window['-IN-'].ParentRowFrame.config(background=sg.theme_background_color())
window.close()

Let's see if this is a good start for you
osaOc5RhZm

@jason990420
Copy link
Collaborator

You can use same color for both options highlightcolor and highlightbackground at the same time.

Example Code

import PySimpleGUI as sg

default_width = 5


def border(element, color=None, width=default_width):
    if color is None:
        color = sg.theme_background_color()
    element.Widget.configure(highlightcolor=color, highlightbackground=color,
        highlightthickness=width)

font = ('Courier New', 16)
sg.theme('DarkBlue3')
sg.set_options(font=font)

layout = [
    [sg.Input(default_text='test', key='IN1')],
    [sg.Input(default_text='test', key='IN2')],
    [sg.Button('RED', key='RED'),
     sg.Button('GREEN', key='GREEN'),
     sg.Button('RESET COLOR', key='RESET')]
]

window = sg.Window('title', layout, finalize=True)
entry1, entry2 = window['IN1'], window['IN2']
border(entry1), border(entry2)

while True:
    event, values = window.read()
    if event == sg.WINDOW_CLOSED:
        break
    elif event in ('RED', 'GREEN'):
        border(entry1, event.lower())
    elif event == 'RESET':
        border(entry1)

window.close()

image

@jason990420 jason990420 changed the title Question - How can i set a Label border color and it would show WITHOUT it being focused Question - How can i set a Input border color and it would show WITHOUT it being focused Nov 26, 2021
@jason990420 jason990420 added the question Further information is requested label Nov 26, 2021
@PySimpleGUI
Copy link
Owner

I stayed away from the highlight settings. The problem with many of these highlight settings in particular is how they behave differently for Windows versus Linux versus Mac. I stuck with using the Frame for this reason.

https://tcl.tk/man/tcl8.6/TkCmd/options.htm#M-highlightthickness

image

@vncs1880
Copy link

vncs1880 commented Jul 25, 2022

You can use same color for both options highlightcolor and highlightbackground at the same time.

Example Code

import PySimpleGUI as sg

default_width = 5


def border(element, color=None, width=default_width):
    if color is None:
        color = sg.theme_background_color()
    element.Widget.configure(highlightcolor=color, highlightbackground=color,
        highlightthickness=width)

font = ('Courier New', 16)
sg.theme('DarkBlue3')
sg.set_options(font=font)

layout = [
    [sg.Input(default_text='test', key='IN1')],
    [sg.Input(default_text='test', key='IN2')],
    [sg.Button('RED', key='RED'),
     sg.Button('GREEN', key='GREEN'),
     sg.Button('RESET COLOR', key='RESET')]
]

window = sg.Window('title', layout, finalize=True)
entry1, entry2 = window['IN1'], window['IN2']
border(entry1), border(entry2)

while True:
    event, values = window.read()
    if event == sg.WINDOW_CLOSED:
        break
    elif event in ('RED', 'GREEN'):
        border(entry1, event.lower())
    elif event == 'RESET':
        border(entry1)

window.close()

image

Hi, I see its been a while but could you please give me some pointers?

self.window = sg.Window('', [[get_layout(w, h)]], finalize=True)

[self.window[k].Widget.configure(highlightcolor='red', highlightthickness=2) for k,v in self.window.AllKeysDict.items() if k.startswith('-FLD-')]

the "configure" keeps giving me: TclError: unknown option "-highlightcolor"

any thoughts on this deeply appreciated!

UPDATE1:
just to clarify, "self.window[k]" are of type "sg.Input"

UPDATE2:
I actually just managed to achieve desired result via following code:

(...)
        elif str(event).endswith('+FOCUS OUT+'):
            color = sg.theme_background_color()
            self.window[event.replace('+FOCUS OUT+','')].Widget.configure(highlightcolor=color, highlightbackground=color, highlightthickness=0)
        elif str(event).endswith('+INPUT FOCUS+'):
            element_with_focus = self.window.find_element_with_focus()
            element_with_focus.Widget.configure(highlightcolor='red', highlightbackground='red',highlightthickness=5)
(...)

if its ok id still appreciate any idea on why initial attempt didnt work and/or whether my solution is fine

@PySimpleGUI
Copy link
Owner

if its ok id still appreciate any idea on why initial attempt didn't work and/or whether my solution is fine

I don't know the OS you're using, I don't know anything about the version of Tkinter. There's just not enough here to answer those questions. As stated earlier, these settings, highlight color, are OS-dependent.

You're outside the scope of PySimpleGUI itself and into tkinter programming. It's in learning tkinter programming in more detail that I believe your answers can be found.

Replying to a closed issue isn't the best route to take for support because of the missing info and often I don't see these comments once closed. I happened to scan them this morning and saw the update.

Since I was looking at this again, I try not to dip down into tkinter programming directly. Just to get the basic effect this time I Tried a Frame to see if that would work as another method. This would be a potential route that's not OS dependent.

import PySimpleGUI as sg

layout = [  [sg.Text('My layout')],
            [sg.Frame('',[[sg.Input(pad=(0,0))]], border_width=5, background_color='red', relief=sg.RELIEF_FLAT)],
            [sg.Button('Read'), sg.Button('Exit')] ]

sg.Window('My new window', layout).read(close=True)

image

@vncs1880
Copy link

thank you!
I understand, will open issue next time!

as stated on UPDATE2, i found a workaround to get the desired effect for my use case i.e. binding focus events and updating highlight colors

@PySimpleGUI
Copy link
Owner

image

It's all good!

@jason990420 jason990420 added the Port - TK PySimpleGUI label Jul 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Port - TK PySimpleGUI question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants