I realize that this question has been asking several times before, though none of them seem to apply to my situation. I have installed PyQt, and am simply trying to open up a window as such:
import sys
from PyQt4 import QtGui as qt
segmentation = qt.QApplication(sys.argv)
main = qt.QWidget()
main.show()
All the other questions I have looked at on here usually were caused by an error with the window going out of scope because of the window's show method being called from within a function, or something similar.
My code uses no functions at all so this cannot be the issue. This should work as it is, no? I am following this tutorial:
https://www.youtube.com/watch?v=JBME1ZyHiP8
and at time 8:58, the instructor has pretty much exactly what I have written, and their window shows up and stays around just fine. Mine displays for a fraction of a second and then closes.
Screen shot of the code block from the video to compare to the code block provided here:
Without seeing all of your code, I'm assuming that you're missing the sys.exit() bit.
For your specific code sys.exit(segmentation.exec_()) would be what you needed.
segmentation = qt.QApplication(sys.argv)
main = qt.QWidget()
main.show()
sys.exit(segmentation.exec_())
A little bit of detail of what's going on here.
segmentation = qt.QApplication(sys.argv) creates the actual application.
main = qt.QWidget() and main.show() creates the Widget and then displays.
When executing the python script, this does exactly what you tell it to:
Create an application
Create a widget
Show the widget
Finished. End of the script.
What the sys.exit() does is cleanly closes the python script. segmentation.exec_() starts the event driven background processing of QT. Once the segementation.exec_() is finished (user closes the application, your software closes the application, or a bug is encountered) it'll return a value which is then passed into the sys.exit() function which in turn terminates the python process.
Related
I've created a tkinter app designed to let users create and take quizzes locally. Unfortunately, if a user closes the window by hitting the 'x' in the corner instead of hitting the "quit" button on the main menu, the window is destroyed but the process remains in the background. It isn't a huge deal as it stops using any CPU and only holds on to about 40mb of memory per instance, but this just seems pretty sloppy for an app that I'd like to deploy.
I have no idea what specifically is refusing to exit when the window is closed, and as it could be coming from almost anywhere in my 1700 lines of code, I'm instead looking for some more general tips for identifying what's still running or for killing any remaining processes when the window is closed. I'm happy to provide my code if anyone thinks it would help, though I reiterate that it's quite long given that I can't identify the source of the particular problem.
You can use state() from Tk to check if the window is open or not. When the window is open it should return 'normal' and if the window isn't open it will return something else.
What I would do is add something that checks the state of the window and exit the app when it's closed.
while app_is_running:
if root.state() != 'normal':
sys.exit(0)
I am working on a scientific algorithm (image processing), which is written in C++, and uses lots of parallelization, handled by OpenMP. I need it to be callable from Python, so I created a CPython package, which handles the wrapping of the algorithm.
Now I need some UI, as user interaction is essential for initializing some stuff. My problem is that the UI freezes when I run the algorithm. I start the algorithm in a separate thread, so this shouldn't be a problem (I even proved it by replacing the function call with time.sleep, and it works fine, not causing any freeze). For testing I reduced the UI to two buttons: one for starting the algorithm, and another just to print some random string to console (to check UI interactions).
I also experienced something really weird. If I started moving the mouse, then pressed the button to start the computation, and after that kept moving the mouse continuously, the UI did not freeze, so hovering over the buttons gave them the usual blueish Windows-style tint. But if I stopped moving my mouse for a several seconds over the application window, clicked a button, or swapped to another window, the UI froze again. It's even more strange that the UI stayed active if I rested my mouse outside of the application window.Here's my code (unfortunately I cannot share the algorithm for several reasons, but I hope I manage to get some help even like this):
if __name__ == "__main__":
from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget
from PyQt5.QtCore import QThread, QObject, pyqtSignal
import time
from CustomAlgorithm import Estimator # my custom Python package implemented in C++
class Worker(QObject):
finished = pyqtSignal()
def run(self):
estimator = Estimator()
estimator.calculate()
# if the above two lines are commented, and the next line is uncommented,
# everything's fine
# time.sleep(5)
print("done")
app = QApplication([])
thread = QThread()
window = QWidget()
layout = QVBoxLayout()
# button to start the calculation
btn = QPushButton("start")
layout.addWidget(btn)
btn.clicked.connect(thread.start)
# button to print some text to console
btn2 = QPushButton("other button")
layout.addWidget(btn2)
btn2.clicked.connect(lambda: print("other button clicked"))
window.setLayout(layout)
# handling events
worker = Worker(app)
worker.moveToThread(thread)
thread.started.connect(worker.run)
worker.finished.connect(thread.quit)
worker.finished.connect(worker.deleteLater)
thread.finished.connect(thread.deleteLater)
window.show()
app.exec_()
I tried multiple variants of using threads, like threading.Thread, multiprocessing.Process, PyQt5.QtCore.QThread (as seen above), even napari's worker implementation, but the result was the same. I even tried removing omp from the code, just in case it interferes somehow with python threads, but it didn't help.
As for the reason I use python, is that the final goal is to make my implementation available in napari.
Any help would be highly appreciated!
Because of Python's "Global Interpreter Lock", only one thread can run Python code at a time. However, other threads can do I/O at the same time.
If you want to allow other threads to run (just like I/O does) you can surround your code with these macros:
Py_BEGIN_ALLOW_THREADS
// computation goes here
Py_END_ALLOW_THREADS
Other Python threads will be allowed to run while the computation is happening. You can't access anything from Python between these two lines - so get that data in order before Py_BEGIN_ALLOW_THREADS.
Reference
After running the program in the background, when I execute I get (Not responding in the title bar).
And if I try to close it shows this
And after closing it start giving kernel killing message as shown in the screen on the right side.
I am running "Anaconda-2.3.0-Windows-x86_64". Please tell me what to do.
Spyder does some weird things where it doesn't run code in a new process and so it can keep things around from the last time the code was run. Quite frankly I would find this extremely annoying, and so I don't use Spyder (which means this answer is potentially not perfect, and someone else should probably post another with a better solution!)
What you need to do is check to see if the QApplication already exists, and only create it if does not.
if QApplication.instance():
app = QApplication.instance()
else:
app = QApplication(sys.argv)
...
app.exec_()
I think you should always be calling app.exec_(), regardless of whether the QApplication has been created before.
Personally though, I launch python files from a standard windows command line so that I always know it is starting fresh.
Not Responding image
You just need to add this: app.exec_() at the end of the code
Working fine
import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
window = QtGui.QWidget()
window.setGeometry(50,50,500,300)
window.setWindowTitle("PyQt Ecuador")
window.show()
app.exec_()
I've been fighting for three hours now to get this process multithreaded, so that I can display a progress box. I finally got it working, insomuch as the process completes as expected, and all the functions call, including the ones to update the progress indicator on the window.
However, the window never actually displays. This is a PyGObject interface designed in Glade. I am not having fun.
def runCompile(obj):
compileWindow = builder.get_object("compilingWindow")
compileWindow.show_all()
pool = ThreadPool(processes=1)
async_result = pool.apply_async(compileStrings, ())
output = async_result.get()
#output = compileStrings() #THIS IS OLD
compileWindow.hide()
return output
As I mentioned, everything works well, except for the fact that the window doesn't appear. Even if I eliminate the compileWindow.hide() command, the window never shows until the process is done. In fact, the whole stupid program freezes until the process is done.
I'm at the end of my rope. Help?
(By the way, the "recommended" processes of using generators doesn't work, as I HAVE to have a return from the "long process".)
I'm not a pyGobject expert and i don't really understand your code. I think that you should post more. Why are you calling the builder in a function? you can call it at the init of the GUI?
Anyways.. It seems that you are having the common multithread problems..
are you using at the startup GObject.threads_init() and Gdk.threads_init() ?
Then, if you want to show a window from a thread you need to use Gdk.threads_enter() and Gdk.threads_leave().
here is an useful doc
I changed the overall flow of my project, so that may affect it. However, it is imperative that Gtk be given a chance to go through its own main loop, by way of...
if Gtk.events_pending():
Gtk.main_iteration()
In this instance, I only want to call it once, to ensure the program doesn't hang.
(The entire program source code can be found on SourceForge. The function in question is on line 372 as of this posting, in function compileModel().
I'm new to python and now I want to try wxpython, but I can't continue even at the very beginning.
Following the toturial,
import wx
app = wx.App(False)
frame = wx.Frame(None, wx.ID_ANY, "Hello World")
frame.Show(True)
after I did that, the new windows stops responding as soon as the it appears or I try to click it. Then I can only force close it and the editor restarts.
All the same on shell or IDLE, even all the same on different computers(I happened to bought a new one). Maybe I've done something wrong since I searched the internet and it seems no one encounters the problem, but I can't figure it out.
I'm using the latest python(x,y).
In addition, I tried tkinter also on my old computer and the problem is the same, if I remember rightly.
that's because the app loop is not running. usually, you also have to do:
app.MainLoop()
after frame.Show(). of course, now your console will be running the main loop, and you won't get your console back until after the app exits (well, when your main window closes), which probably isn't what you want either.
i haven't used python(x,y), but from a quick look, it looks like it supports IPython(x,y). If you use that as the console, then you can do
%gui wx
after loading, and then instead of creating/running the app yourself, IPython itself implements the app and does event processing in a special way as an input hook - which means that while it is waiting for you to type something, instead of just waiting, it actively polls the gui to see if there are active events and processes them if they are. This can create some interesting problems as well, but then you can just create the window & show it, and it will work correctly....