Pysimplegui: [ Bug/Question] window.close() not closing window

Created on 30 Dec 2019  路  29Comments  路  Source: PySimpleGUI/PySimpleGUI

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

I believe this is a bug but may be intented behaviour but can not example of what I am trying to do in docs etc.

After recieving the None value (user closes the window using 'x') window.close() is not working.

Operating System

Linux - Elementary OS 5.1

Python version

3.6.9

PySimpleGUI Port and Version

Tkinker, 4.4.1

Your Experience Levels In Months or Years

_4 years_ Python programming experience
_7 years_ Programming experience overall
_yes_ Have used another Python GUI Framework (tkiner, Qt, etc) previously (yes/no is fine)?

You have completed these steps:

  • [x] Read instructions on how to file an Issue
  • [x] Searched through main docs http://www.PySimpleGUI.org for your problem
  • [x] Searched through the readme for your specific port if not PySimpleGUI (Qt, WX, Remi)
  • [x] Looked for Demo Programs that are similar to your goal http://www.PySimpleGUI.com
  • [x] Note that there are also Demo Programs under each port on GitHub
  • [x] Run your program outside of your debugger (from a command line)
  • [x] Searched through Issues (open and closed) to see if already reported

Code or partial code causing the problem

import PySimpleGUI as sg
from time import sleep

layout = [[sg.Text("Sample")]]

window = sg.Window("sample", layout)

while True:
    event, values = window.read()
    if event is None:
        break


window.close()

print("Window Still Open")
print("Window Still Open")
sleep(2)
print("Window Closes after this line")

Further Explanation

I have noticed however it does close as soon as another window is generated so I have a workaround using this:

 jobs_running_layout = [
                [sg.Text("Existing jobs will continue in the background")]
            ]
jobs_running_window = sg.Window(
                "Running...", jobs_running_layout, disable_close=True
            )
jobs_running_window.read(timeout=2000)
jobs_running_window.hide()
jobs_running_window.close()

Essentially I want to close a window then move on to another process etc (or leave another process going with multiprocessing etc).

Bug Done - Download from GitHub

All 29 comments

Additionally if you use window.close() with another GUI event (say a button) it functions as expected and the window closes straight away.

I'm really confused. If you've closed a window using the "X", the window is gone. The call to window.close() doesn't actually do anything in that case.

Is this a misunderstanding that you can have multiple windows open at one time. The close call closes the window, not all windows.

I'll try on my Elementary Linux distro to make sure something weird isn't happening there.

Maybe make a GIF if it's not going away?

Are you saying you click the "X" but the window doesn't close?

Oh, I also see you're running an older version of PySimpleGUI. I recommend always updating to the latest version before filing an issue to be sure your problem hasn't already been fixed.

I'm not able to get my version of ElementaryOS running on VmWare with shares at the moment. I recall having trouble setting up the shared folder previously.

I tried running on MintOS again and had no problem clicking the "X" and closing the window.

Try updating to 4.14.1.

Do you know the version of tkinter installed? It seems strange that a window would send a closed event to PySimpleGUI that didn't close the window, even in an older version.

Ohhh.,... wait.... I see what you mean now. I was able to duplicate it using sleeps.

OK... that was just plain weird. I dunno why I didn't notice it before except that I don't normally have a long delay between windows or before exiting I guess. And this is only happening on Linux.

The fix was to call update again when closing. I dunno why tkinter wants that call in there but it does.

Download a new PySimpleGUI.py file from GitHub and it should work as expected now. Version = 4.14.1.4

This has fixed it for me, thanks for such a quick great job. I have used virtualbox with elemntary OS as a VM before, I find shares easier with Virtualbox, just for info.

Awesome! Thanks for following up with verification I appreciate you opening an Issue on it. Sorry it took me a bit of flailing to get just how basic of a problem it was. It was strangely confusing for me at first.

It could have been there for a very long time. I guess everyone closes popups with buttons or else programs that use only popups would have noticed it as they tend to have long operations between calls.

Thanks for the Virtualbox tip. I've struggled to get shared folders across all of the linux distro's I'm running on VMware. So far I've settled on Mint for the majority of my testing for Linux.

Yes, I have a unique problem that I am trying to carry on the program in the background with no window, I have potentially just found a knock on effect (or another issue) though. After closing the primary window further pop ups with autoclose and non blocking behaviour seem to be hanging..shall post code in a minute...

import PySimpleGUI as sg
from time import sleep

layout = [[sg.Text("Sample")]]

window = sg.Window("sample", layout)

while True:
    event, values = window.read()
    if event is None:
        break


window.close()

print("Window now closes straight away with 4.14.1.4")

sg.PopupAutoClose(
                "Should auto close",
                non_blocking=True,
            )
print("Is non blocking but does not auto close")
sleep(10)
sg.Popup("Closes when this pop up opens")

if non_blocking is not set True then auto close works but obviosuly popup then becomes blocking. I shall see if this behaviour existed before hand.

Autoclose will not happen until you call either refresh or read again.

Autoclose will not happen until you call either refresh or read again.

is that because of the non-blocking call?

Actually, never mind that post. Let me look at your stuff in detail before commenting so I don't mess up like I did earlier :-)

Yea, the architecture of tkinter itself blocks my ability to autoclose a window if you are non-blocked.

tkinter is a single-threaded package. As a result, there is no "alarm" capability unless tkinter code is executing.

This means your self-closing window will only self-close when you are inside of tkinter after the alarm has expired. That second call can be a non-blocking call itself.

Let me know if that's not clear.

I've been taking advantage of this behavior in my recent additions to my demos of calls to popup_quick_message where I display a message to the user that the operation that's taking place can take a little while. Perhaps seconds.

I know my message will stay visible regardless of the timeout value I place on the popup. I can tell the popup to close in 1 second, but until another call into tkinter takes place, it won't actually close.

This makes sense, obvious when you remind me that tkinker is single threaded. I think I have a "complete" program now. Can close issue as I see no more issues, I shall publish my program to github shortly.

Let's leave it open until this gets rolled into a PyPI release. I also want to review and test my changes more. Having it be open reminds me to include it in the release notes, etc. The "DONE" flag makes it easy to skip over seeing it in the Open List.

I've just been relooking at my code to update pysimplegui from pypi to the latest version, something seems to have gone wrong again between version 4.15.0 and 4.15.1.

Version 4.15.1 now seems to have an issue closing the main window again.

My program in full can be found at the github repo https://github.com/chrisbeardy/Gdirsync

The issue seems to come when trying to exit the main window during a sync, the auto close popup does not appear and the main window stays. At the next blocking pop up, teh main window closes.

It's a change between 4.15.0 and 4.15.1 that caused your problem?

Can you describe the problem in a step by step way? I'm not familiar with your program, code, what you mean by "during a sync", how an auto-close popup is part of it, etc.

Your prior code example was great as it demonstrated the problem you're having. I can't quite tell from the 2 sentences in your post exactly what's wrong nor how to duplicate it.

There was very little changed between 4.15.0 and 4.15.1 and it wasn't in this area of the code.

I fixed a very specific corner case that dealt with the debug window in the 4.15 release. There may be another instance where the window count gets out of sync, I just haven't seen it yet.

Sorry, Yes the change between 4.15.0 and 4.15.1 seems to have caused an issue.

When I first opened the pull request, a main window would not close on the 'X' button press until a subsequent window was called or the whole program exited. This was fixed by the script that could be downloaded from github and in release 4.15.0.

I am now experiencing the issue on 4.15.1 where the main window does not close until a non auto close pop up is called.

Sequence is like this:

  1. 'X' pressed on main window.
  2. Auto close pop up is called by code - however this does not show and the main window stays open.
  3. Normal blocking popup is called, this closes main window.

In my code there can be a large wait between steps 2 and 3, and I would prefer that the main window is not on show for this point..

I am happy using 4.15.0 but thought it would be a good idea to flag this up again.

Simplified Example:

import PySimpleGUI as sg
import time


def main():
    # PySimpleGUI Layout
    layout = [
        [sg.Button("Sync", key="syncButton")],
    ]
    window = sg.Window("Gdirsync", layout)
    sync_button = window["syncButton"]

    # App Logic - Main persistent window
    while True:
        event, values = window.read(timeout=500)
        if event is None:
            break
        elif event == "syncButton":
            sg.PopupAutoClose(
                "Syncing ", title="Syncing..."
            )

    # main window should close
    sg.PopupAutoClose(
        "Existing sync jobs will continue in the background",
        title="Gdirsync - Syncing...",
    )

    time.sleep(5)
    sg.Popup(
        "Sync  complete ",
        title="Gdirsync - Sync Complete",
    )


if __name__ == "__main__":
    main()

There is only 2 lines different between 4.15.0 and 4.15.1 and they are this if statement in the popup function that was removed.

            if len(message_wrapped) > local_line_width:
                message_wrapped = textwrap.fill(message, local_line_width)

It has to be a different version that 4.15.0 where things worked differently like perhaps 4.14.1?

One problem I see that might be playing into this is a missing call to window.close(). Even through the user has closed the window, you should still close the window yourself to make sure all cleanup is performed. It's why you see a window.close() at the end of all PySimpleGUI demo programs.

I'll check your provided code shortly. Thanks for posting it.

Oh, yea, this is your problem for sure. You must call windows.close. The fix that was added for Linux to deal with the user pressing the "X" to close the window is handled when the user's code calls Window.close().

Here is the first few lines of the close method:

        try:
            self.TKroot.update()    # On Linux must call update if the user closed with X or else won't actually close the window
        except:
            pass

So, on Linux, without calling close you won't see your window go away. Try adding it and see if that doesn't fix it.

OK thank you

I was going to close this after I got back confirmation that your problem was verified on your system using 4.15 or 4.15.1. Is it OK to close now? You're up and running?

yep, thanks again!

OK, good. This one's been a real bitch to get worked through. It's a weird double-problem that's happening because of the Debug Window's use in a non-blocking application that is then being closed with an "X" which in itself had problems on Linux. I tried the implement a fix that dealt with this odd-ball corner case without potentially impacting 10,000's of other programs that a core-lvel chance could impact.

Thanks for verifying it's all working.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mozesa picture mozesa  路  4Comments

ncotrb picture ncotrb  路  4Comments

xuguojun168 picture xuguojun168  路  3Comments

MikeTheWatchGuy picture MikeTheWatchGuy  路  5Comments

ECOM-Klaus picture ECOM-Klaus  路  4Comments