I have some code (see below) that works as expected under Python 2, but when I execute it under Python 3 it raises the exception:
Traceback (most recent call last):
File "./test3.py", line 23, in <module>
programsComboBox.addItem("Jan Novak",QtCore.QVariant("661107/3939"))
TypeError: PyQt4.QtCore.QVariant represents a mapped type and cannot be instantiated
Why is this and is there any workaround?
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
import sys
def activated(i):
data=programsComboBox.itemData(i)
label.setText("Rodne cislo: "+data.toString())
app = QtGui.QApplication(sys.argv)
mainWindow = QtGui.QMainWindow()
mainWindow.setWindowTitle("QVariant")
mainWidget=QtGui.QWidget(mainWindow)
mainWindow.setCentralWidget(mainWidget)
layout=QtGui.QVBoxLayout(mainWidget)
label=QtGui.QLabel("Rodne cislo: ",mainWidget)
programsComboBox=QtGui.QComboBox(mainWidget)
programsComboBox.addItem("Jan Novak",QtCore.QVariant("661107/3939"))
programsComboBox.addItem("Jakub Dvorak",QtCore.QVariant("750802/1278"))
layout.addWidget(programsComboBox)
layout.addWidget(label)
app.connect(programsComboBox,QtCore.SIGNAL("activated (int)"),activated)
mainWindow.show()
sys.exit(app.exec_())
Update: For this simple code it’s enough to add these before the first PyQt4 import
import sip
sip.setapi('QVariant', 1)
But in the real code I can’t do that (somewhere in a different place QVariant requires api2).
Is there any reason why you have to use a QVariant?
If you add your item as a string:
then the code should work in Python 2 and 3.
I don’t use Python 3 myself so can’t test this, but the modification runs fine on Python 2.7.
EDIT:
I was curious, so I tested this in a VM using Python 3.2. It seems that
.itemData()will return a string object rather than a QVariant in Python 3.In addition to using a string when adding an item as above you could modify your
activatedfunction to:so that it would work with Python 2 and 3. If the return of
.itemData()isn’t a string then the function will convert to a string using.toString().I’m not sure if this is the correct way, but it works for me. I still need to look into the whole 2 to 3 porting thing properly.