Commit 75388f33 authored by Clinton Stimpson's avatar Clinton Stimpson
Browse files

ENH:  Add ability to call any Qt slot in the application with "QVariant foo()"
      signature from python.  Will be used to validate menu/toolbar stuff.
parent 383a7577
......@@ -285,6 +285,60 @@ QtTesting_getChildren(PyObject* /*self*/, PyObject* args)
ret.toAscii().data());
}
static PyObject*
QtTesting_invokeMethod(PyObject* /*self*/, PyObject* args)
{
// string QtTesting.invokeMethod('object', 'method')
// calls a method and returns its value
const char* object = 0;
const char* method = 0;
if(!PyArg_ParseTuple(args, const_cast<char*>("ss"), &object, &method))
{
return NULL;
}
PropertyObject = object;
PropertyValue = method;
PropertyResult = QString();
if(Instance && QThread::currentThread() != QApplication::instance()->thread())
{
QMutex mut;
mut.lock();
QMetaObject::invokeMethod(Instance, "threadInvokeMethod", Qt::QueuedConnection);
if(!Instance->waitForGUI(mut))
{
PyErr_SetString(PyExc_ValueError, "error invoking method");
return NULL;
}
}
else if(QThread::currentThread() == QApplication::instance()->thread())
{
PropertyResult = pqPythonEventSource::invokeMethod(PropertyObject,
PropertyValue);
}
else
{
PyErr_SetString(PyExc_AssertionError, "pqPythonEventSource not defined");
return NULL;
}
if(PropertyObject == QString::null)
{
PyErr_SetString(PyExc_ValueError, "object not found");
return NULL;
}
else if(PropertyValue == QString::null)
{
PyErr_SetString(PyExc_ValueError, "method not found");
return NULL;
}
return Py_BuildValue(const_cast<char*>("s"),
PropertyResult.toAscii().data());
}
static PyMethodDef QtTestingMethods[] = {
{
......@@ -325,6 +379,12 @@ static PyMethodDef QtTestingMethods[] = {
METH_VARARGS,
const_cast<char*>("Return a list of child objects.")
},
{
const_cast<char*>("invokeMethod"),
QtTesting_invokeMethod,
METH_VARARGS,
const_cast<char*>("Invoke a Qt slot with the signature \"QVariant foo()\".")
},
{NULL, NULL, 0, NULL} // Sentinal
};
......@@ -482,3 +542,31 @@ void pqPythonEventSource::run()
this->done(result);
}
void pqPythonEventSource::threadInvokeMethod()
{
PropertyResult = this->invokeMethod(PropertyObject, PropertyValue);
this->guiAcknowledge();
}
QString pqPythonEventSource::invokeMethod(QString& object, QString& method)
{
// ensure other tasks have been completed
pqEventDispatcher::processEventsAndWait(1);
QVariant ret;
QObject* qobject = pqObjectNaming::GetObject(object);
if(!qobject)
{
object = QString::null;
}
else
{
if(!QMetaObject::invokeMethod(qobject, method.toAscii().data(),
Q_RETURN_ARG(QVariant, ret)))
{
method = QString::null;
}
}
return ret.toString();
}
......@@ -34,8 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define _pqPythonEventSource_h
#include "pqThreadedEventSource.h"
class QString;
#include <QString>
/** Concrete implementation of pqEventSource that retrieves events recorded
by pqPythonEventObserver */
......@@ -52,6 +51,7 @@ public:
static QString getProperty(QString& object, const QString& prop);
static void setProperty(QString& object, QString& prop, const QString& value);
static QStringList getChildren(QString& object);
static QString invokeMethod(QString& object, QString& method);
protected:
virtual void run();
......@@ -60,6 +60,7 @@ protected slots:
void threadGetProperty();
void threadSetProperty();
void threadGetChildren();
void threadInvokeMethod();
private:
class pqInternal;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment