This question already has an answer here:
Adding pyqtgraph to PyQt6
(1 answer)
Closed 4 days ago.
I am trying to add a GraphicsLayoutWidget from pyqtgraph to a PyQt application. On multiple machines, the code below works without error: I see a QLineEdit input textbox above a black square.
import pyqtgraph as pg
from PyQt5.QtWidgets import QWidget, QLineEdit, QVBoxLayout, QLabel, QApplication
import sys
class Test(QWidget):
def __init__(self, headers: list = None, parent=None):
QWidget.__init__(self, parent=parent)
layout = QVBoxLayout(self)
layout.addWidget(QLabel('QLineEdit'))
w = QLineEdit()
print(type(w))
layout.addWidget(w)
x = pg.GraphicsLayoutWidget()
print(type(x))
layout.addWidget(x)
if __name__ == "__main__":
app = QApplication(sys.argv)
main = Test()
main.show()
app.exec()
However, on one machine, I receive the error below and the code will not run.
File "my_file.py", line 22, in __init__
layout.addWidget(self, w)
TypeError: addWidget(self, a0: QWidget, stretch: int = 0, alignment: Union[Qt.Alignment, Qt.AlignmentFlag] = Qt.Alignment()): argument 1 has unexpected type 'GraphicsLayoutWidget'
I've tried adding a self.setLayout(layout), but this doesn't fix the issue.
I updated both machines so that their installed packages and versions both match. On the non-working machine, I tried uninstalling pyqtgraph and PyQt5, then reinstalling them with PyQt5 first followed by pyqtgraph. The error persists.
On both machines I am running:
Python 3.11.1
PyQt5 5.15.8
pyqtgraph 0.13.1
All other packages that I see listed by pip freeze or pip list are identical in version, i.e. the lists contain the same packages and the same versions of each package.
The print lines in the above code print the class of each object.
For QLineEdit: <class 'PyQt5.QtWidgets.QLineEdit'>.
For GraphicsLayoutWidget: <class 'pyqtgraph.widgets.GraphicsLayoutWidget.GraphicsLayoutWidget'>.
I've run the code in PyCharm as well as from the command line and the result is the same. For some reason, it seems that PyQt5 is not identifying widgets from pyqtgraph.widgets as QWidget.
I don't even know how to reproduce the error on the working machines.
I'm not sure where to go from here.
You may have to specify the stretch.
Can you run this example?
Also I've normally used pyqt.PlotWidget for general graphing with no problems.
Related
I have a problem freezing my tkinter application. As long as I don't import an external library the frozen app works. If I import a module like pandas the app crashes with no error messages. My OS is macOS monterey, I also tried on a windows machine and the same problem happens. Here's an example code:
from tkinter import *
import pandas as pd # it only works after building if this line is ommited
class MyApp(Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.title("Welcome to My_App")
self.geometry('350x200')
app = MyApp()
app.mainloop()```
It seems there is a problem with the conda environment and there is somehow a clash between the conda env and cx_Freeze. It was solved when I created a pyenv.
I am creating a PySide2 application which uses matplotlib. I am running this application from Spyder in an environment with PySide2 installed. This is causing the application to be run from the iPython console. Somewhere along the line, PyQt5 is imported, which I am attempting to purge in order to convince matplotlib that I really do want to use PySide2, NOT PyQt5. Something like following was working until very recently and I am not really sure why it has stopped, but safe to say this method is unreliable. How can I absolutely convince matplotlib that I am wanting PySide2?
I have tried setting the environment variable QT_API in the operating system (Windows 10), but in this case Spyder itself refuses to open.
import sys
import os
ps = list(filter(lambda x: 'PyQt5' in x, sys.modules))
for p in ps:
print(f"purging module {p}")
sys.modules.pop(p)
# matplotlib.__init__ uses this
os.environ["MPLBACKEND"] = "PySide2"
# matplotlib.backends.qt_compat uses this
os.environ["QT_API"] = "PySide2"
import PySide2.QtCore
assert "PyQt5.QtCore" not in sys.modules
assert "PySide2.QtCore" in sys.modules
# rcParams has the right idea
from matplotlib import rcParams
print(rcParams["backend"])
# qt_compat has the WRONG idea!
import matplotlib.backends.qt_compat as qt_compat
print(qt_compat.QT_API)
# The FigureCanvasWidget is of the wrong (PyQt5) type
from matplotlib.backends.backend_qt5agg import FigureCanvas
import inspect
print(inspect.getmro(FigureCanvas))
To answer this question, the reason that it stopped working was because I had set 'activate support' for Matplotlib graphics in the ipython tab under Spyder settings. After unchecking this, the above works.
Running on Windows 10 64 bit and Python 3.7.4 (no Anaconda), the basic script from Terminate PyQt Application
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QLabel, QGridLayout, QWidget
from PyQt5.QtCore import QSize
class HelloWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(640, 480))
self.setWindowTitle("Hello world")
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
gridLayout = QGridLayout(self)
centralWidget.setLayout(gridLayout)
title = QLabel("Hello World from PyQt", self)
title.setAlignment(QtCore.Qt.AlignCenter)
gridLayout.addWidget(title, 0, 0)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = HelloWindow()
mainWin.show()
sys.exit( app.exec_() )
does not exit when starting from Spyder.
The IPython console simply "idles", but never returns. Running the script from the command prompt (i.e. 'python script.py') works OK.
Switching back to a fresh install of Python 3.7.2, everthing works as expected. The IPython version is in both cases 7.7.0.
In both cases (3.7.2 and 3.7.4) all modules including Spyder had been installed via pip.
Any idea why that is? Is it a Spyder related issue?
Keeping the Graphics Backend as not "Inline" is creating this problem.
Either change the graphics backend as,
Tools -> Preferences --> IPython Console -> Graphics --> Graphics Backend as Inline
Or Restore the default settings of the Spyder Environment. Which can be done by,
Tools -> Preference --> Reset to Defaults.
I have Python 3.6.3 and Spyder 3.2.4, both installed along with Pyqt5 yesterday on a computer with a new installation of Windows 10. I am having a problem running some previously written Pyqt5 code in Spyder. The below code shows a minimum code snippet that reproduces the problem.
The Spyder IPython console hangs indefinitely on running the code, and never opens the window. Ctrl-C does not stop execution, so I have to kill Spyder. If I try to run it line by line, I observe that "w.show()" executes but does nothing, while "app.exec()" is the line that hangs. In contrast, if I instead run it from the command line console, "w.show()" makes a nonfunctional window appear, while "app.exec()" makes the window functional. All of the non-pyqt code I have run in Spyder executes just fine.
I'd prefer to develop code in Spyder because running code from the command line often takes 30-60s to start (presumably from the imports.)
I could run the code in Spyder on my old (now broken) system, so clearly it is a problem with my installation or computer. But I am at a loss as to what. I have already tried disabling my virus software, updating all of the relevant packages with pip, resetting Spyder from the Anaconda prompt, and restarting the computer. Any other ideas?
import sys
from PyQt5.QtWidgets import QApplication, QWidget
if not QApplication.instance():
app = QApplication(sys.argv)
else:
app = QApplication.instance()
print("app started")
w = QWidget()
w.resize(250, 250)
w.move(200, 200)
w.setWindowTitle('Test window')
print('app setting')
w.show()
print("shown")
app.exec_()
#sys.exit(app.exec_())
print("exit")
When running this in python it needs to be modified as below. I've modified your script a little to be able to let it run for you some of the main PyQt conventions. See also my inline comments to make sense of what you're trying to accomplish with your print lines. Enjoy!
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget
class MyMainUI(QtWidgets.QMainWindow):
def __init__(self, parent=None):
print ' Start Main'
super(MyMainUI, self).__init__(parent)
self.setWindowTitle('Test window')
self.resize(250, 250)
self.move(200, 200)
MySpidercodeHook()
def MySpiderCodeHook(self):
...link/run code...
if __name__ == '__main__':
app = QApplication(sys.argv) # no QApplication.instance() > returns -1 or error.
# Your setting up something that cannot yet be peeked
# into at this stage.
print("app started")
w = MyMainUI() # address your main GUI application
# not solely a widgetname..that is confusing...
x = 200
y = 200
# w.move(x, y) # normally this setting is done within the mainUI.
# See also PyQT conventions.
print 'app setting: moving window to position : %s' % ([x, y])
w.show()
print("shown")
app.exec_()
#sys.exit(app.exec_()) # if active then print "exit" is not shown..
# now is while using app.exec_()
#sys.exit(-1) # will returns you '-1' value as handle. Can be any integer.
print("exit")
sys.stdout.flush() # line used to print "printing text" when you're in an IDE
# like Komodo EDIT.
I am trying to compile a bare-bones wxPython project in Python 3 using py2app.
py2app 0.13 <pip>
wxPython 4.0.0a3.dev3059+4a5c5d9 <pip>
Python 3.5.3 :: Anaconda custom (x86_64)
OS X 10.12.4
Here is my setup.py file:
from setuptools import setup
import sys
sys.setrecursionlimit(2000) # need this to prevent max recursion depth reached
APP = ['wx_py2app.py']
DATA_FILES = []
OPTIONS = {'plist': {'PyRuntimeLocations':
['/Users/***/anaconda/lib/libpython3.5m.dylib',
'/Users/***/Python/simple_examples/dist/wx_py2app.app/Contents/Frameworks/libpython3.5m.dylib']}
}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
Here is my wxPython code:
import wx
class simpleapp_wx(wx.Frame):
def __init__(self, parent, wx_id, title):
wx.Frame.__init__(self, parent, wx_id, title, size=(100, 100))
self.Show()
if __name__ == "__main__":
app = wx.App()
frame = simpleapp_wx(None, -1, 'my application')
app.MainLoop()
I had to make a few patches. First, I had to hard code /Users/***/anaconda/lib/libpython3.5m.dylib into py2app/build_app.py, or else it would look for libpython3.5.dylib instead and crash here:
ValueError: '/Users/***/anaconda/lib/libpython3.5.dylib'
Second, I patched PyQt5/uic/port_v2/load_plugin.py to avoid a syntax error, and PyQt5/uic/port_v2/ascii_upper.py which was using deprecated string.maketrans.
My bare-bones project works fine in alias mode, but in non-alias mode the project compiles, but then when I open it it immediately terminates:
Detected missing constraints for <private>. It cannot be placed because there are not enough constraints to fully define the size and origin. Add the missing constraints, or set translatesAutoresizingMaskIntoConstraints=YES and constraints will be generated for you. If this view is laid out manually on macOS 10.12 and later, you may choose to not call [super layout] from your override. Set a breakpoint on DETECTED_MISSING_CONSTRAINTS to debug. This error will only be logged once.
As a side note, my project does work without this problem when I compile it in alias mode. Otherwise, I haven't been able to figure out anything about this error. How can I debug or fix this?