使用 Docker 使用 QOffscreenSurface 进行屏幕外渲染
Posted
技术标签:
【中文标题】使用 Docker 使用 QOffscreenSurface 进行屏幕外渲染【英文标题】:Offscreen render with QOffscreenSurface using Docker 【发布时间】:2020-03-03 21:13:27 【问题描述】:我使用 Qt5 进行离屏渲染,在 Docker 中运行时出现分段错误。
我在c++
中有代码,并通过python
使用pybind11
调用函数
这是导致段错误的代码
QSurfaceFormat glFormat;
glFormat.setVersion(3, 3);
glFormat.setProfile(QSurfaceFormat::CoreProfile);
glFormat.setRenderableType(QSurfaceFormat::OpenGL);
surface = new QOffscreenSurface();
surface->setFormat(glFormat);
surface->create(); // <-- Here
确切的错误是:
QObject::connect: Cannot connect (null)::destroyed(QObject*) to QOffscreenSurface::screenDestroyed(QObject*)
我尝试通过xvfb-run -a python prg.py
运行它并得到同样的错误
任何调试这个的指针?
关于这个问题的更多上下文,如果我在包裹在QApplication
中的主线程中使用上面的代码,它可以正常工作。仅当我将其移动到函数中时才会出现此问题,以便我可以在 python 中调用它。
【问题讨论】:
提供minimal reproducible example 【参考方案1】:关于在主线程之外运行的最后一条线索可能是您遇到的问题。
查看文档https://doc.qt.io/qt-5/qoffscreensurface.html#details:
注意:由于 QOffscreenSurface 由 QWindow 支持 某些平台,跨平台应用程序必须确保 create() 仅在主(GUI)线程上调用。 QOffscreenSurface 然后是 在其他线程上与 makeCurrent() 一起使用是安全的,但是 初始化和销毁必须始终在主(GUI)上进行 线程。
因此解决方案可能是在主线程中创建表面,然后通过 pybind11 像您需要的那样使用它。
【讨论】:
我没有 GUI 线程。关于如何使用 pybind11 调用创建它的任何指示? GUI 线程只是应用程序的主线程。你应该在那里创建你的表面,然后如果你想从另一个线程中使用它,调用bool QOpenGLContext::makeCurrent(QSurface *surface)
。
但是在使用 pybind 时,我只是链接到一个函数调用,例如在 python 中 import myPackage as p p.myFunction()
我在调用表面之前在我的 pybind 函数中调用了 QApplication 并使用 xvfb 运行它以使 ti 工作。以上是关于使用 Docker 使用 QOffscreenSurface 进行屏幕外渲染的主要内容,如果未能解决你的问题,请参考以下文章
使用 docker 如何使用 docker run 将文件从 docker 复制到主机 [重复]