Fix bug#347 - "Setting properties in constructors gives incorrect results"
Added new function to libpyside: "fillQtProperties".
Reviewer: Luciano Wolf <luciano.wolf@openbossa.org>
Renato Araújo <renato.filho@openbossa.org>
This commit is contained in:
parent
cd7dac40f7
commit
87ea5d920c
4 changed files with 67 additions and 0 deletions
|
|
@ -24,6 +24,10 @@
|
||||||
#include "pyside.h"
|
#include "pyside.h"
|
||||||
#include "signalmanager.h"
|
#include "signalmanager.h"
|
||||||
#include "qproperty.h"
|
#include "qproperty.h"
|
||||||
|
#include <basewrapper.h>
|
||||||
|
#include <conversions.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "qsignal.h"
|
||||||
|
|
||||||
extern "C" void init_signal(PyObject* module);
|
extern "C" void init_signal(PyObject* module);
|
||||||
extern "C" void init_slot(PyObject* module);
|
extern "C" void init_slot(PyObject* module);
|
||||||
|
|
@ -41,5 +45,42 @@ void init(PyObject *module)
|
||||||
SignalManager::instance();
|
SignalManager::instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fillQtProperties(PyObject* qObj, const QMetaObject* metaObj, PyObject* kwds, const char** blackList, unsigned int blackListSize)
|
||||||
|
{
|
||||||
|
|
||||||
|
PyObject *key, *value;
|
||||||
|
Py_ssize_t pos = 0;
|
||||||
|
|
||||||
|
while (PyDict_Next(kwds, &pos, &key, &value)) {
|
||||||
|
if (!blackListSize || !std::binary_search(blackList, blackList + blackListSize, std::string(PyString_AS_STRING(key)))) {
|
||||||
|
QByteArray propName(PyString_AS_STRING(key));
|
||||||
|
if (metaObj->indexOfProperty(propName) != -1) {
|
||||||
|
propName[0] = std::toupper(propName[0]);
|
||||||
|
propName.prepend("set");
|
||||||
|
|
||||||
|
Shiboken::AutoDecRef propSetter(PyObject_GetAttrString(qObj, propName.constData()));
|
||||||
|
if (!propSetter.isNull()) {
|
||||||
|
Shiboken::AutoDecRef args(PyTuple_Pack(1, value));
|
||||||
|
Shiboken::AutoDecRef retval(PyObject_CallObject(propSetter, args));
|
||||||
|
} else {
|
||||||
|
PyObject* attr = PyObject_GenericGetAttr(qObj, key);
|
||||||
|
if (isQPropertyType(attr))
|
||||||
|
PySide::qproperty_set(attr, qObj, value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
propName.append("()");
|
||||||
|
if (metaObj->indexOfSignal(propName) != -1) {
|
||||||
|
propName.prepend('2');
|
||||||
|
PySide::signal_connect(qObj, propName, value);
|
||||||
|
} else {
|
||||||
|
PyErr_Format(PyExc_AttributeError, "'%s' is not a Qt property or a signal", propName.constData());
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} //namespace PySide
|
} //namespace PySide
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <pysidemacros.h>
|
#include <pysidemacros.h>
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
namespace PySide
|
namespace PySide
|
||||||
{
|
{
|
||||||
|
|
@ -41,6 +43,17 @@ inline uint hash(const T& value)
|
||||||
return qHash(value.toString());
|
return qHash(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill QObject properties and do signal connections using the values found in \p kwds dictonary.
|
||||||
|
* \param qObj PyObject fot the QObject.
|
||||||
|
* \param metaObj QMetaObject of \p qObj.
|
||||||
|
* \param blackList keys to be ignored in kwds dictionary, this string list MUST be sorted.
|
||||||
|
* \param blackListSize numbe rof elements in blackList.
|
||||||
|
* \param kwds key->value dictonary.
|
||||||
|
* \return True if everything goes well, false with a Python error setted otherwise.
|
||||||
|
*/
|
||||||
|
PYSIDE_API bool fillQtProperties(PyObject* qObj, const QMetaObject* metaObj, PyObject* kwds, const char** blackList, unsigned int blackListSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the type \p T was registered on Qt meta type system with Q_DECLARE_METATYPE macro, this class will initialize
|
* If the type \p T was registered on Qt meta type system with Q_DECLARE_METATYPE macro, this class will initialize
|
||||||
* the meta type.
|
* the meta type.
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ PYSIDE_TEST(qtimer_singleshot_test.py)
|
||||||
PYSIDE_TEST(qtimer_timeout_test.py)
|
PYSIDE_TEST(qtimer_timeout_test.py)
|
||||||
PYSIDE_TEST(qtnamespace_test.py)
|
PYSIDE_TEST(qtnamespace_test.py)
|
||||||
PYSIDE_TEST(qurl_test.py)
|
PYSIDE_TEST(qurl_test.py)
|
||||||
|
PYSIDE_TEST(setprop_on_ctor_test.py)
|
||||||
PYSIDE_TEST(static_method_test.py)
|
PYSIDE_TEST(static_method_test.py)
|
||||||
PYSIDE_TEST(static_protected_methods_test.py)
|
PYSIDE_TEST(static_protected_methods_test.py)
|
||||||
PYSIDE_TEST(thread_signals_test.py)
|
PYSIDE_TEST(thread_signals_test.py)
|
||||||
|
|
|
||||||
12
tests/QtCore/setprop_on_ctor_test.py
Normal file
12
tests/QtCore/setprop_on_ctor_test.py
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
import unittest
|
||||||
|
from PySide.QtCore import *
|
||||||
|
|
||||||
|
|
||||||
|
class SetPropOnCtorTest(unittest.TestCase):
|
||||||
|
def testIt(self):
|
||||||
|
obj = QEventTransition(targetStates = [QState()])
|
||||||
|
self.assertEqual(len(obj.targetStates()), 1);
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue