Skip to content

Commit df7be19

Browse files
committed
fixed support for PythonQt classes in Slot/Signature
print error if keywords are passed to C++ call allows unicode strings on connect/disconnect
1 parent d01c636 commit df7be19

4 files changed

Lines changed: 56 additions & 55 deletions

File tree

src/PythonQtConversion.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,9 +1464,16 @@ QByteArray PythonQtConv::getCPPTypeName(PyObject* type)
14641464
{
14651465
QByteArray result;
14661466
if (PyType_Check(type)) {
1467-
if (PyType_IsSubtype((PyTypeObject*)type, (PyTypeObject*)(&PythonQtClassWrapper_Type))) {
1467+
if (type->ob_type == &PythonQtClassWrapper_Type) {
14681468
PythonQtClassWrapper* wrapper = (PythonQtClassWrapper*)type;
1469-
result = wrapper->classInfo()->className();
1469+
// we have no good decision if this should be a pointer or a const reference
1470+
if (wrapper->classInfo()->isQObject()) {
1471+
// for QObjects, use a pointer
1472+
result = wrapper->classInfo()->className() + "*";
1473+
} else {
1474+
// everything else is a const reference (otherwise the user needs to use strings to specify the type)
1475+
result = wrapper->classInfo()->className();
1476+
}
14701477
} else {
14711478
PyTypeObject* typeObject = reinterpret_cast<PyTypeObject*>(type);
14721479
if (typeObject == &PyFloat_Type) {
@@ -1489,7 +1496,7 @@ QByteArray PythonQtConv::getCPPTypeName(PyObject* type)
14891496
result = "void";
14901497
} else {
14911498
bool dummy;
1492-
result = PyObjGetString(type, true, dummy).toLatin1();
1499+
result = QMetaObject::normalizedType(PyObjGetString(type, true, dummy).toLatin1());
14931500
}
14941501
return result;
14951502
}

src/PythonQtSlot.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,14 @@ PyObject *PythonQtMemberFunction_Call(PythonQtSlotInfo* info, PyObject* m_self,
327327
return NULL;
328328
}
329329

330-
PyObject *PythonQtSlotFunction_CallImpl(PythonQtClassInfo* classInfo, QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject * /*kw*/, void* firstArg, void** directReturnValuePointer, PythonQtPassThisOwnershipType* passThisOwnershipToCPP)
330+
PyObject *PythonQtSlotFunction_CallImpl(PythonQtClassInfo* classInfo, QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject * kw, void* firstArg, void** directReturnValuePointer, PythonQtPassThisOwnershipType* passThisOwnershipToCPP)
331331
{
332+
if (kw != NULL && PyDict_Check(kw) && (PyDict_Size(kw) > 0)) {
333+
QString e = QString("Calling C++ functions with Python keywords is not supported! Function: ") + info->fullSignature(true) + " Keywords: " + PythonQtConv::PyObjGetString(kw);
334+
PyErr_SetString(PyExc_ValueError, e.toLatin1().data());
335+
return NULL;
336+
}
337+
332338
int argc = args?PyTuple_Size(args):0;
333339
if (passThisOwnershipToCPP) {
334340
*passThisOwnershipToCPP = IgnoreOwnership;

src/PythonQtStdDecorators.cpp

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -46,61 +46,53 @@
4646

4747
#include <QCoreApplication>
4848

49-
bool PythonQtStdDecorators::connect(QObject* sender, const QByteArray& signal, PyObject* callable)
49+
bool PythonQtStdDecorators::connect(QObject* sender, const QString& signal, PyObject* callable)
5050
{
5151
bool result = false;
52-
QByteArray signalTmp;
53-
char first = signal.at(0);
54-
if (first>='0' && first<='9') {
55-
signalTmp = signal;
56-
} else {
57-
signalTmp = "2" + signal;
52+
QByteArray signalTmp = signal.toLatin1();
53+
char first = signalTmp.at(0);
54+
if (first<'0' || first>'9') {
55+
signalTmp = "2" + signalTmp;
5856
}
5957

6058
if (sender) {
6159
result = PythonQt::self()->addSignalHandler(sender, signalTmp, callable);
6260
if (!result) {
6361
if (sender->metaObject()->indexOfSignal(QMetaObject::normalizedSignature(signalTmp.constData()+1)) == -1) {
64-
qWarning("PythonQt: QObject::connect() signal '%s' does not exist on %s", signal.constData(), sender->metaObject()->className());
62+
qWarning("PythonQt: QObject::connect() signal '%s' does not exist on %s", signal.toLatin1().constData(), sender->metaObject()->className());
6563
}
6664
}
6765
}
6866
return result;
6967
}
7068

71-
bool PythonQtStdDecorators::connect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot, Qt::ConnectionType type)
69+
bool PythonQtStdDecorators::connect(QObject* sender, const QString& signal, QObject* receiver, const QString& slot, Qt::ConnectionType type)
7270
{
7371
bool r = false;
7472
if (sender && receiver) {
75-
QByteArray signalTmp;
76-
char first = signal.at(0);
77-
if (first>='0' && first<='9') {
78-
signalTmp = signal;
79-
} else {
80-
signalTmp = "2" + signal;
73+
QByteArray signalTmp = signal.toLatin1();
74+
char first = signalTmp.at(0);
75+
if (first<'0' || first>'9') {
76+
signalTmp = "2" + signalTmp;
8177
}
8278

83-
QByteArray slotTmp;
84-
first = slot.at(0);
85-
if (first>='0' && first<='9') {
86-
slotTmp = slot;
87-
} else {
88-
slotTmp = "1" + slot;
79+
QByteArray slotTmp = slot.toLatin1();
80+
first = slotTmp.at(0);
81+
if (first<'0' || first>'9') {
82+
slotTmp = "1" + slotTmp;
8983
}
9084
r = QObject::connect(sender, signalTmp, receiver, slotTmp, type);
9185
}
9286
return r;
9387
}
9488

95-
bool PythonQtStdDecorators::disconnect(QObject* sender, const QByteArray& signal, PyObject* callable)
89+
bool PythonQtStdDecorators::disconnect(QObject* sender, const QString& signal, PyObject* callable)
9690
{
9791
bool result = false;
98-
QByteArray signalTmp;
99-
char first = signal.at(0);
100-
if (first>='0' && first<='9') {
101-
signalTmp = signal;
102-
} else {
103-
signalTmp = "2" + signal;
92+
QByteArray signalTmp = signal.toLatin1();
93+
char first = signalTmp.at(0);
94+
if (first<'0' || first>'9') {
95+
signalTmp = "2" + signalTmp;
10496
}
10597
if (sender) {
10698
result = PythonQt::self()->removeSignalHandler(sender, signalTmp, callable);
@@ -109,31 +101,27 @@ bool PythonQtStdDecorators::disconnect(QObject* sender, const QByteArray& signal
109101
}
110102
if (!result) {
111103
if (sender->metaObject()->indexOfSignal(QMetaObject::normalizedSignature(signalTmp.constData()+1)) == -1) {
112-
qWarning("PythonQt: QObject::disconnect() signal '%s' does not exist on %s", signal.constData(), sender->metaObject()->className());
104+
qWarning("PythonQt: QObject::disconnect() signal '%s' does not exist on %s", signal.toLatin1().constData(), sender->metaObject()->className());
113105
}
114106
}
115107
}
116108
return result;
117109
}
118110

119-
bool PythonQtStdDecorators::disconnect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot)
111+
bool PythonQtStdDecorators::disconnect(QObject* sender, const QString& signal, QObject* receiver, const QString& slot)
120112
{
121113
bool r = false;
122114
if (sender && receiver) {
123-
QByteArray signalTmp;
124-
char first = signal.at(0);
125-
if (first>='0' && first<='9') {
126-
signalTmp = signal;
127-
} else {
128-
signalTmp = "2" + signal;
115+
QByteArray signalTmp = signal.toLatin1();
116+
char first = signalTmp.at(0);
117+
if (first<'0' || first>'9') {
118+
signalTmp = "2" + signalTmp;
129119
}
130120

131-
QByteArray slotTmp;
132-
first = slot.at(0);
133-
if (first>='0' && first<='9') {
134-
slotTmp = slot;
135-
} else {
136-
slotTmp = "1" + slot;
121+
QByteArray slotTmp = slot.toLatin1();
122+
first = slotTmp.at(0);
123+
if (first<'0' || first>'9') {
124+
slotTmp = "1" + slotTmp;
137125
}
138126

139127
r = QObject::disconnect(sender, signalTmp, receiver, slotTmp);

src/PythonQtStdDecorators.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,15 @@ class PYTHONQT_EXPORT PythonQtStdDecorators : public QObject
6464
Q_OBJECT
6565

6666
public Q_SLOTS:
67-
bool connect(QObject* sender, const QByteArray& signal, PyObject* callable);
68-
bool connect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot, Qt::ConnectionType type = Qt::AutoConnection);
69-
bool connect(QObject* receiver, QObject* sender, const QByteArray& signal, const QByteArray& slot, Qt::ConnectionType type = Qt::AutoConnection) { return connect(sender, signal, receiver, slot, type); }
70-
bool static_QObject_connect(QObject* sender, const QByteArray& signal, PyObject* callable) { return connect(sender, signal, callable); }
71-
bool static_QObject_connect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot, Qt::ConnectionType type = Qt::AutoConnection) { return connect(sender, signal, receiver, slot, type); }
72-
bool disconnect(QObject* sender, const QByteArray& signal, PyObject* callable = NULL);
73-
bool disconnect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot);
74-
bool static_QObject_disconnect(QObject* sender, const QByteArray& signal, PyObject* callable = NULL) { return disconnect(sender, signal, callable); }
75-
bool static_QObject_disconnect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot) { return connect(sender, signal, receiver, slot); }
67+
bool connect(QObject* sender, const QString& signal, PyObject* callable);
68+
bool connect(QObject* sender, const QString& signal, QObject* receiver, const QString& slot, Qt::ConnectionType type = Qt::AutoConnection);
69+
bool connect(QObject* receiver, QObject* sender, const QString& signal, const QString& slot, Qt::ConnectionType type = Qt::AutoConnection) { return connect(sender, signal, receiver, slot, type); }
70+
bool static_QObject_connect(QObject* sender, const QString& signal, PyObject* callable) { return connect(sender, signal, callable); }
71+
bool static_QObject_connect(QObject* sender, const QString& signal, QObject* receiver, const QString& slot, Qt::ConnectionType type = Qt::AutoConnection) { return connect(sender, signal, receiver, slot, type); }
72+
bool disconnect(QObject* sender, const QString& signal, PyObject* callable = NULL);
73+
bool disconnect(QObject* sender, const QString& signal, QObject* receiver, const QString& slot);
74+
bool static_QObject_disconnect(QObject* sender, const QString& signal, PyObject* callable = NULL) { return disconnect(sender, signal, callable); }
75+
bool static_QObject_disconnect(QObject* sender, const QString& signal, QObject* receiver, const QString& slot) { return connect(sender, signal, receiver, slot); }
7676

7777
const QMetaObject* metaObject( QObject* obj );
7878

0 commit comments

Comments
 (0)