spyder-ide / qtpy Goto Github PK
View Code? Open in Web Editor NEWProvides an uniform layer to support PyQt5, PySide2, PyQt6, PySide6 with a single codebase
License: MIT License
Provides an uniform layer to support PyQt5, PySide2, PyQt6, PySide6 with a single codebase
License: MIT License
Maybe I'm wrong, but it seems to me that is_old_pyqt
and is_pyqt46
should use PYQT_VERSION
instead of __version__
in https://github.com/spyder-ide/qtpy/blob/master/qtpy/__init__.py#L113. __version__
is now the version of qtpy.
The version of QtPy on PyPi lacks the AUTHORS.md
, CHANGELOG.md
, LICENSE.txt
, and README.md
. The lack of the license in particular is a problem for downstream packagers. Could you please include these in the upcoming bugfix release?
Spyder has a number of global variables for convenience to check whether we are running on PyQt5, PyQt4 or PySide.
It would be nice if those were moved to qtpy. I think that anyone using qtpy could use those.
The README says the API is PyQt5 compatible, yet the PyQt5 identifiers such as QtCore.pyqtSignal
are explicitly deleted in favor of PySide's.
PyQt5's symbols were removed in #47 with IMHO not so great justification:
I still think that the duplicate imports are very weird and not needed
in Qt5 QHeaderView.setResizeMode is deprecated (and thus not existing in pyqt5) and was replaced by QHeaderView.setSectionResizeMode. qtpy should define QHeaderView.setSectionResizeMode if qt4 or pyside is used to not raise an attribute error.
The QDesktopServices from Qt4 has been split into two namespaces, QDesktopServices and QStandardPaths, but there is no support for QStandardPaths in QtPy. I would expect QtPy to support code like:
home_location = QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.HomeLocation)
Qt4 API
http://doc.qt.io/qt-4.8/qdesktopservices.html
Qt5 API
http://doc.qt.io/qt-5/qdesktopservices.html
http://doc.qt.io/qt-5/qstandardpaths.html
PySide has been forked to add Qt5 support so integration into PySide2 would prove very helpful for this project. It should be difficult either since PySide2 just uses 'PySide2' instead. In fact, someone might even be able to write a script to integrate it into the code easily: https://github.com/PySide/pyside2
We need to generate all the things that change between qt4 and qt5 and try to trun them into issues so we can start working on this issues little by little.
At the moment, QtPy crashes completely if used with the latest PyQt4 build from conda-forge:
I wonder if we could make QtPy more tolerant of cases where session support is not enabled, by putting the session-related imports inside a try/except?
Written and edited by @CAM-Gerlach (OP was initially empty):
__init__
docstring to the README for visibilityfrom qtpy.QtCore import Signal, Slot
QFileDialog
helpersqtpy.QtCore.__version__
FORCE_QT_API
, etc)PYQT5
, PYSIDE2
, etc)I liked the approach of py.qode better cause it did not relly on helper functions, but instead it patched QFileDialog to get the correct behavior.
We could do the same and get rid of the helper functions.
Hi qtpy!
Me and fellow developers are working on a shim much like yours, except with a different mindset and target audience (i.e. film and visual effects). We aren't yet sure whether our approach is better or worse than yours, but expect changes to eventually occur relative our narrow target audience to conflict with those of yours (assuming yours is the Spider IDE and/or the general public, though do correct me if I'm wrong!).
Our goals are to:
We'll be keeping an eye on your developments and hope our coexistence will make us both stronger. I hope we can be friends!
When using .ui
files to build an interface graphically with QtDesigner, it is possible to load the interface directly from the .ui
file rather than having to transform it onto python then import it. This is already integrated into PyQt4 and PyQt5, and relatively easy to implement in PySide as seen in python_qt_binding, the concurrent that doesn't support Qt5.
I know it's not the workflow used in spyder, but it would be a great utility for some projects (including mine).
Imports should be named instead of using import *
. It would help for introspection for example.
It was suggester first in #35 (comment)
The modules to update would be:
In QtCore.py
a few variables are renamed but the old names still persist, like pyqtSignal
and Signal
. PyQt variants should be removed.
(PyQt variants are imported by import *
)
The following files are missing a copyright header:
qtpy/_patch/qheaderview.py
Please consider adding one to be consistent with the rest of the (mixed copyright) codebase.
This has to be the greatest strength of this project, yet we do not say anything about it on the readme.
We should give a small description on its importance.
I'm wondering if there is a reason why QtOpenGL is not wrapped in qtpy ?
Hi qtpy,
As discussed in #65, I've got a problem, and it occurs at random.
Reproducible
# Ubuntu 16.04
$ apt-get update
$ apt-get install python3-pyside git
$ git clone https://github.com/spyder-ide/qtpy.git
$ export PYTHONPATH=$(pwd)/qtpy
$ python3
>>> from PySide import QtGui
>>> # setSectionResizeMode is added by qtpy on import
>>> assert not hasattr(QtGui.QHeaderView, "setSectionResizeMode")
>>> import sys
>>> from qtpy import QtWidgets
>>> app = QtWidgets.QApplication(sys.argv)
>>> widget = QtWidgets.QTreeView()
>>> qheaderview = widget.header()
>>> qheaderview.setSectionResizeMode(qheaderview.Fixed)
AttributeError: 'PySide.QtGui.QHeaderView' object has no attribute 'setSectionResizeMode'
The error there is thrown 9/10 times I try. :(
If I remove the line with hasattr
, it works 10/10, so I figure some magic (threaded initialisation?) must be occurring on this line.
I just noticed that we're only using PyQt5 to run our tests on CircleCI. This is of course wrong and must be fixed ASAP.
@goanpeca, this one is for you ;-)
The URL to the home page on https://pypi.python.org/pypi/QtPy/1.0 is currently pointing at a fork
➜
conda list qtpy
qtpy 1.1.2 py35_0
➜ anaconda-navigator
Traceback (most recent call last):
File "/home/xueyao/anaconda3/bin/anaconda-navigator", line 4, in <module>
import anaconda_navigator.app.main
File "/home/xueyao/anaconda3/lib/python3.5/site-packages/anaconda_navigator/app/main.py", line 21, in <module>
from anaconda_navigator.widgets.dialogs.splash import SplashScreen
File "/home/xueyao/anaconda3/lib/python3.5/site-packages/anaconda_navigator/widgets/__init__.py", line 18, in <module>
from anaconda_navigator.utils.analytics import GATracker
File "/home/xueyao/anaconda3/lib/python3.5/site-packages/anaconda_navigator/utils/analytics.py", line 33, in <module>
from qtpy.QtCore import QT_VERSION_STR, QObject, QThread, QTimer, Signal
ImportError: cannot import name 'QT_VERSION_STR'
#47 delete the attribute 'QT_VERSION_STR'
Hi, qtpy is breaking code that does not even use it. This was already warned by @titusjan in #65 (comment)
The following is a snippet where the problem is demonstrated. A PyQt4 program that does not use qtpy but imports it (perhaps it imports some other module that imports qtpy) gets broken. If the qtpy import is removed, the program reaches the print 3
line, but if the import is done, an exception prevents reaching that line.
import sip
sip.setapi('QString', 2)
sip.setapi('QVariant', 2)
sip.setapi('QDate', 2)
sip.setapi('QDateTime', 2)
sip.setapi('QTextStream', 2)
sip.setapi('QTime', 2)
sip.setapi('QUrl', 2)
from PyQt4 import QtGui, QtCore
app = QtGui.QApplication([])
w = QtGui.QHeaderView(QtCore.Qt.Vertical)
w.setResizeMode(w.Fixed)
print 1, w.setResizeMode
# Importing qtpy.Qwidgets changes w!!! (even if never using qtpy)
import qtpy.QtWidgets
print 2, w.setResizeMode
w.setResizeMode(w.Fixed)
print 3
IMHO, simply importing qtpy should never affect programs that do not use it (in the case of taurus-org/taurus#401 , just importing spyder.widgets.editor
breaks our module ).
Would it be possible to avoid patching those methods? (or at least doing something less disruptive than raising an exception?)
Cheers!
I am running openSUSE Tumbleweed and I have the following problem:
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/qtpy/__init__.py", line 119, in <module>
from PySide import __version__ as PYSIDE_VERSION # analysis:ignore
ImportError: cannot import name '__version__'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/bin/spyder3", line 3, in <module>
start.main()
File "/usr/lib/python3.6/site-packages/spyder/app/start.py", line 103, in main
from spyder.app import mainwindow
File "/usr/lib/python3.6/site-packages/spyder/app/mainwindow.py", line 49, in <module>
requirements.check_qt()
File "/usr/lib/python3.6/site-packages/spyder/requirements.py", line 39, in check_qt
import qtpy
File "/usr/lib/python3.6/site-packages/qtpy/__init__.py", line 125, in <module>
raise PythonQtError('No Qt bindings could be found')
qtpy.PythonQtError: No Qt bindings could be found
It seems qtpy
tries to import __version__
, which was only available in the Python2 version of PySide
. I had a quick dir(PySide)
look at the available attributes and there isn't one that handles a version string.
Hi
I think this a function escaped in the hierarchy from QtGui, because I can call this using
from qtpy.QtGui import *
but not
from qtpy.QtWidgets import (QIcon)
I think this is a minimal issue (depends your implementation), but it's contribute to improve order ;).
Thanks
Forwarding a bug reported to me by Santiago Vila from the reproducible builds project. He has experienced some random test failures when building packages for qtpy
multiple times on Debian.
Tests are run at build time for all supported Python versions, via a python -m pytest tests
on their respective build trees wrapped by a call to xvfb-run
. The builds succeed locally and on the Debian builders but fails on the reproducibility builders with the following output:
============================= test session starts ==============================
platform linux2 -- Python 2.7.13, pytest-3.0.5, py-1.4.32, pluggy-0.4.0
PyQt4: not installed
PyQt5: PyQt: 5.7 - Qt: 5.7.1
PySide: not installed
rootdir: /<<PKGBUILDDIR>>, inifile:
collected 8 items
tests/test_main.py .
tests/test_patch_qcombobox.py ..
tests/test_patch_qheaderview.py .
tests/test_qtmultimedia.py .
tests/test_uic.py Aborted
Any idea where this could come from?
Prior to 48eecd3, all of uic
was imported from PyQt in __init__.py
, but now it is only loadUi
in uic.py
. I understand that there may be an issue with the functions not being present in Pyside. Would it be possible to add something similar to the loadUi
implementation?
The following does not seem to work with QtPy:
from qtpy import QtMultimedia
but it does work if we import QtMultimedia directly from either PyQt4 or PyQt5.
Would it be desirable to provide a wrapper over QtMultimedia and QtMultimediaWidgets?
Are there any gotchas?
Scenario:
In my app, I from qtpy.QtCore import Qt
. I run my app with QT_API=pyqt5
, so PyQt5 is preferred, defaulting to PyQt4 if the former is not available. Anyway, PyQt5 is available and my app runs fine.
In some obscure module, or in a stand-alone add-on for my app, I rely on a third-party Python package that imports and works with PyQt4. The import fails. My app breaks.
Use case:
I would like like qtpy to inject itself into sys.modules
so that any requests for objects from PyQt4 are resolved, best effort, from qtpy.
There is some coe like:
from PyQt4.QtCore import *
from PyQt4.QtCore import QCoreApplication
Why is the secon line needed, since import *
is supposed to have imported QCoreApplication
already ?
When running the matplotlib example "embedding_in_qt4.py"
(http://matplotlib.org/examples/user_interfaces/embedding_in_qt4.html#user-interfaces-embedding-in-qt4),I met the error as follows:
File "embedding_in_qt4.py", line 80, in
class ApplicationWindow(QtGui.QMainWindow):
AttributeError: module 'qtpy.QtGui' has no attribute 'QMainWindow'
I have replaced the “PyQt4” by "qtpy" in the line "from qtpy import QtGui, QtCore"
This includes documenting
from qtpy.QtCore import Signal, Slot
from qtpy.QtCore import __version__
Would it be possible to propose it in wheel package format on pypi ?
python setup.py sdist bdist_wheel --universal
twine upload dist/*
Right now the signal contentsSizeChanged
brokes all compatibility with applications that depend on QWebPage's contentsChanged
signal. An example of this is presented on spyder-ide/spyder-terminal#48
Creating a module list crashes because of QtPy version 1.1.2
Windows error message (Windows German)
Problemsignatur:
Problemereignisname: APPCRASH
Anwendungsname: pythonw.exe
Anwendungsversion: 3.5.1150.1013
Anwendungszeitstempel: 576f0390
Fehlermodulname: Qt5Gui.dll
Fehlermodulversion: 5.7.0.0
Fehlermodulzeitstempel: 575a6c44
Ausnahmecode: c0000005
Ausnahmeoffset: 00000000000e226e
Betriebsystemversion: 6.1.7601.2.1.0.256.4
Gebietsschema-ID: 1031
Zusatzinformation 1: 7646
Zusatzinformation 2: 76464eeb47a1e3d49908af68236b05ac
Zusatzinformation 3: 1fda
Zusatzinformation 4: 1fda969d7aac5ad7fe5a776efb2b5b2f
I've posted some description here
While trying to run this simple GUI-based matplotlib
script, I get a kernel died, restarting
message, repeating 3-5 times, every other time I try to run the script.
I suspect this could be tied with PyQt
, as I've used Spyder
and matplotlib
for relatively long and never had this type of behaviour.
from PyQt5.uic import loadUiType
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg as FigureCanvas,
NavigationToolbar2QT as NavigationToolbar)
import numpy as np
from scipy import interpolate
import pandas as pd
Ui_MainWindow, QMainWindow = loadUiType('txfmr.ui')
class Main(QMainWindow, Ui_MainWindow):
def __init__(self,):
super(Main, self).__init__()
self.setupUi(self)
self.fstart = 2
self.fstop = 4
self.fstartLblLine.setText(str(self.fstart))
self.fstopLblLine.setText(str(self.fstop))
self.LpLblLine.setText('1')
self.LsLblLine.setText('1')
self.kLblLine.setText('0.75')
self.w = np.linspace(2*np.pi*self.fstart*1e9,2*np.pi*self.fstop*1e9,101)
self.DrawBtn.clicked.connect(self.draw)
def addmpl(self, fig):
self.canvas = FigureCanvas(fig)
self.mplvl.addWidget(self.canvas)
self.canvas.draw()
self.toolbar = NavigationToolbar(self.canvas, self.mplwindow, coordinates=True)
self.mplvl.addWidget(self.toolbar)
def rmmpl(self,):
self.mplvl.removeWidget(self.canvas)
self.canvas.close()
self.mplvl.removeWidget(self.toolbar)
self.toolbar.close()
def R(self,L,w,rf=1,rf2=1,deg=0):
#rf = 1.78/1.24
r0 = rf*L*1e9
rf2 = 1
alpha = rf2/(w[-1]-w[0])
if deg == 0:
return np.array([r0])
return r0 + (alpha*(w-w[0]))**deg
def calc_txf_std(self,Lp,Ls,k,w,rf=1,rf2=1,deg=0):
RL = 50
Rp = self.R(Lp,self.w,1.78/1.24,rf2,deg) #primary inductance resistance
Rs = self.R(Ls,self.w,4.66/2.4,rf2,deg)
tratio = 1/k*np.sqrt(Lp/Ls)
n = k*np.sqrt(Lp/Ls)
M = k*np.sqrt(Lp*Ls)
Qip = w*Lp/Rp
Qis = w*Ls/Rs
Ql = w*Ls/(Rs+RL)
Rsp = Rp + Ql**2/(1+Ql**2)*n**2*(Rs+RL)
Lsp = Lp*(1-k**2*Ql**2/(1+Ql**2))
Qsp = w*Lsp/Rsp
Rpp = Rsp*(1+Qsp**2)
Lpp = Lsp*(1+Qsp**2)/Qsp**2
Cres = 1/(w**2*Lpp)
Qc = 1/(w*Rp*Cres)
w0 = 1/np.sqrt(Cres*Lp)
ww0 = np.array([(w/wx)**2-1 for wx in w0])
R_e_o = Rs + (w*M)**2/(Rp*(1+(Qc*ww0)**2))
R_e_o_max = np.array([x.max() for x in R_e_o[:]])
ww0 = (w/w0)**2-1
IL = 10*np.log10(Rsp/(Ql**2/(1+Ql**2)*n**2*RL))
Lprime_p = Lp*(1 - (1-k**2*Ql**2/(1+Ql**2))*(1+Qsp**2)/Qsp**2)
Qprime_p = w*Lprime_p/Rp
R_o_res = Rs + (w*M)**2/(Rp*(1+Qprime_p**2))
X_o_res = w*Ls - (w*M)**2/(w*Lprime_p*(1+Qprime_p**2)/Qprime_p**2)
RTL = 20*np.log10(abs((R_e_o_max-50)/(R_e_o_max+50)))
return({'tratio':tratio,'n':n,'Ql':Ql,'Qsp':Qsp,'Rsp':Rsp,'Lsp':Lsp,'Rpp':Rpp,'Lpp':Lpp,'Cres':Cres,'IL':IL,\
'Lprime_p':Lprime_p,'Qprime_p':Qprime_p,'R_o_res':R_o_res,'X_o_res':X_o_res,'RL':RTL,'Rs':Rs,'Rp':Rp,'Qip':Qip,'Qis':Qis})
def plt_stuff(self,Lp=1,Ls=0.9,k=0.85):
fig = Figure()
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(223)
ax4 = fig.add_subplot(224)
ax1.plot(self.w*1e-9/(2*np.pi),self.calc_txf_std(Lp*1e-9,Ls*1e-9,k,self.w)['Rpp'],label='Rpp')
ax1.legend()
fig.suptitle('voltage ratio :{:.2f}'.format(self.calc_txf_std(Lp*1e-9,Ls*1e-9,k,self.w)['tratio']))
ax1.grid(True)
ax3.plot(self.w*1e-9/(2*np.pi),self.calc_txf_std(Lp*1e-9,Ls*1e-9,k,self.w)['IL'],label='IL (dB)',color='g')
ax3.legend()
ax3.grid(True)
ax4.plot(self.w*1e-9/(2*np.pi),self.calc_txf_std(Lp*1e-9,Ls*1e-9,k,self.w)['RL'],label='RL (dB)',color='k')
ax4.legend()
ax4.grid(True)
if len(self.calc_txf_std(Lp*1e-9,Ls*1e-9,k,self.w)['Rs']) == 1:
ax2.plot([self.w[0]*1e-9/(2*np.pi),self.w[-1]*1e-9/(2*np.pi)],[self.calc_txf_std(Lp*1e-9,Ls*1e-9,k,self.w)['Rs'],self.calc_txf_std(Lp*1e-9,Ls*1e-9,k,self.w)['Rs']],label='Rs',color='r')
ax2.plot([self.w[0]*1e-9/(2*np.pi),self.w[-1]*1e-9/(2*np.pi)],[self.calc_txf_std(Lp*1e-9,Ls*1e-9,k,self.w)['Rp'],self.calc_txf_std(Lp*1e-9,Ls*1e-9,k,self.w)['Rp']],label='Rp',color='b')
else:
ax2.plot(w*1e-9/(2*pi),calc_txf_std(Lp*1e-9,Ls*1e-9,k,w)['Rs'],label='Rs',color='r')
ax2.plot(w*1e-9/(2*pi),calc_txf_std(Lp*1e-9,Ls*1e-9,k,w)['Rp'],label='Rp',color='b')
ax2.legend()
ax2.grid(True)
self.rmmpl()
self.addmpl(fig)
def draw(self,):
Lp = float(self.LpLblLine.text())
Ls= float(self.LsLblLine.text())
k= float(self.kLblLine.text())
self.fstart = float(self.fstartLblLine.text())
self.fstop = float(self.fstopLblLine.text())
self.w = np.linspace(2*np.pi*self.fstart*1e9,2*np.pi*self.fstop*1e9,101)
self.plt_stuff(Lp,Ls,k)
if __name__ == '__main__':
import sys
from PyQt5 import QtGui,QtWidgets
import numpy as np
import pandas as pd
fig1 = Figure()
app = QtWidgets.QApplication(sys.argv)
main = Main()
main.addmpl(fig1)
main.show()
sys.exit(app.exec_())
The UI is create with Qt Designer
and left as XML
file:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="mplwindow" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="mplvl"/>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>100</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>30</y>
<width>91</width>
<height>80</height>
</rect>
</property>
<layout class="QFormLayout" name="tx_params">
<item row="0" column="0">
<widget class="QLabel" name="LpLbl">
<property name="text">
<string>Lp (nH)</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="LpLblLine">
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="LsLbl">
<property name="text">
<string>Ls (nH)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="LsLblLine">
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>10</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="kLbl">
<property name="text">
<string>k</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="kLblLine">
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QPushButton" name="DrawBtn">
<property name="geometry">
<rect>
<x>110</x>
<y>30</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>Draw</string>
</property>
</widget>
<widget class="QWidget" name="formLayoutWidget_2">
<property name="geometry">
<rect>
<x>200</x>
<y>30</y>
<width>81</width>
<height>80</height>
</rect>
</property>
<layout class="QFormLayout" name="f_range">
<item row="0" column="0">
<widget class="QLabel" name="fstartLbl">
<property name="text">
<string>f start</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="fstartLblLine">
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="fstopLbl">
<property name="text">
<string>f stop</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="fstopLblLine">
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>10</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>290</x>
<y>30</y>
<width>40</width>
<height>20</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>GHz</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>290</x>
<y>56</y>
<width>40</width>
<height>20</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>GHz</string>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
In qt-helpers, we patch QComboBox because on PySide, storing Python objects in the userData
causes segmentation faults (while it works correctly in PyQt4 and PyQt5). Here is our implementation (which is only used with PySide):
https://github.com/glue-viz/qt-helpers/blob/master/qt_helpers.py#L320
Would you be interested in something similar here? If so, I can open a PR.
PyQt4.uic.loadUi
provides support for custom widgets using the "Promoted Widget" feature of Qt Designer. The convention in PyQt4 is to specify the import module path using the header file section. For example, if mypackage.mymodule.MyWidget
is the custom Widget, then in Qt Designer you would list the header file as mypackage/mymodule.h
and the class name as MyWidget
and loadUi
would translate that to mypackage.mymodule.MyWidget
.
The loadUi
implementation for PySide in qtpy doesn't appear to support this behavior.
How is this normally handled? should we add an environment.yaml to set a full environment for qtpy? or should we add a specfile/requirements-test.txt file?
These modules are:
@rlaverde, you can look at test_qtmultimedia
for inspiration. Please note that QtTest and QtDesigner are not available for PySide2.
With PyQt4 or PySide as backend, QValidator and QDoubleValidator are properly imported when importing qtpy.QtGui / deleted when importing qtpy.QtWidgets. But the poor QIntValidator seems to have been left behind... I didn't check in detail but maybe other classes were forgotten too, since this was apparently a manual process?
If I do pip install -U qtpy, spyder crashes with the following message:
Traceback (most recent call last):
File "/home/developer/.virtualenvs/dev3/lib/python3.5/site-packages/spyder/app/mainwindow.py", line 3001, in main
mainwindow = run_spyder(app, options, args)
File "/home/developer/.virtualenvs/dev3/lib/python3.5/site-packages/spyder/app/mainwindow.py", line 2905, in run_spyder
main.setup()
File "/home/developer/.virtualenvs/dev3/lib/python3.5/site-packages/spyder/app/mainwindow.py", line 869, in setup
self.projects = Projects(self)
File "/home/developer/.virtualenvs/dev3/lib/python3.5/site-packages/spyder/plugins/projects.py", line 71, in init
self.setup_project(self.get_active_project_path())
File "/home/developer/.virtualenvs/dev3/lib/python3.5/site-packages/spyder/widgets/projects/explorer.py", line 226, in setup_project
show_all=self.show_all)
File "/home/developer/.virtualenvs/dev3/lib/python3.5/site-packages/spyder/widgets/explorer.py", line 195, in setup
self.common_actions = self.setup_common_actions()
File "/home/developer/.virtualenvs/dev3/lib/python3.5/site-packages/spyder/widgets/projects/explorer.py", line 55, in setup_common_actions
self.toggle_hscrollbar(self.show_hscrollbar)
File "/home/developer/.virtualenvs/dev3/lib/python3.5/site-packages/spyder/widgets/projects/explorer.py", line 70, in toggle_hscrollbar
self.header().setResizeMode(QHeaderView.ResizeToContents)
File "/home/developer/.virtualenvs/dev3/lib/python3.5/site-packages/qtpy/_patch/qheaderview.py", line 83, in setResizeMode
raise Exception('setResizeMode is only available in Qt4. Use '
Exception: setResizeMode is only available in Qt4. Use setSectionResizeMode instead.
If I revert with pip install qtpy==1.1.2, Spyder starts normally.
System and Qt4 info:
Ubuntu 16.04, Python 3.5.2, Qt 4.8.7, PyQt 4.11.4, SIP 4.18.1
I am using Spyder 3.0.2.
QStyleOptionViewItemV4
is renamed to QStyleOptionViewItem
but the old name still persists in the namespace.
I am using tightVNC to access my server. On the server, I installed anaconda spyder and the standalone spyder respectively. The anaconda spyder has the problem to show the correct keyboard response, but the standalone spyder works just fine.
Ubuntu Linux: 16.04
Anaconda 2.7.13 :: Anaconda 4.2.0 (64-bit) | Spyder: 3.1.2 |
Qt version 5.6.2
Error Log for theAnaconda Spyder Launch
Qt: XKEYBOARD extension not present on the X server.
Fontconfig error: Cannot load default config file.
I did some research. I think the qt module messed up the keyboard mapping, which makes the anaconda spyder not responding correctly the keyboard type ins.
Please check and help.
Thanks
Calls to write to stdout and stderr are not ouput to the console in the same sequence as they are called. The call to stdout often overtakes the call to stderr.
This code:
from sys import stdout, stderr
stderr.write("writing to stderr\n")
stdout.write("writing to stdout\n")
prints
writing to stdout
writing to stderr
The same happens for this code:
print >> stderr, "writing to stderr"
print "writing to stdout"
Note that the sequence is reversed.
This is on Win 7 with Spyder 3.1.4 and Python 2.7, both in the Python and IPython consoles. It can't be reproduced in IDLE.
The installer for the message handler is called qInstallMsgHandler in PyQt4 and pyside and qInstallMessageHandler in PyQt5. In PyQt5 the message handler got an extra argument called context.
The reason to use qtpy is to have a program running in all three environments. Thus, there should be a unified way to use it (e.g. set context to None if pyqt4/pyside is used).
There's a bunch of missing classes on QtGui:
QApplication, QFileIconProvider, QItemDelegate, QHBoxLayout,
QVBoxLayout, QDialog, QLineEdit, QLabel, QSizePolicy, QDialogButtonBox,
QLayout, QSpinBox, QDoubleSpinBox, QListView, QTreeView, QCompleter,
QTableView, QAbstractItemView, QPushButton, QDirModel, QSplitter,
QHeaderView, QFileDialog, QGridLayout, QAbstractItemDelegate
Some of these seem to be quite fundamental classes, so was wondering why they are not included.
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.