Crash when running PyQt5 with matplotlib on iPython - python

I want to use matplotlib on my own GUI application, so decided to implement it using PyQt5. I wrote the test code below.
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
import matplotlib as mpl
mpl.use('Qt5Agg')
import matplotlib.pyplot as plt
class MyApp(QMainWindow):
def __init__(self):
super().__init__()
self.show()
self.raise_()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyApp()
sys.exit(app.exec_())
However, I was faced with a weird problem.
When I ran the code on iPython, there is no problem.
The 2nd running is also OK.
But, after I launched the application 3rd times and closed it, iPython freezed with some messages. The message is as follows.
QEventLoop: Cannot be used without QApplication
QSocketNotifier: Can only be used with threads started with Thread
This problem can be reproduced on my PC. Why such a crash occurs?
I use python (3.5.2), iPython (5.1.0), and matplotlib (1.5.3). PC's OS is Mac OS X (10.11.4).

Related

SetWindowFlags immediately closes the program

I am trying to run the following script inside a software called Anki. This is basically an addon (a plugin) that makes the program to be always on top. This is the MRE:
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget
import time
app = QApplication([])
window = QWidget()
window.show()
def start():
while True:
window.setWindowFlags(Qt.WindowStaysOnTopHint)
#window.show()
#app.exec()
time.sleep(1)
start()
This is the closer I could get to the actual error I'm getting. Whenever the program runs the line window.setWindowFlags(Qt.WindowStaysOnTopHint), it immediatly closes the window and becomes unable to reach window.show(). Since this is just a plugin to the base app, I assume all plugins are loaded AFTER the main window has opened and within the main window. So if you close the main window, all plugins also stop running. How can I prevent the main window from closing?
There should only be one QApplication, and you don't have to create a new QApplication since anki creates it. Nor is a while True necessary since it will block the eventloop and even less use time.sleep since it also blocks the eventloop.
import time
from aqt import gui_hooks
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget
window = QWidget()
window.setWindowFlags(window.windowFlags() | Qt.WindowStaysOnTopHint)
gui_hooks.main_window_did_init.append(window.show)

QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True) not working at all on python

I've been programming an application with PySide2 and Python 3.8, and i was trying to enable HiDPi, and i found that adding this at the start of the script
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
was supposed to do the trick.
But it did not work for me. The window is shown with regular dpi (96ppp), while the whole system and apps are running on 125% (120ppp). Am I doing sth wrong?
Code:
import sys
from PySide2 import QtWidgets, QtGui, QtCore, QtMultimedia
"""
some functions
"""
if __name__ == "__main__":
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QMainWindow()
label = QtWidgets.QLabel(window)
label.setText("hey")
window.show()
app.exec_()
Screenshot (On the screenshot is difficult to appreciate the difference, I'm sorry):
System specs:
Windows 10 Pro 64bit
Python 3.7.8
PySide2 5.15.2
I found the answer when testing the code on another computer. It seems like default Qt scaling alghoritm sets the scaling settings for 100-149% to 100% and 150% or + to 200% scaling.
I mean:
If you have windows 10 scale set to 100% or 125%, it will be shown with 100% scaling
But instead, if you have windows 10 scale set to 150%, 175% or 200%, the window will be shown wit 200% scaling.
For PySide2 as far as I can tell you need to run from the QCoreApplication, setting attributes before initialising the app.
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
app = QtWidgets.QApplication(sys.argv)

Python - How do I get my GUI to display in Spyder

I'm new to creating GUI's in Python and can't seem to get over the first hurdle.
I'm using Anaconda - Spyder and I normally run all (mainly mathematical) code through this (and the IPython console?).
My issue is that when I run the code below I'm expecting it to display a simple blank window but nothing happens.
Is Spyder/IPython not the best way to do this or is there an issue with my code?
I've tried using the command prompt by typing "python TestScript.py" whilst in the correct directory but I get an error saying 'Python is not recognised as a internal or external command'. Do I need to set up cmd to use Anaconda?
import sys
from PyQt5.QtWidgets import QApplication, QWidget
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWidget()
w.resize(250,150)
w.move(30,30)
w.setWindowTitle('Simple Window')
w.show
sys.exit(app.exec_())
Clearing this one up, as the answer was posted in the comments by Patrick Artner.
Simply adding () after w.show solved the problem.

Different program behavior depending if its main part is enclosed in a function

Right at the beginning I would like to say that I am a very beginner when it comes to writing GUI applications and this is the topic of this question.
I am using Anaconda 4.1.1 as my Python distribution and Spyder as my IDE. I was trying to write a very simple window application using PyQt4 (already installed in Anaconda) or - to be precise - I copied some examples form the Internet and try to make some "experiments" with them. The results are really surprising for me.
The thing is that when I am running the following example in the IPython console:
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.show()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
everything seems to be OK - I can close the window of an application whenever I want and it successfully opens once again when I am running the code once again. But when I make a small modification in the code, namely - getting rid of the main function:
import sys
from PyQt4 import QtGui
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
then I can run my program only once, because when I close it and try to run it once again - the IPython console displays the following message:
It seems the kernel died unexpectedly. Use 'Restart kernel' to continue using this console.
repeating every few seconds. The Kernel itself displays something like that:
QWidget: Must construct a QApplication before a QPaintDevice
I don't really understand how can it happen because for me these two pieces of code should work exactly the same since the only difference between them is presence of the main function which (I believe) is not necessary to make this program work. Why does it give an error the second way?

Pyside UI pops up and then disappears when run from cmd before it can be used?

I am fairly new to python and have made a simple UI using pyside. When run from inside the anaconda IDE the UI works fine, but when I run it using anaconda from the command line \python.exe 'runquacker.py' the UI flashes up and disappears immediately.
The initial script is:
from PySide.QtCore import *
from PySide.QtGui import *
import sys
import quacker
class MainDialog(QDialog, quacker.Ui_Dialog):
def __init__(self, parent=None):
super(MainDialog, self).__init__(parent)
self.setupUi(self)
app = QApplication(sys.argv)
form = MainDialog()
form.show()
The rest of the UI is in quacker.py which collects a bunch of variables from the user, before executing a further analysis.py program using a subprocesscall. The variables are all passed in this way because thats the only way I could get pyside to work with my script!
e.g. For two variables 'plots' and 'block':
subprocess.call([sys.executable, 'd:\\py\\anaconda\\analysis.py', str(plots), str(block)], shell=True)
Ive tried putting a raw_input('Blah..') in a few places but it just causes the program to hang or nothing at all.
Using \python.exe -i runquacker.py also causes the program to hang.
Thanks
You need to add this line at the end of your script: app.exec_()
That's because you need to actually execute your Qt application if you whant to see something.
I'm not pretty sure why it works in Anaconda but if you are using some IDE like Spyder I think it works because Spyder is already running in Qt (so it called QApplication.exec_ before).

Categories