Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong type returned for the icon? #23

Closed
baudren opened this issue Jun 24, 2015 · 24 comments
Closed

Wrong type returned for the icon? #23

baudren opened this issue Jun 24, 2015 · 24 comments

Comments

@baudren
Copy link

baudren commented Jun 24, 2015

Hi,

thanks for the project, and for using some layer of abstraction to make it simpler to support both PySide and PyQt.

I am getting a strange error on my ubuntu 14.04, though, when trying out the simple example in the readme. I am trying to interface with my PySide project, doing the following:

icon = qta.icon('fa.flag')
button = QtGui.QPushButton(icon, 'New entry', self)  # class instance as parent

but when running, I get the following trace:

TypeError: 'PySide.QtGui.QPushButton' called with wrong argument types:
  PySide.QtGui.QPushButton(QIcon, unicode, Editing)
Supported signatures:
  PySide.QtGui.QPushButton(PySide.QtGui.QWidget = None)
  PySide.QtGui.QPushButton(PySide.QtGui.QIcon, unicode, PySide.QtGui.QWidget = None)
  PySide.QtGui.QPushButton(unicode, PySide.QtGui.QWidget = None)

The QIcon is probably coming from PyQt? In anyway, it is not understood as PySide.QtGui.QIcon.

If that helps to narrow down the problem:

  • it seems to be absent on windows 8.1
  • I don't have PyQt installed on my system, only PySide

Thanks in advance!

@SylvainCorlay
Copy link
Member

Thanks for reporting. Does your Editing class inherit from QWidget?

@SylvainCorlay
Copy link
Member

@goanpeca this looks like an issue with qtpy.

@goanpeca
Copy link
Member

Hmmmm I will take a look

@goanpeca
Copy link
Member

@baudren Can you print the type of icon?

print(type(icon))
print(icon.__str__)
print(icon.__unicode__)
print(icon.__repr__)

@goanpeca
Copy link
Member

You do not have PyQt on ubuntu or on windows?

@goanpeca
Copy link
Member

Can you show the full script/code of the example you are trying to run?

@baudren
Copy link
Author

baudren commented Jun 25, 2015

Hi @goanpeca

print(type(icon))
<class 'PyQt4.QtGui.QIcon'>

print(icon.__str__)
<method-wrapper '__str__' of QIcon object at 0x2aab6d9e7d60>

print(icon.__unicode__)
AttributeError: 'QIcon' object has no attribute '__unicode__'

print(icon.__repr__)
<method-wrapper '__repr__' of QIcon object at 0x2b379b695d60>

@SylvainCorlay , Editing inherits from QtGui.QFrame, which itself inherits from QWidget. And I agree, it might be an issue from qtpy.

For the presence of PyQt on windows, @egolus is the one for whom it works, maybe he can help with narrowing down the issue.

By the way, I am running python 2.7.6, so not the latest.

@baudren
Copy link
Author

baudren commented Jun 25, 2015

To give a full example (which, by the way, does not work on my other setup, Win8.1, with Anaconda 2.1 (Python 2.7.8), under cygwin):

import sys
from PySide import QtGui
import qtawesome as qta

app = QtGui.QApplication(sys.argv)

wid = QtGui.QWidget()
wid.setWindowTitle('Simple')
icon = qta.icon('fa.flag')
button = QtGui.QPushButton(icon, 'toto', wid)

wid.show()

sys.exit(app.exec_())

This snippet without the icon displays a toto button, but with the icon, gives the same trace as mentionned previously:

Traceback (most recent call last):
  File "simple.py", line 10, in <module>
    button = QtGui.QPushButton(icon, 'Toto', wid)
TypeError: 'PySide.QtGui.QPushButton' called with wrong argument types:
  PySide.QtGui.QPushButton(QIcon, str, PySide.QtGui.QWidget)
Supported signatures:
  PySide.QtGui.QPushButton(PySide.QtGui.QWidget = None)
  PySide.QtGui.QPushButton(PySide.QtGui.QIcon, unicode, PySide.QtGui.QWidget = None)
  PySide.QtGui.QPushButton(unicode, PySide.QtGui.QWidget = None)

@goanpeca
Copy link
Member

Can you put this at the top of your script?

from PySide import QtGui

##
import os
print(os.environ['QT_API'])
os.environ['QT_API'] = 'PySide'
##

import qtawesome as qta

@baudren
Copy link
Author

baudren commented Jun 25, 2015

The print(os.environ['QT_API']) call results in a KeyError: 'QT_API', which means this was not set (even though the from PySide call is done before that).

However, setting os.environ['QT_API'] = 'PySide' solves the problem: the icon is displayed (however, now I have the #4 issue, and the icon does not scale with the fontsize.)

What do you recon? Why is the os.environ not set properly? Should this be on qtpy side?

Thanks

@goanpeca
Copy link
Member

Not sure if calling PySide is supposed to set an environment variable, I just wanted to check.

QtPy will autodetect the backend in this order, PyQt5, PyQt4, PySide, unless it is enforced using os.environ['QT_API'] = 'PySide', so if you are using a specific backend in your application you have to ensure that QT_API is set accordingly. I will update the readme to make this clear.

@baudren
Copy link
Author

baudren commented Jun 25, 2015

But precisely - since I do not have PyQt5, nor PyQt4 installed, it should never set it to anything else. I don't think it is right to specify an os.environ when there is nothing to be decided for. Shouldn't it fallback to the first available system?

@goanpeca
Copy link
Member

Well it seems that you do have some remnant of either PyQt4 or PyQt5 in the system

@goanpeca
Copy link
Member

In projects that use the shim (qtpy in this case), there will be no problem cause the project and qtawesome will use the same (whatever that is) but if you are using or aiming a specific backend (pyside in this case) this must be set explicitly before calling qtawesome.

@baudren
Copy link
Author

baudren commented Jun 25, 2015

pip freeze | grep Qt
   QtAwesome==0.1.10
   QtPy==0.1.2

I really have nothing from PyQt4 nor 5 on my system.

Indeed, the problem goes away if I replace my from PySide import QtGui by a from qtpy import QtGui, but this is not a nice solution for existing (potentially large) projects using one or the other. I was expecting a library based on such a thing as qtpy to just work on a project using either distribution. Otherwise, you are providing a completely distribution agnostic package, which is a very good goal in the first place!

@goanpeca
Copy link
Member

What do you get if you do

import sip
import PyQt4

and what do you get when you import

import PyQt5

Regarding...

I was expecting a library based on such a thing as qtpy to just work on a project using either distribution.

It should and I unfortunately cannot reproduce your error. I am using ubuntu 14.04 and have tested the library with only PyQt4, or with only PySide installed and it works on both cases.

However if you have PyQt4 and PySide side by side and in your project you only use PySide, then it will not work and hence why I said "I will update the readme to make this clear."

@baudren
Copy link
Author

baudren commented Jun 25, 2015

Ok, fair enough, the PyQt4 was not showing on pip but was installed, sorry about the confusion. I don't think that one should have to use a virtual environment to separate PyQt from PySide, and that QtPy should solve the problem, but this is probably a QtPy issue.

In any case, now that I realised that I do have PyQt4, I went ahead, and tried the exact same code, but doing from PyQt4 import QtGui:

import sys
from PyQt4 import QtGui
import qtawesome as qta

app = QtGui.QApplication(sys.argv)

wid = QtGui.QWidget()
wid.setWindowTitle('Simple')
icon = qta.icon('fa.flag')
button = QtGui.QPushButton(icon, 'Toto', wid)

wid.show()

sys.exit(app.exec_())

I get this traceback, then:

No handlers could be found for logger "qtpy"
Traceback (most recent call last):
  File "qt.py", line 10, in <module>
    button = QtGui.QPushButton(icon, 'Toto', wid)
TypeError: arguments did not match any overloaded call:
  QPushButton(QWidget parent=None): argument 1 has unexpected type 'PySide.QtGui.QIcon'
  QPushButton(QString, QWidget parent=None): argument 1 has unexpected type 'PySide.QtGui.QIcon'
  QPushButton(QIcon, QString, QWidget parent=None): argument 1 has unexpected type 'PySide.QtGui.QIcon'

There really seems to be something fishy, here. Why would suddenly the icon get the PySide class? It would not be sequential as you are claiming. Maybe this is an indication that the detection of the implementation is faulty, somewhere?

@goanpeca
Copy link
Member

True, it seems something is weird, but in your specific case is clear that you DO have to define the environment variable.

Can you print the os.eviron['QT_API'] as I asked before in your example?

@baudren
Copy link
Author

baudren commented Jun 25, 2015

This time again, os.environ does not contain the key QT_API. If I use from qtpy import ..., then os.environ['QT_API'] is set to pyqt.

@goanpeca
Copy link
Member

Thanks for reporting but given your actual setup (having both a system PyQt4, and a PySide on pip) you need to set the API to use explicitly, otherwise the automatic detection might result in the error case you found.

@SylvainCorlay
Copy link
Member

@baudren, another option is for you to use qtpy for your entire project, with the benefit that your software will work with both pyqt and pyside! It is pretty stable (used in Spyder for a while).
At startup, you could print in stdout the one that is used.

@baudren
Copy link
Author

baudren commented Jun 25, 2015

@SylvainCorlay, sure. I did a quick test by replacing the import statements, and it was breaking the code - I have to adapt all my calls to the PyQt5 syntax, including the tests, which will not be done so quickly. Does qtpy support both python 2 and 3, and supports windows/linux well? I can see no build on Travis.

In any case, thank you for the feedback.

@baudren baudren closed this as completed Jun 25, 2015
@goanpeca
Copy link
Member

@baudren it does support Python 2 and 3 PyQt5, PyQt4 and PySide, but the calls need to resemble the Qt5 api which splitted QtGui into QtGui and QtWidgets.

QtPy will also add in the future some new widgets for common use, like rich text checkboxes and others.

If you experience any problem please report it in the QtPy issue tracker :-)

Thanks!

@SylvainCorlay
Copy link
Member

qtpy is heavily used in Spyder which is Python2/Python3/PySide/PyQt compatible and has a big userbase, hence I am rather confident that you should be able to use it in your application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants