我想使用 PyQt5 渲染 SVG 文件。
最简单的方法是使用应用于 QPainter 对象的 QSvgGenerator。
但是,由于某种原因,我必须在输出 SVG 文件中渲染文本。为此,必须运行 QApplication,因为需要在 QApplication 执行期间初始化一些组件。否则,QPainter.drawText()
方法以 SEGFAULT 结束。
我现在可以通过创建 QSvgWidget 对象在 SVG 文件中生成文本,并通过 paintEvent
方法处理绘画。
如果我只是使用 exec_
方法运行应用程序,则一切正常。不过,我只对生成 SVG 感兴趣,所以我不想被迫用鼠标关闭主窗口(我想在 headless 服务器上运行我的程序)。这是我的基本代码:
app = QApplication(sys.argv)
drawer = MyDrawerClass()
drawer.show()
app.exec_()
和MyDrawerClass
继承自QSvgWidget
并实现了printEvent
方法,该方法在执行应用程序时成功调用。
所以我的问题是:有没有办法以 headless 方式运行应用程序并在渲染所有内容后退出它?我在 QTimer
上阅读了一些内容,但找不到任何适合我的用法的示例。
最佳答案
我假设您指的是 previous question 中使用的方法.
一些绘图功能要求在使用它们之前先构造一个 QGuiApplication,并且绘制文本也在其中,因为它取决于系统自己的 GUI 管理(默认字体、DPI 等)。通常人们会使用标准的 QApplication,但是,正如 documentation 中所报告的那样。 :
For "non-QWidget based Qt applications, use QGuiApplication instead, as it does not depend on the QtWidgets library".
这将使 QGuiApplication 的创建更快、更轻。
不幸的是,对于 Q[Gui]Applications 来说,运行显示是强制的,因此您将无法在 headless 服务器上运行它,除非至少有一个最小的虚拟 X 服务器处于事件状态。如果您能做到这一点,下面的示例应该可以正常工作。
def createImage(width=400, height=400):
rect = QRect(0, 0, width, height)
generator = QSvgGenerator()
generator.setFileName("test.svg")
generator.setSize(rect.size())
generator.setViewBox(rect)
painter = QPainter(generator)
painter.fillRect(rect, Qt.black)
textRect = QRect(0, 0, 200, 200)
textRect.moveCenter(rect.center())
painter.setPen(Qt.white)
painter.setBrush(Qt.darkGray)
painter.drawRect(textRect)
painter.drawText(textRect, Qt.AlignCenter, 'test')
painter.end()
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
createImage()
由于不需要事件循环(因为没有 GUI 交互),因此您实际上不必执行 exec_()
,一旦绘制函数运行,程序就会自动退出返回。
关于python - 运行应用程序并在 PyQt5 上渲染后退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57465934/