Giter Site home page Giter Site logo

spyder-ide / qtpy Goto Github PK

View Code? Open in Web Editor NEW
957.0 33.0 151.0 976 KB

Provides an uniform layer to support PyQt5, PySide2, PyQt6, PySide6 with a single codebase

License: MIT License

Python 100.00%
python qtpy spyder qt-gui pyqt pyside pyside2 pyside6 pyqt6 closember

qtpy's People

Contributors

almarklein avatar altendky avatar astrofrog avatar cam-gerlach avatar ccordoba12 avatar czaki avatar daelonsuzuka avatar dalthviz avatar daniel-edler avatar davvid avatar dgoeries avatar dgovil avatar goanpeca avatar jschueller avatar krokosik avatar kumattau avatar kurtjacobson avatar larsoner avatar matthieudartiailh avatar milanmatic avatar nodd avatar pre-commit-ci[bot] avatar random-developer avatar renefritze avatar rlaverde avatar stonebig avatar stsav012 avatar sylvaincorlay avatar tlambert03 avatar tobiasgehring avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qtpy's Issues

Feature Request: PySide2 support

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

QHeaderView.setSectionResizeMode

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.

Missing Classes

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!

anaconda-navigator load fail, because #47 delete the attribute 'QT_VERSION_STR'

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'

Add basic project documentation and example usage

Written and edited by @CAM-Gerlach (OP was initially empty):

  • Add/move general information currently contained in __init__ docstring to the README for visibility
  • Clarify that QtPy follows PyQt5 conventions, and link Qt and PyQt5 API docs
  • Add examples of using QtPy in place of the specific bindings
  • List/describe the methods/helpers specific to QtPy (listed in #61 )
    • from qtpy.QtCore import Signal, Slot
    • QFileDialog helpers
    • qtpy.QtCore.__version__
    • Others?
  • Document the QtPy-specific environment variables (FORCE_QT_API, etc)
  • Describe the main package-level constants (PYQT5, PYSIDE2, etc)
  • Clarify the benefits of using QtPy with regard to cross-Qt-version migration, and link success stories (described in #62 )
  • Clarify Qt version compatibility in the readme

Add tests for untested modules

These modules are:

  • QtDesigner
  • QtNetwork
  • QtOpenGL
  • QtPrintSupport
  • QtSvg
  • QtTest

@rlaverde, you can look at test_qtmultimedia for inspiration. Please note that QtTest and QtDesigner are not available for PySide2.

QIntValidator left in QtWidgets, should be in QtGui

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?

Include core doc files in PyPi releases

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?

Anaconda Spyder Keyboard input error

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

Random test failures on Debian infrastructure

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?

Missing copyright headers

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.

QDesktopServices split into QDesktopServices and QStandardPaths

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

QtMultimedia support

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?

Importing qtpy should not raise exceptions

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!

you should add QIcon to QtWidgets...

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

Kernel died, restarting cycle happening very often

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>

uic.loadUiType is missing

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?

Add QHeaderView.setSectionResize for Qt4 layer

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.

Add PYQT5 / PYQT4/PYSIDE boolean variables

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.

Behavior mismatch between PyQt and PySide implementation of loadUi

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.

Letting you know about the existence of Qt.py

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:

  1. Remain a single-file implementation.
  2. Enable code written explicitly for PySide2 to run on any other binding.
  3. Not implement anything; just remap Qt 4 bindings to Qt 5 (again, to PySide2 specifically)
  4. Document and aggressively test differences.

We'll be keeping an eye on your developments and hope our coexistence will make us both stronger. I hope we can be friends!

Python3 qtpy uses deprecated __version__ attribute from PySide

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.

upgrading qtpy from 1.1.2 to 1.2.0 breaks spyder with qt4

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.

Remove `import *`

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:

  • qtpy/QtCore.py
  • qtpy/QtDesigner.py
  • qtpy/QtGui.py
  • qtpy/QtNetwork.py
  • qtpy/QtPrintSupport.py
  • qtpy/QtSvg.py
  • qtpy/QtWidgets.py

Add loadUI functionality

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).

Inject itself into sys.modules for other PyQt versions

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.

wheel package format

Would it be possible to propose it in wheel package format on pypi ?

python setup.py sdist bdist_wheel --universal
twine upload dist/* 

Add documentation for methods or helpers that are specific to qtpy

This includes documenting

  • from qtpy.QtCore import Signal, Slot
  • The use of the openfiledialog openfolderdialog helpers (study the option of overloading QFileDialog... which would also need documentation as it would change the default behavior)
  • Where to find the Qt version from qtpy.QtCore import __version__

CircleCI is only using PyQt5

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 ;-)

Simplify QtCore.py

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 ?

Request for a new bugfix release

Please consider making a new (bugfix) release (soon) which include commit 088c58e.

Right now, this bug forces the pyzo project to vendor qtpy instead of depending on it. A new stable release would allow us to place a versioned dependency on qtpy and ultimately drop the vendoring.

Thanks.

help() > modules crashes because of QtPy

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

race condition: sys.stdout faster than sys.stderr

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.

del some names in QtCore ?

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 *)

qInstallMessageHandler <-> qInstallMsgHandler

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).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.