gpt4 book ai didi

c++ - 如何在 QT 应用程序中的嵌入式 Python 中休眠

转载 作者:太空宇宙 更新时间:2023-11-04 14:22:54 25 4
gpt4 key购买 nike

我正在将 Python 嵌入到 GUI QT 应用程序中。我为我的 UI 文件中的一个按钮分配了一个信号,当它被点击时我运行脚本。

这在使用来自

的方法时有效

http://docs.python.org/py3k/extending/embedding.html

我还在该页面的第 5.4 节中演示了向嵌入式模块添加了一些功能。我希望能够在 python 脚本中添加一些延迟。我如何在不使用 sleep 的情况下执行此操作,因为 sleep 会停止整个应用程序?我猜你会用 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, "l", &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, METH_VARARGS, "."},
{"sleep", mysleep, METH_VARARGS, "Sleep."},
{NULL, NULL, 0, NULL}
};

static PyModuleDef EmbModule = {
PyModuleDef_HEAD_INIT, "obu", NULL, -1, EmbMethods,
NULL, NULL, NULL, 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)

sleep 不起作用的原因是它基本上看起来像下面的 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, 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) {
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 实现 handleEvents() 函数的方法,您应该查看 QT 文档,此解决方案应该可以解决您的问题。

注意:这会导致计算机等待至少 n 秒,在处理事件时必须先完成,然后循环才能再次检查时间。

而且 handleEvents() 应该只允许一个事件运行下一个要运行的事件调用列表,否则它不会返回,直到所有事件都已处理。

关于c++ - 如何在 QT 应用程序中的嵌入式 Python 中休眠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6157594/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com