Python PyQt Close Hidden Window - python

I create my main window as hidden because I just need it to do something in the background. I don't call self.show(), then when it's done, I call self.close(), but it looks like the close() function doesn't work on a window that isn't visible. I'm probably missing something obvious, but I can't seem to find any answers in my Google searches. I'm using PyQt6 and running Python 3.10.5.
I know that I can call show() first and close() immediately after, but that makes the window appear for a flash and takes focus away from the main view. I also know that I can call QApplication.instance().quit() to completely close the app (as this background task is all the app is doing), but I want to make sure there's not a better solution.

Related

PyQT force rendering some widget before calling other function

I am designing a GUI for a Python project that manages some simulations. As the simulations take some time, I want to have a window that tells the user to wait, popping up when the simulation is started.
Currently, the code is like
def start_simulation(self):
self.calculation_running_dialog.show()
heavy_function_call(self)
self.calculation_running_dialog.hide()
However, I face the following problem: When the simulation is started the window does appear, but it is rendered with a transparent body in Ubuntu and with an empty (white) body in Windows. Only after the heavy function call has terminated, the window is rendered properly. How can I force the window to be displayed properly before the simulation starts?
Recently, I have asked a similar question here: PyQT force update textEdit before calling other function.
For that purpose, the repaint() function turned out to be the solution. But for the current problem, neither self.calculation_running_dialog.repaint() nor self.calculation_running_dialog.update() or self.calculation_running_dialog.textLabel.repaint() does the trick.
Any suggestions?

Functions acting strange when run as thread in Kivy/Python

I am building an app that, when the user hits a 'run' button, generates a table of buttons.
Because this process takes a while, I want to add a popup or progress bar to alert the user that the function is running and not frozen. To do this I decided to create a popup and call my function using threading so that the screen will be updated when the function starts (as opposed to once it is done).
mythread = threading.Thread(target=run_function)
mythread.start()
The trouble is that when I call my function from the above code it works very strangely: the columns of my table are the wrong width, some of my buttons are arbitrarily empty, and others have the wrong fill color. To fix this, all I need to do is to remove the threading operation and simply call run_function()
Any idea why this is happening?
I am new to Python, so it is likely some dumb mistake, but I have no idea. What is different between a process running as a thread and its default operation?
Disclaimer: I haven't worked with Kivy.
Not every framework works well with multithreading.
But most of the GUI frameworks have an event loop which is responsible for managing user events (mouse clicks, keyboard) and queued drawing operations (widgets).
In your case if don't want the UI to be freezed, you should regularly give control to your framework's event loop.
I guess kivy.base.EventLoopBase.dispatch_input is what you need to call to show an added widget or to handle user events.

How to hide a Widget when the program starts in PyQt?

I have some objects in a PyQt GUI that I wish to be hidden when the program runs until a button is pressed that shows them. So far all my attempts have failed, I have experimented with Signals/Slots but I can't seem to find a way of calling a function without an action (e.g. a button press). I would like to know if it is possible to call hide() on an object in this way, and if so, how.
To Close:
QtCore.QObject.connect(self.closeWidget, QtCore.SIGNAL(_fromUtf8("activated()")), widgetName.close)
To Show:
QtCore.QObject.connect(self.actionShow, QtCore.SIGNAL(_fromUtf8("activated()")), widgetName.show)
In other words, widgets inherit a close() and show() method.
See http://pyqt.sourceforge.net/Docs/PyQt4/qwidget.html
Also, some example code: http://www.saltycrane.com/blog/2007/06/more-pyqt-example-code/

Force update GUI in kivy

I am writing an app in kivy which does cpu-heavy calculations at launch. I want the app to display what it's doing at the moment along with the progress, however, since the main loop is not reached yet, it just displays empty white screen until it finishes working. Can I force kivy to update the interface?
Basically I'm looking for kivy's equivalent of Tkinter's root.update()
I could create a workaround by defining a series of functions with each calling the next one through Clock.schedule_once(nextFunction, 1), but that would be very sloppy.
Thanks in advance.
Leaving aside the question of whether you should be using threading or something instead (which possibly you should), the answer is just that you should move your cpu calculations to somewhere else. Display something simple initially (i.e. returning a simple widget from your build method), then do the calculations after that, such as by clock scheduling them.
Your calculations will still block the gui in this case. You can work around this by doing them in a thread or by manually breaking them up into small pieces that can be sequentially scheduled.
It might be possible to update the gui by manually calling something like Clock.tick(), but I'm not sure if this will work right, and even if so it won't be able to display graphics before they have been initialised.

How can I close the active window but still run the rest of the execution statements in the function?

I have a function that needs to work between two different windows. It starts off working in one active window. I want it to work with that window until I call
self.Close(true)
This will successfully close the active window, but as far as I understand it, it also terminates any more execution statements I have inside the function. The execution statements that are after the Close call (and still in the same function) are ones I want to be applied to the newly active window.
How can I achieve this? Is there something other than Close I can call?
The usual way to go about this is to have a main wxPython program (i.e. a main window). When you call the long running process, you can hide the main window by calling the frame's Hide() method. When the long running process finishes, you can re-show the main window or you could instantiate a secondary frame and show that while keeping the main window hidden. The secondary frame can show the output from the long running process.
Another approach would be to hide the main frame during the long running process and then when the process finishes, you just update the main frame and re-show it. You could create a completely different panel for the frame and swap it out for the original to make it look like a completely different frame. This tutorial talks about doing this latter suggestion.

Categories

Resources