Closing a python program window leaves program still running in the background - python

I made a program, which uses tkinter to create a window where stuff happens. It contains images and loops to constantly shift and move the images.
Now, when I close the window, the scripts are still running and it creates error messages that it has nowhere to place the images with new coordinates.
I think that the loops are still running. So my question is, how do I close the program all together after clicking the x on the window. Is there a way to bind the x(close window) to terminate the program, or cat n ibe done inside a code, to see when the tkinter window is closed(to me this way seems to be bad, because it would keep checking for if the window is still existing or not).
Thanks a lot!

I had the same issue caused by a top level window I had created and withdrawn but didn't destroy. Properly destroying it fixed my issue.

Related

How do I get the position of a window at the close of the window in MacOS Python

Using PyCharm, Python 3.10, MacBook M1 Monterey
I have a module I wrote to produce a plot. It uses a dialog to create a modal window. It works fine, but the position of the window is hard wired in the code. I can move the window manually but if I close the dialog and start another (refreshing the data) it starts at the default position. I want to be able to move a window and have the next refresh appear at the same position. To do that I need the position of the window when it is closed. My approach was to generate a function that stores the position when the window is moved and use that parameter when the window is closed.
The windows is generated by wx.Dialog. I have tried Bind(wx.EVT_MOVE_END...) but although the bound function is executed when the window is generated, moving the window does not generate a move event.
I started writing Python code in Win10 and had no problems with binding functions but when I got the MacBook, I was unable to get keyboard events to work using Bind(wx.EVT_CHAR_HOOK,...) so it appears that there's something different about MacOS and events in Python. I solved the keyboard problem by adding buttons to the dialog to generate the events that I could generate with keystrokes in Win10. I consider this workaround to be a kluge that indicates that something is not working the way I expect (maybe because I'm a beginner and doing self-study [where 'study' -> error and trial]).
Does anyone know why keyboard events and move events do not work in MacOS? I have no problem with EVT_BUTTON, EVT_TIMER, and EVT_LEFT_DOWN.
https://docs.wxpython.org/wx.MoveEvent.html says that EVT_MOVE should work but EVT_MOVE_END is wxMSW only (I assume that means MicroSoftWindows only?). So I tried wx.EVT_MOVE to no avail.
.
.
.
self.Bind(wx.EVT_MOVE_END,self.MovePlot(self))
def MovePlot(self,parent):
PlotPosition = parent.GetPosition()
print('MovePlot Position', PlotPosition)
gp.PlotPosition=PlotPosition
print('parent',parent,parent.Title,parent.ScreenPosition)
.
.
.
In re-reading the link referenced above I find the possible explanation:
"These events are currently generated for top level (see wx.TopLevelWindow) windows in all ports, but are not generated for the child windows in wxGTK."
So now the question becomes "How do I get an event handler for a child window?"
And "Why does the keyboard event work in Win10 but not in MacOS?"

Window moving behind other open windows when button pressed (Python with Tkinter)

Apologies if this is a completely easy fix and I've just missed it. I am learning Python and I am trying to develop a GUI alongside my backend code using Tkinter. This is completely foreign to me and I have recently come across the problem that when I press my buttons there is a very small chance that it will make my window move behind all other open programs.
I am not entirely sure what is causing this but my guess is it stems somehow from one of two functions I have; one meant to minimise the main root window and the second to reveal it. However, these functions are not called in any place in my program that I would not expect them and the windows being minimised are not the root window (which my two functions act on).
I have both functions added below (hopefully, I am pretty new to SO) but if any additional code is needed I will supply it. I have quite a bit of code and everything else functions perfectly so I didn't want to post all my code is all.
There is no particular combination of button presses or buttons in particular which cause it, it appears to be any of them seemingly at random. It sends whatever window I have up to the taskbar.
def revealMenu():
root.update()
root.deiconify()
def hideMenu():
root.withdraw()

Control position of new Veusz window

This question is about Veusz, a python-based plotting program. Not about usage, but about where to start hacking to fix a particular problem... This is on Windows.
Currently, when the program is launched it starts non-maximized, even if it was maximized last time it was closed. I can modify the shortcut to always start maximized but new windows opened within the app are always non-maximized.
Although it doesn't remember its maximized state, it does remember the size of last non-maximized window. As a workaround, I tried positioning the program top-left and resizing it as if it were maximized. However, when I open new windows from this one, they are offset from the top-left corner by the height of the "window bar". The offset does not cascade though; that is, opening a new window from an offset one results in a window in the same position.
I've been pawing through the program's files looking for somewhere window position might be saved or a default might be set. Not seeing anything, though. This is a Qt app so perhaps it's not Veusz-specific but I'm inclined to think it is. Spyder, for instance is Qt-based but I don't see this problem with it.
Does the community have any suggestions regarding changing this behavior? I don't understand the setup routine well enough yet. The source is on Github if you're feeling that helpful.
The relevant code is here in functions closeEvent (for saving state) and setupWindowGeometry (for loading state).
https://github.com/jeremysanders/veusz/blob/master/veusz/windows/mainwindow.py
Veusz needs to save the state of the window, as well as the geometry. Maybe doing something like this http://doc.qt.io/qt-4.8/restoring-geometry.html

hide pygame window on OSX

Pressing command-H in OSX immediately hides the active window. How do I achieve the same effect, programmatically, from Python? Specifically, I'd like to find a particular window that my application creates and then be able to show & hide it programmatically.
I already know how to do this with pywin32 but I'm afraid my expertise there doesn't quite cover OSX as well.
If it helps, the window in question is one created by pygame. I know that pygame has pygame.display.iconify() but that doesn't satisfy my requirements - the window doesn't disappear immediately, but rather the disappearance is animated, and there's no corresponding "uniconify" function that I can find.
Well, this ended up working. When I want to hide the window, I do pygame.display.quit() and make my code properly handle not having a display. When I want to show it, I do pygame.display.set_mode(...) with the former resolution.
The net effect is that of hiding & showing the window. Unfortunately the window gets created in a different spot than where it started, and although apparently you can tell SDL to create the window in a particular spot, I haven't been able to find a way to get the window's location...

Make a window top priority

I have a root window with a panel on it. Then there is this function, in which I create a TopLevel (another window) for asking input from user. I'm trying to find some way to make it compulsory for user to either enter input and click OK or cancel to dismiss the window before being able to access the root window. It's like when an error message pops up, you can't just ignore it and do other things in the root window. Does anyone have any suggestion for me?
Have a look at Dialog Windows. You can use widget.wait_window(window) to achieve this.
You can do what is called a grab, which forces all events into the window of your choice. There are several methods for managing grab, including grab_set and grab_release.
For an example, see NiceGrab.
When working with grabs, exercise extreme care. It's possible to lock up your computer if you do a global grab and then have a bug that prevents you from releasing it. During development I will often implement a timer that kills the program after a minute or so, so if I lock everything up it will be automatically released after a short wait.

Categories