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.
https://www.PySimpleGUI.com
Other
13.43k stars 1.83k forks source link

[Question] Question of shortcut #6752

Closed ingdariogiacomelli closed 5 months ago

ingdariogiacomelli commented 6 months ago

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

Question


Environment

Operating System

Windows version ('10', '10.0.19041', 'SP0', 'Multiprocessor Free')

PySimpleGUI Port (tkinter, Qt, Wx, Web)

tkinter


Versions

Python version (sg.sys.version)

3.10.0 (tags/v3.10.0:b494f59, Oct 4 2021, 18:46:30) [MSC v.1929 32 bit (Intel)]

PySimpleGUI Version (sg.__version__)

5.0.2

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

8.6.10


Your Experience In Months or Years (optional)

Years Python programming experience Years Programming experience overall No Have used another Python GUI Framework? (tkinter, Qt, etc) (yes/no is fine)


Troubleshooting

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

Detailed Description

When a PSG window is launched from a desktop shortcut, and for some reason an error occurs in the python code that breaks python, the window disappears - as is normal - but no one knows why. Is there a way to know why everything disappeared?

Code To Duplicate

# Paste your code here

Screenshot, Sketch, or Drawing

PySimpleGUI commented 6 months ago

One way I do this is by putting a try around the event loop, or around a piece of code that may be having trouble. This Demo Program shows one way to go about it:

https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Exception_Traceback_Popup.py

ingdariogiacomelli commented 6 months ago

Ah, thank you very much, I hadn't thought about trying the whole event loop! Of course it is strange that among the properties of the shortcut at Windows level there is no option to avoid closing it in case of errors. Anyway, thanks so much for your help, I'll try as you suggested.

PySimpleGUI commented 6 months ago

The "closure problem" will happen regardless of how you launched your application. Because the program exits, all windows that are currently open will close. The purpose of the try is to delay the program from exiting so an additional window can be shown. Of course, this assumes that you can still open a new window. If something has gone really badly and nothing can be displayed at all, then you can write to a log file (one solution among many).

ingdariogiacomelli commented 6 months ago

When I have this type of problem I launch the window from inside an already open command prompt window, at least this way I can see the error... oh yes or otherwise use the logs... ok thanks for the help.

PySimpleGUI commented 6 months ago

This could mean that it's related to the "Working Directory" or "Current Directory" that you are running inside in your command line prompt. That's one difference that will be present between a double-clicked .py/.pyw file versus manually launched. See if you can capture with a try statement why you're crashing.

ingdariogiacomelli commented 6 months ago

I have already captured the error I had, but this chat was very useful, because I hadn't thought about putting the whole event in the try box (but why sometimes simple things don't come to mind?) and then because I had missed the correct way to display the error in PSG, which you told me indicated in the example link. Thank you very much, and good work!

ingdariogiacomelli commented 6 months ago

was a banal string + None concatenation as string ... they came from database fields ... :-/

PySimpleGUI commented 6 months ago

Thank you so much for the "thank you"! image It means a lot knowing we're making a difference. I appreciate you taking the time to provide some details. It's really helpful to see/understand problems.

I wrote something about errors a long time ago that is in the Cookbook that may be helpful too: https://docs.pysimplegui.com/en/latest/cookbook/original/exception_handling/

ingdariogiacomelli commented 6 months ago

Thanks for the additional link! I will study it carefully. I have always taken the protection of possible errors lightly (I confess ... but I have the mitigating circumstance that with Python and PSG things go so well that in the end there are few "unforeseen" errors ...) and I simply go to print to understand something about it ... I've never been a phenomenon with try except ... but I'll definitely have to improve, I realize that, otherwise it happens like yesterday, that I go to click a button and before I can do it everything disappears (and between I fall off my chair a bit) :-/

PySimpleGUI commented 6 months ago

Sounds like you're doing great to me!

I like this software development mantra:

Make it run Make it right Make it fast

We're all learning as we go when writing software. I like your "unforeseen errors" description. That's exactly what they were too.... unforeseen.... and now, they've become "seen", and you're learning ways of dealing with them.

I don't see anything you've written as unusual or taking a development path that's "wrong". You're writing software like the rest of us... learning and adding error checking to "make it right". Keep doing what you're doing

image

jason990420 commented 6 months ago

Folowing code demo another way for it -- Add special code, then no try...except required.

No more test, so not sure if anything wrong.

import traceback, sys
import PySimpleGUI as sg

def handle_exception(exc_type, exc_value, exc_traceback):
    tb = traceback.TracebackException.from_exception(exc_value)
    message = ''.join(tb.format())
    sg.popup(message, title="Traceback", button_justification="right")

sys.excepthook = handle_exception

layout = [[sg.Text("Hello World")]]
window = sg.Window("Test", layout)
window = sg.Window("Test", layout)        # Reuse the layout to test PSG alarm

1/0                                       # Normal exception
PySimpleGUI commented 6 months ago

Excellent suggestion! I'll look at ways to get this built into PySimpleGUI itself so that it's easy to "enable" making a popup with traceback call using this mechanism. Love it! This is good stuff.

ingdariogiacomelli commented 6 months ago

Thank you very much Jason, your suggestion seems to work perfectly for me! i will try in more strutured program where i have a lot of single windows launched from unique menu. I could put this error handling via sys. in just one point of the code and find it active everywhere for all the individual programs I launch ... regardless of the window launched (without changing them) ... but I'll do some tests (then I'll let you know).

ingdariogiacomelli commented 6 months ago

since I develop ERP management software, I have many windows that I launch, and this one above would be the best, because I wouldn't have to modify them one by one

ingdariogiacomelli commented 6 months ago

Jason's suggestion is great, because compact, and I will use it. But now I would like to delve deeper into the matter. The case that is close to my heart is this: from a menu I launch various independent PSG programs. In each of these an error can obviously occur, and until yesterday - since I didn't manage exceptions - everything disappeared and I didn't see what was happening. Now, with the Jason method, I finally see the error and can take action (video 1). And it's already more than excellent! However after the error, the window goes away. So I went back to the method suggested first but put it internally to the event loop, so that in case of an error, the event loop doesn't break. In fact now I have the whole story of the error, but I close this one, the window continues to live and nothing closes. This is the result I wanted to obtain, I wanted to share it, for any other suggestions you may have. However in this method, I have to insert try except in all programs. I'm totally fine with it, it's really not a lot of effort and I finally have programs that don't break. Would it be possible to achieve the same thing with just the application checkpoint? I'm afraid not, because I believe that not breaking the cycle of events is something at the individual window level, but I ask you to know what you think. I repeat that I didn't have too much need, because python+psg are excellent for developing with few errors, however as the complexity of the window increased, it became important for me and I had to understand how to solve it.

Video 1: https://www.youtube.com/watch?v=n_mVwxZPx8Y

Video 2: https://www.youtube.com/watch?v=0w6sRTewy5A

while sw_contina_lettura_eventi:

        event, values = window.read()
        print(event)

        try:

           ..... a lot of event checks ....
           ..... a lot of event checks ....
           ..... a lot of event checks ....

        except Exception as e:
            tb = traceback.TracebackException.from_exception(e)
            message = '\n'.join(tb.format())
            sg.Print(message, keep_on_top=True)

self.window.close()

p.s. the Jason tb = traceback.TracebackException.from_exception(e) message = '\n'.join(tb.format()) is very very better clear than the other one in the first link example because is a complete error display point by point

ingdariogiacomelli commented 6 months ago

So the best for me is try except in event loop + jason way to display the complete error (was the video2). Further suggestions? improvements? Thank you very much!

PySimpleGUI commented 6 months ago

the best for me

Put on the spot on this one

image

I like to claim, "there is no best"... but that only applies to general questions. There may be a best in this detailed of a situation. I like the idea of localized error handling in and around the event loop.

One of my Weather Gadgets, that looks like this:

image

has an event loop that looks like this:

    window = create_window(win_location, settings)

    while True:  # Event Loop
        event, values = window.read(timeout=refresh_in_milliseconds)
        if event in (None, '-QUIT-', 'Exit', sg.WIN_CLOSE_ATTEMPTED_EVENT):
            sg.user_settings_set_entry('-win location-', window.current_location())  # The line of code to save the position before exiting
            break
        try:
            if event == '-CHANGE-':
                x, y = window.current_location()
                settings = change_settings(settings, (x + 200, y+50))
                window.close()
                window = create_window(win_location, settings)
            elif event == '-REFRESH-':
                sg.popup_quick_message('Refreshing...', keep_on_top=True, background_color='red', text_color='white',
                                       auto_close_duration=3, non_blocking=False, location=(window.current_location()[0]+window.size[0]//2-30, window.current_location()[1]+window.size[1]//2-10))
            elif event == 'Edit Me':
                sg.execute_editor(__file__)
            elif event == 'Versions':
                sg.main_get_debug_data()
            elif event != sg.TIMEOUT_KEY:
                sg.Print('Unknown event received\nEvent & values:\n', event, values, location=win_location)

            update_weather()
            update_metrics(window)
        except Exception as e:
            sg.Print('*** GOT Exception in event loop ***', c='white on red', location=window.current_location(), keep_on_top=True)
            sg.Print('File = ', __file__, f'Window title: {window.Title}')
            sg.Print('Exception = ', e, wait=False)
    window.close()

Rather than use a popup that blocks, I print to the Debug Window and keep going. The wait parm is on there so that if I use the same code around the entire main function/event loop, it'll keep the program from exiting if I set wait=True. Most programs I use the popup with traceback so that I can click the button and have it open PyCharm to that line of code that had the error (I'm quite lazy).