Skip to content

Commit 830b1df

Browse files
committed
added automatic conversion to QColor,QPen,QCursor and QBrush from enums and colors
1 parent 4648a62 commit 830b1df

5 files changed

Lines changed: 96 additions & 7 deletions

File tree

src/PythonQtClassInfo.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -753,13 +753,17 @@ void* PythonQtClassInfo::castDownIfPossible(void* ptr, PythonQtClassInfo** resul
753753
return resultPtr;
754754
}
755755

756-
PyObject* PythonQtClassInfo::findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool& isLocalEnum)
756+
PyObject* PythonQtClassInfo::findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool* isLocalEnum)
757757
{
758-
isLocalEnum = true;
758+
if (isLocalEnum) {
759+
*isLocalEnum = true;
760+
}
759761
int scopePos = name.lastIndexOf("::");
760762
if (scopePos != -1) {
761-
isLocalEnum = false;
762-
// slit into scope and enum name
763+
if (isLocalEnum) {
764+
*isLocalEnum = false;
765+
}
766+
// split into scope and enum name
763767
QByteArray enumScope = name.mid(0,scopePos);
764768
QByteArray enumName = name.mid(scopePos+2);
765769
PythonQtClassInfo* info = PythonQt::priv()->getClassInfo(enumScope);

src/PythonQtClassInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ class PythonQtClassInfo {
195195
void* castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo);
196196

197197
//! returns if the localScope has an enum of that type name or if the enum contains a :: scope, if that class contails the enum
198-
static PyObject* findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool& isLocalEnum);
198+
static PyObject* findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool* isLocalEnum = NULL);
199199

200200
private:
201201
void createEnumWrappers();

src/PythonQtConversion.cpp

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,92 @@ return Py_None;
254254
return object;
255255
}
256256

257-
void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* /*classInfo*/, void* alreadyAllocatedCPPObject)
257+
void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject)
258+
{
259+
void* ptr = alreadyAllocatedCPPObject;
260+
261+
static int penId = QMetaType::type("QPen");
262+
static int brushId = QMetaType::type("QBrush");
263+
static int cursorId = QMetaType::type("QCursor");
264+
static int colorId = QMetaType::type("QColor");
265+
static PyObject* qtGlobalColorEnum = PythonQtClassInfo::findEnumWrapper("Qt::GlobalColor", NULL);
266+
if (typeId == cursorId) {
267+
static PyObject* qtCursorShapeEnum = PythonQtClassInfo::findEnumWrapper("Qt::CursorShape", NULL);
268+
if ((PyObject*)obj->ob_type == qtCursorShapeEnum) {
269+
Qt::CursorShape val = (Qt::CursorShape)PyInt_AS_LONG(obj);
270+
if (!ptr) {
271+
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QCursor(), ptr);
272+
ptr = (void*)((QVariant*)ptr)->constData();
273+
}
274+
*((QCursor*)ptr) = QCursor(val);
275+
return ptr;
276+
}
277+
} else if (typeId == penId) {
278+
// brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
279+
static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
280+
if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
281+
Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
282+
if (!ptr) {
283+
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
284+
ptr = (void*)((QVariant*)ptr)->constData();
285+
}
286+
*((QPen*)ptr) = QPen(QColor(val));
287+
return ptr;
288+
} else if ((PyObject*)obj->ob_type == qtColorClass) {
289+
if (!ptr) {
290+
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
291+
ptr = (void*)((QVariant*)ptr)->constData();
292+
}
293+
*((QPen*)ptr) = QPen(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
294+
return ptr;
295+
}
296+
} else if (typeId == brushId) {
297+
// brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
298+
static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
299+
if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
300+
Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
301+
if (!ptr) {
302+
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
303+
ptr = (void*)((QVariant*)ptr)->constData();
304+
}
305+
*((QBrush*)ptr) = QBrush(QColor(val));
306+
return ptr;
307+
} else if ((PyObject*)obj->ob_type == qtColorClass) {
308+
if (!ptr) {
309+
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
310+
ptr = (void*)((QVariant*)ptr)->constData();
311+
}
312+
*((QBrush*)ptr) = QBrush(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
313+
return ptr;
314+
}
315+
} else if (typeId == colorId) {
316+
// colors can be created from Qt::GlobalColor (and from colors, but that's the default)
317+
if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
318+
Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
319+
if (!ptr) {
320+
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QColor(), ptr);
321+
ptr = (void*)((QVariant*)ptr)->constData();
322+
}
323+
*((QColor*)ptr) = QColor(val);
324+
return ptr;
325+
}
326+
}
327+
return NULL;
328+
}
329+
330+
void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* /*classInfo*/, void* alreadyAllocatedCPPObject)
258331
{
259332
bool ok = false;
260333
void* ptr = NULL;
334+
335+
// autoconversion of QPen/QBrush/QCursor/QColor from different type
336+
if (!info.isPointer && !strict) {
337+
ptr = handlePythonToQtAutoConversion(info.typeId, obj, alreadyAllocatedCPPObject);
338+
if (ptr) {
339+
return ptr;
340+
}
341+
}
342+
261343
if (PyObject_TypeCheck(obj, &PythonQtInstanceWrapper_Type) && info.typeId != PythonQtMethodInfo::Variant) {
262344
// if we have a Qt wrapper object and if we do not need a QVariant, we do the following:
263345
// (the Variant case is handled below in a switch)

src/PythonQtConversion.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ class PYTHONQT_EXPORT PythonQtConv {
152152
protected:
153153
static QHash<int, PythonQtConvertMetaTypeToPythonCB*> _metaTypeToPythonConverters;
154154
static QHash<int, PythonQtConvertPythonToMetaTypeCB*> _pythonToMetaTypeConverters;
155+
156+
//! handle automatic conversion of some special types (QColor, QBrush, ...)
157+
static void* handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject);
155158

156159
//! converts the list of pointers of given type to Python
157160
static PyObject* ConvertQListOfPointerTypeToPythonList(QList<void*>* list, const QByteArray& type);

src/PythonQtMethodInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray
135135
if (type.typeId == PythonQtMethodInfo::Unknown || type.typeId >= QMetaType::User) {
136136
bool isLocalEnum;
137137
// TODOXXX: make use of this flag!
138-
type.enumWrapper = PythonQtClassInfo::findEnumWrapper(type.name, classInfo, isLocalEnum);
138+
type.enumWrapper = PythonQtClassInfo::findEnumWrapper(type.name, classInfo, &isLocalEnum);
139139
}
140140
} else {
141141
type.typeId = QMetaType::Void;

0 commit comments

Comments
 (0)