为什么运行pybind11c++库的pyqt5qthread仍然挂起我的主GUI?

2024-05-16 11:42:27 发布

您现在位置:Python中文网/ 问答频道 /正文

在我的PyQt5程序中,我想启动一个运行一些代码的新线程:

class SlamThread(QThread):
    """docstring for SlamThread"""
    def __init__(self, parent):
        QThread.__init__(self, parent)

    def setSlam(self, params):
        self.params = params

    def run(self):
        self.slam = Slam()
        self.slam.setParams(self.params)
        self.slam.start()
<^ >其中^ {< CD2>}是用C++编写的,用PybDun11转换。你知道吗

在我的主程序中,代码由qAction按钮触发:

def startSlam(self, ...):
        params = ...
        self.thread = SlamThread(self)
        self.thread.setSlam(params)
        self.thread.start()

        for i in range(10):
            print('done')

奇怪的是,它确实启动了一个新线程,done在我的Slam程序之前被打印出来。但是,当Slam启动时,整个程序将挂起,直到Slam完成。你知道吗

在我的C++ ^ {CD2>}代码中,就好像这个

int Slam::start()
{
    init();
    ...
    startSlam();
    return 0;
}

运行startSlam需要几分钟。你知道吗


Tags: 代码self程序forinitdefparams线程
1条回答
网友
1楼 · 发布于 2024-05-16 11:42:27

根据docs,当对象在线程中执行时,必须调用gil\u scoped\u release和gil\u scoped\u acquire:

int Slam::start(){
    pybind11::gil_scoped_release release;
    init();
    // ...
    pybind11::gil_scoped_acquire acquire;
    return 0;
}

或在装订中:

pybind11::class_<Slam>(mymodule, "Slam")
      .def(pybind11::init<>())
      .def("setParams", &Slam::setParams)
      .def("start", &Slam::start, pybind11::call_guard<pybind11::gil_scoped_release>());

您可以找到完整的测试here

相关问题 更多 >