如何在QT应用程序中的嵌入式Python中睡觉

问题描述

| 我将Python嵌入到GUI QT应用程序中。我向UI文件中的一个按钮分配了一个信号,然后单击该脚本后运行该脚本。 当使用来自 http://docs.python.org/py3k/extending/embedding.html 我还向嵌入式模块添加了一些功能,如该页第5.4节所示。我希望能够在python脚本中添加一些延迟。由于睡眠会暂停整个应用程序,我该如何不使用睡眠来做到这一点?我猜你会用QTimer来做,它会在一段时间后唤醒python脚本,但是我不知道怎么做。 我相信我已经很接近解决方案了,因此,我尽可能不添加线程,甚至不想添加其他框架,例如PythonQT或Boost。 以下是相关代码段:
    static PyObject* openDoor(PyObject *self,PyObject *args)
    {
        int value1 = 0;
        if (!PyArg_ParseTuple(args,\"l\",&value1))
            return Py_BuildValue(\"i\",-1);

    opendoor(value1)
    return PyLong_FromLong(value1);
}

static PyObject* mysleep(PyObject *self,PyObject *args)
{
    int value1 = 0;
    if (!PyArg_ParseTuple(args,&value1))
        return Py_BuildValue(\"i\",-1);
// this does not work !!!
//  QTimer slideShowtimer = new QTimer(this);
//  connect(slideShowtimer,SIGNAL(timeout()),this,SLOT(slideShowHelper()));
//  slideShowtimer->start(5000);


    return PyLong_FromLong(value1);
}


static PyMethodDef EmbMethods[] = {
        {\"openDoor\",openDoor,METH_VaraRGS,\".\"},{\"closeDoor\",closeDoor,{\"sleep\",mysleep,\"Sleep.\"},{NULL,NULL,NULL}
};

static PyModuleDef EmbModule = {
    PyModuleDef_HEAD_INIT,\"obu\",-1,EmbMethods,NULL
};

static PyObject*
PyInit_emb(void)
{
    return PyModule_Create(&EmbModule);
}

// taken from python docs
void MainWindow::on_ScriptButton_clicked()
{
    PyObject *pName,*pModule,*pFunc;
    PyObject *pArgs,*pValue;
    int i;

    PyImport_AppendInittab(\"emb\",&PyInit_emb);
    Py_Initialize();

    pName = PyUnicode_FromString(\"multiply\");
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if (pModule != NULL) {
        pFunc = PyObject_GetAttrString(pModule,\"run\");

        if (pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_New(1);
            for (i = 0; i < 1; ++i) {
                pValue = PyLong_FromVoidPtr(this);
                if (!pValue) {
                    Py_DECREF(pArgs);
                    Py_DECREF(pModule);
                    fprintf(stderr,\"Cannot convert argument\\n\");
                }
                PyTuple_SetItem(pArgs,i,pValue);
            }
            pValue = PyObject_CallObject(pFunc,pArgs);
            Py_DECREF(pArgs);
            if (pValue != NULL) {
                printf(\"Result of call: %ld\\n\",PyLong_AsLong(pValue));
                Py_DECREF(pValue);
            }
            else {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,\"Call Failed\\n\");
            }
        }
        else {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr,\"Cannot find function \\n\");
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
        ;
    }
    else {
        PyErr_Print();
        fprintf(stderr,\"002 Failed to load \\n\");
    }
    Py_Finalize();
}
    

解决方法

        这个答案是一般性的,可能不适用于QT框架。 (我自己不使用QT) 睡眠不起作用的原因是它基本上看起来像C ++中的以下代码
static PyObject* mysleep(PyObject *self,PyObject *args)
{
    int secs = 0;
    if (!PyArg_ParseTuple(args,\"l\",&secs))
        return Py_BuildValue(\"i\",-1);
   long start = gettimestamp(); // This function should return a unix timestamp
   long now = start;
   while (now < start + secs) {
     now = gettimestamp(); }
   return PyLong_FromLong(now-start); }
请注意,这对于您的函数来说是个好主意,它返回程序实际休眠的时间,而不是输入值。如您可能需要在代码中知道这段时间。 该函数将由python调用 但是,在GUI环境中,您还希望继续检查并运行此功能无法执行的任何事件。 因此,您需要一个新的功能,如下所示:
static PyObject* mysleep(PyObject *self,-1);
   long start = gettimestamp(); // This function should return a unix timestamp
   long now = start;
   while (now < start + secs) {
     handleEvents(); // This function makes the framework check,and run events in they have occurred it will be framework spefic
     now = gettimestamp(); }
   return PyLong_FromLong(now-start); }
您应该检查QT文档,是否存在使用QT实现handleEvents()函数的方法,此解决方案应该可以解决您的问题。 注意:这会导致计算机等待至少n秒,如果正在处理事件,则必须先完成计算机,然后循环才能再次检查时间。 同样,handleEvents()应该只允许运行一个事件,而下一个事件调用列表必须运行,否则它将在处理完所有事件后才返回。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...