[Qgis-developer] PyQt4.QtCore.QVariant represents a mapped type and cannot be instantiated

Mark Coletti mcoletti at gmail.com
Thu Oct 2 09:03:32 PDT 2014


On Wed, Oct 1, 2014 at 5:06 PM, Gary Sherman <gsherman at geoapt.com> wrote:

> On 10/1/14 12:55 PM, Mark Coletti wrote:
>
>> I'm writing a qgis python plugin and have encountered a curious
>> problem.  I've successfully tested the plugin's dialog standalone via
>> ipython.  However, I get the following error when I try to execute the
>> same code from within qgis: "PyQt4.QtCore.QVariant represents a mapped
>> type and cannot be instantiated".
>>
>>
> Your answer is here: http://hub.qgis.org/wiki/
> quantum-gis/Python_plugin_API_changes_from_18_to_20
>
> QVariant is no longer present in QGIS since we use the sip 2.0 api.
> Use regular strings rather than a QVariant.


I'm posting a follow up here on the odd chance that someone else has the
same problem and greps for it on this mailing list.  I'm relatively new to
python-based qgis plugins, and found that most of the extant documentation
for PyQt was for sip 1.0 api; and, worse yet, there was no mention that
there were two versions.  So it's very, very easy for a newbie to fall into
the same trap I did.

First, the link you provided was helpful except with regards to situations
where a **null, or empty, QVariant** was returned.  I found that returning
empty strings and empty lists yielded all manner of strange and
counter-intuitive behavior for my table.  I.e., both horizontal and
vertical headers were missing altogether, and the cells were mysteriously
populated with uncheckable check boxes.  The solution was simple: return
None.  I would have done that *first*, but read somewhere that that
wouldn't work.  :(

So, for future reference for those wanting to do this same thing as I was,
that is creating a Qt table from a model for use within qgis, here's a
stripped down version of my class:

from PyQt4 import QtGui, QtCore, Qt
from PyQt4.QtCore import Qt, QDateTime

from Event import Event


class Events(QtCore.QAbstractTableModel) :

    # column headers
    headers = ['Created', 'Name', 'Description']

    def __init__(self, parent = None):
        super(Events, self).__init__(parent)
        self.events = []


    def rowCount(self, parent=QtCore.QModelIndex()) :
        return len(self.events)


    def columnCount(self, parent=QtCore.QModelIndex()) :
        return len(self.headers)


    def data(self, index, role) :
        if not index.isValid() :
            return None #With sip v 1.0 used to be QVariant()
        elif role != Qt.DisplayRole :
            return None

        if index.column() == 1 :
            return self.events[index.row()].name
        elif index.column() == 2 :
            return self.events[index.row()].description
        elif index.column() == 0 :
            return
QDateTime.fromMSecsSinceEpoch(self.events[index.row()].created)
        return None


    def headerData(self, section, orientation, role):
        if role == Qt.DisplayRole :
            if orientation == Qt.Horizontal :
                return self.headers[section]
            elif orientation == Qt.Vertical :
                return str(self.events[section].categoryID)
        return None

    def addEvent(self, categoryID, name, description = '', created = 0) :
        self.events.append( Event( name, description, categoryID, created )
)


I did find a way to force ipython to use sip 2.0, which was particularly
useful for when I wanted to test the dialog standalone.  In my
"~/.ipython/profile_default/ipython_config.py" I placed the following:

import sip
try:
    sip.setapi('QDate', 2)
    sip.setapi('QDateTime', 2)
    sip.setapi('QString', 2)
    sip.setapi('QtextStream', 2)
    sip.setapi('Qtime', 2)
    sip.setapi('QUrl', 2)
    sip.setapi('QVariant', 2)
except ValueError, e:
    raise RuntimeError('Could not set API version (%s): did you import
PyQt4 directly?' % e)


So, while in ipython I could use the "gui qt" command and The Right Thing
would happen: sip 2.0 would be used, so I could then test within the proper
sip API context.  (H/t to
http://cyrille.rossant.net/making-pyqt4-pyside-and-ipython-work-together/)

Hopefully someone out there at sometime will find this useful!

Cheers,

Mark
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20141002/04359574/attachment.html>


More information about the Qgis-developer mailing list