Search code examples
qtpyqtpyqt4python-sip

PyQt4 4.11.4 no longer accepts QBrush(None) or QColor(None)


With PyQt4, I had always been able to initialize QBrush and QColor with None as argument (creates no color etc):

QBrush(None)
QColor(None)

But after I upgraded from 4.11.3 to 4.11.4 (which is a minor upgrade), I found these are no longer accepted:

>>> QColor(None)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: arguments did not match any overloaded call:
  QColor(Qt.GlobalColor): argument 1 has unexpected type 'NoneType'
  QColor(int): too many arguments
  QColor(QVariant): argument 1 has unexpected type 'NoneType'
  QColor(): argument 1 has unexpected type 'NoneType'
  QColor(int, int, int, int alpha=255): argument 1 has unexpected type 'NoneType'

I have tried to search on the changes between 4.11.3 and 4.11.4 but cannot see any relevant information that explains this. And I started to wonder if I am searching the right thing.

Is this caused by the changes in Qt? or PyQt4? or python-SIP?

Also I don't actually understand what the underlying (C++) call in Qt is. Is it actually calling QBrush() and QColor() or is it trying to change Python None to c null?

Thanks, I hope I didn't miss something obvious online.


Solution

  • The PyQt-4.11.4 ChangeLog has this entry:

    2015-02-06 Phil Thompson

    • PyQt4.msp: Fixed all pseudo-ctors that take a QVariant argument. [5c941d8fb16b] <4.11-maint>

    And here's the relevant parts of the diff for sip/QtGui/qcolor.sip:

    --- PyQt-x11-gpl-4.11.3/sip/QtGui/qcolor.sip    2014-11-09
    +++ PyQt-x11-gpl-4.11.4/sip/QtGui/qcolor.sip    2015-06-11
    @@ -75,13 +70,17 @@
    
         QColor(Qt::GlobalColor color /Constrained/);
         QColor(QRgb rgb);
    -    QColor(const QVariant &variant) /NoDerived/;
    +    QColor(const QVariant &variant /GetWrapper/) /NoDerived/;
     %MethodCode
             #if QT_VERSION >= 0x050000
    -        sipCpp = new QColor(a0->value<QColor>());
    +        if (a0->canConvert<QColor>())
    +            sipCpp = new QColor(a0->value<QColor>());
             #else
    -        sipCpp = new QColor(qVariantValue<QColor>(*a0));
    +        if (qVariantCanConvert<QColor>(*a0))
    +            sipCpp = new QColor(qVariantValue<QColor>(*a0));
             #endif
    +        else
    +            sipError = sipBadCallableArg(0, a0Wrapper);
     %End
    
         QString name() const;
    

    So it seems that the copy constructors now check whether QVariant can convert the argument to a QColor/QBrush, and if not, an error is raised.