PySimpleGUI / PySimpleGUI

Python GUIs for Humans! PySimpleGUI is the top-rated Python application development environment. Launched in 2018 and actively developed, maintained, and supported in 2024. Transforms tkinter, Qt, WxPython, and Remi into a simple, intuitive, and fun experience for both hobbyists and expert users.

Home Page:https://www.PySimpleGUI.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[ Bug?] numeric input fields blocked on macOS after button running background task

hvdwolf opened this issue · comments

Type of Issue (Bug)

I do a number of actions and after having pressed a button that runs two background tasks, the numeric input fields don't work anymore.
This ONLY occurs in MacOS. On Linux Debian (10 and 11) and Linux Ubuntu 20.10, and on Windows 10 it simply continues functioning.
See screenshot and movie below

Operating System

MacOS Catalina

PySimpleGUI Port (tkinter, Qt, Wx, Web)

tkinter

Versions

Python version (sg.sys.version)

3.10.0

PySimpleGUI Version (sg.__version__)

PySimpleGUI 4.59 and 4.60

GUI Version (tkinter (sg.tclversion_detailed), PySide2, WxPython, Remi)

tkinter 8.6


Your Experience In Months or Years (optional)

Years Python programming experience
8-10 occasional

Years Programming experience overall
30 years

Have used another Python GUI Framework? (tkinter, Qt, etc) (yes/no is fine)
PySide


Troubleshooting

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

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

Detailed Description

It is very difficult to share pieces of code, especially as I do not know why it does not work on MacOS, but does on several linuxes and Windows 10.
My github for PyImageFuser: https://github.com/hvdwolf/PyImageFuser

Code To Duplicate

Background function (from run_command.py):

def run_shell_command(cmdstring, arguments, waitmessage, output):
    retstring = ""
    if platform.system() == 'Windows':
        result = sg.shell_with_animation(cmdstring, arguments, message=waitmessage, font='Helvetica 15', no_titlebar=True, alpha_channel=0.90, keep_on_top=True)
    else:
        tlist = []
        result = sg.shell_with_animation(cmdstring, tlist, message=waitmessage, font='Helvetica 15', no_titlebar=True, alpha_channel=0.90, keep_on_top=True)

    if output:
        sg.popup_scrolled(result, font='Courier 10', keep_on_top=True, icon=image_functions.get_icon())

    if 'error' in result or 'Error' in result:
        retstring = "Something went wrong"
    else:
        retstring = "OK"
    return retstring

My gui part for the numeric fields (from ui_layout.py):

    layoutAISInputs = [
        [ sg.InputText('50', key='_inHFOV_', size=(4, 1), disabled=True, enable_events=True, tooltip='Approximate horizontal field of view of input images, use if EXIF info not complete'), sg.Text("HFOV", tooltip='Approximate horizontal field of view of input images, use if EXIF info not complete'),sg.Checkbox('Auto HFOV', key='_autoHfov', default=True, enable_events=True, tooltip='Use exif info to determine HFOV. If not available, you can override the standard fallback value of 50'), ],
        [sg.InputText('0.9', key='_correlation_', size=(4, 1), enable_events=True), sg.Text('Correlation threshold')],
        [sg.InputText('8', key='_inNoCP_', size=(4, 1), enable_events=True), sg.Text('No. of Control points', tooltip='Default is 8. Increase to 20, 30 or 50 in case of not so good results.')],
        [sg.InputText('3', key='_removeCPerror_', size=(4, 1), enable_events=True), sg.Text('Remove Control points with error > than')],
        [sg.InputText('1', key='_inScaleDown_', size=(4, 1), enable_events=True), sg.Text('Scale down images by 2^ scale')],
        [sg.InputText('5', key='_inGridsize_', size=(4, 1), enable_events=True), sg.Text('Grid size (default: 5x5)')],
    ]

My "keys" listening on the events on the numerical input fields (from the main PyImageFuser.py):

        # Now check the numerical "text" fields if only numerical
        elif event == '_inHFOV_' and values['_inHFOV_'] and values['_inHFOV_'][-1] not in ('0123456789.'):
            window['_inHFOV_'].update(values['_inHFOV_'][:-1])
        elif event == '_correlation_' and values['_correlation_'] and values['_correlation_'][-1] not in ('0123456789.'):
            window['_correlation_'].update(value='0.9')
        elif event == '_inNoCP_' and values['_inNoCP_'] and values['_inNoCP_'][-1] not in ('0123456789'):
            window['_inNoCP_'].update(value='8')
        elif event == '_removeCPerror_' and values['_removeCPerror_'] and values['_removeCPerror_'][-1] not in ('0123456789'):
            window['_removeCPerror_'].update(value='3')
        elif event == '_inScaleDown_' and values['_inScaleDown_'] and values['_inScaleDown_'][-1] not in ('0123456789'):
            window['_inScaleDown_'].update(value='1')
        elif event == '_inGridsize_' and values['_inGridsize_'] and values['_inGridsize_'][-1] not in ('0123456789'):
            window['_inGridsize_'].update(value='5')
        # end of numerical checks

Screenshot, Sketch, or Drawing

pyimagefuser

Below a small movie
https://user-images.githubusercontent.com/4520361/169067165-35041829-de38-412c-b291-07741f5a290c.mp4


Watcha Makin?

From the Readme on my github:
PyImageFuser is a Python3 PySimpleGui program to exposure fuse bracketed images, reduce noise in stacks and do focus stacking. It uses align_image_stack and enfuse to accomplish this.

Does the tab key move focus around the window once in this state? Wondering if it's a problem of clicking on the input field and it getting focus or something related to focus.

Can you also provide the specific version of tkinter like 8.6.12 perhaps?

tab doesn't work either. It does not acivate anything
The tkinter version is 8.6.11

>>> import tkinter
>>> tcl = tkinter.Tcl()
>>> print(tcl.call("info", "patchlevel"))
8.6.11

I also disabled the numeric checks on fields via the event, but that doesn't make a difference.

From the main window I can open the Preferences window. When I open that and close it again, the fields somehow start working again.
Is there "something" I could use to simulate that behavior after my background processes have run?
if platform.system() == 'Darwin'
"do something that has the same efffect as opening & closing another window"

I think tkinter is losing the focus. It's behaving as if nothing has the focus. You're able to interact with some things like checkboxes I see, but not things that require the element to "have focus".

From the main window I can open the Preferences window. When I open that and close it again, the fields somehow start working again.

This sounds like it's giving the focus back to the other window.

Do you have any tooltips? This is an area that has been tripping up tkinter in the past release.

"do something that has the same efffect as opening & closing another window"

You can do this yourself, in your event loop. That's the only "valid" place a new window can be created.

I would try to set the focus on an element to see if tkinter will get back control that way. You can do this by calling Element.set_focus() (See call reference)

For future reference..... get_versions() will give you version info...

image

When I wrote "do something that has the same efffect as opening & closing another window", I did not mean I want to open/close a window, but to simulate something like that as that does enable the text fields again. It has something to do with the focus.
I already found that on MacOS console apps or apps that start from the console, keep the focus on the console. I assume that means that the subprocess shell commands might possibly take and keep the focus.

I use tooltips but they don't work on MacOS. I already knew that.

I tried the set_focus() on several elements (the textfield, the tab, a button), but that doesn't help.

Is your secondary window a popup or have "modal" set?

It is a complete new window, but I don't set the modal boolean, so it should be modal=False by default.
From the main PyImageFuser.py I call the settings_window in the Preferences.py which really builds a new window.

"main" Preferences function

def settings_window():
<snip>
    window = make_window()
   While True:
<snip>

And the layout/window function.

def make_window():
    <snip>
    "layout definition"
    <snip>
   return sg.Window('Preferences Window', layout, icon=image_functions.get_icon())

It's behaving perhaps like the focus is still on that other window. Can you try making it modal? I would normally flip the other way..... assumed you had modal set and then asked you to flip to it non-modal.

There's a force focus flag on set_focus, you may want to set that when experimenting with trying to get focus back.... assuming this is a focus issue.

I thought you meant the preferences window. That is the window that I call and then close and then the fields function again.

This occurs after the background jobs with the external commands have finished.
The background windows use the
result = sg.shell_with_animation(cmdstring, tlist, message=waitmessage, font='Helvetica 15', no_titlebar=True, alpha_channel=0.90, keep_on_top=True) function.
Note that I also tried with keep_on_top=False.
But for those function windows I can't set modal.

The force=True works ("May the force be with you")
I have to set it on an element that is NOT one of the numeric text fields and which is not a tab element or so. I now set it on the main button "Create Exposure fused image", and now the text fields keep working.
window['_CreateImage_'].set_focus(force=True)

Thanks!

EDIT: some more explanation.
I did set it on one of the text fields. That works when that sub tab is not opened, but one of the other tabs.
If I have the sub tab opened where the text fields are (because I immediately wanted to see the effect), it doesn't work, strange enough.
That "Create Exposure fused image" is always visible but is not part of that TabGroup. Maybe that has something to do with it (on MacOS).

The force=True works ("May the force be with you")

image

I think the force was with you!

I'm glad we've made progress.

Thanks so far for your support.
I will keep the ticket open for a few days to see if I find something else.

Of course! You are quite welcome... Thanks for your patience and smooth debugging. It's a great skill and a wonderful experience to work with someone that's got that gift.