qt调用python库_通过python控制台为PythonQt库进行非锁定调用

本文介绍如何在Qt应用中避免GUI冻结,通过创建一个后台线程调用Python模块并使用PythonQt库。关键在于使用QThread派生类和PyEval_InitThreads()初始化线程支持,以在不阻塞UI的情况下执行Python代码。
摘要由CSDN通过智能技术生成

是的,GUI是冻结的,因为长时间调用Python是通过UI线程执行的。为了解决这个问题,我可以继承QThread并通过命令模式将命令发布到Python模块中。

在开始使用以下类对多个Python模块进行调用之前,请确保通过调用PyEval_InitThreads()来初始化线程支持,如您在main()函数中所看到的。

祝你好运!

int main(int argc, char **argv) {

QApplication qapp(argc, argv);

PyEval_InitThreads(); // IMPORTANT

PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut);

PythonQtObjectPtr module = PythonQt::self()->createUniqueModule();

ThreadedPythonContext context(module);

context.start();

# issue some commands into the module

context.issue("import sys");

context.issue("sys.path.append('C:\\Python27\\Lib\\site-packages')");

context.issue("import time");

context.issue("last = time.localtime().tm_sec");

// Release the global interpreter lock (if it has been created and thread support

// is enabled) and reset the thread state to NULL, returning the previous thread

// state (which is not NULL). If the lock has been created, the current thread must

// have acquired it. (This function is available even when thread support is

// disabled at compile time.)

// give up control of the GIL

PyThreadState *state = PyEval_SaveThread();

return qapp.exec()

}

ThreadedPythonContext.h

#ifndef THREADEDPYTHONCONTEXT_H

#define THREADEDPYTHONCONTEXT_H

#include "PythonQt.h"

#include

#include

#include

#include

class ThreadedPythonContext : public QThread

{

Q_OBJECT

public:

ThreadedPythonContext(const PythonQtObjectPtr &context) :

QThread(),

_context(context),

_running(true)

{

}

~ThreadedPythonContext() {

_running = false;

wait();

}

void issue(const QString &code) {

_lock.lock();

_commands.enqueue(code);

_lock.unlock();

_CommandQueued.wakeOne();

}

bool isCommandQueueEmpty() {

QMutexLocker lock(&_lock);

return _commands.isEmpty();

}

protected:

QString dequeue() {

QMutexLocker lock(&_lock);

QString cmd(_commands.dequeue());

return cmd.isEmpty() ? "\n" : cmd;

}

void run() {

QMutex signal;

PyGILState_STATE state;

while(_running) {

// wait to be signaled ...

signal.lock();

_CommandQueued.wait(&signal,1);

signal.unlock();

if (isCommandQueueEmpty()) {

continue;

}

while (!isCommandQueueEmpty()) {

PythonQtObjectPtr p;

PyObject* dict = NULL;

state = PyGILState_Ensure();

if (PyModule_Check(_context)) {

dict = PyModule_GetDict(_context);

} else if (PyDict_Check(_context)) {

dict = _context;

}

if (dict) {

// this command blocks until the code has completed execution

emit python_busy(true);

p.setNewRef(PyRun_String(dequeue().toLatin1().data(), Py_single_input, dict, dict));

emit python_busy(false);

}

// error in the kernel

if (!p) {

PythonQt::self()->handleError();

}

PyGILState_Release(state);

}

}

}

PythonQtObjectPtr _context;

QMutex _lock;

QQueue _commands;

QWaitCondition _CommandQueued;

bool _running;

signals:

void python_busy(bool);

};

#endif //THREADEDPYTHONCONTEXT_H

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值