运行 一个应用程序并在 PyQt5 上渲染后退出

Run an application and quit it after rendering on PyQt5

我想用 PyQt5 渲染 SVG 文件。

最简单的方法是使用应用于 QPainter 对象的 QSvgGenerator。

但是,出于某种原因,我必须在输出的 SVG 文件中呈现文本。为此,QApplication 运行ning 是强制性的,因为需要在 QApplication 执行期间初始化一些组件。否则,QPainter.drawText() 方法以 SEGFAULT 结束。

我现在可以通过创建 QSvgWidget 对象在我的 SVG 文件中生成文本,该对象通过 paintEvent 方法处理绘画。

如果我只是 运行 使用 exec_ 方法的应用程序,一切正常。但是我只对生成 SVG 感兴趣,所以我不想被迫用我的鼠标关闭主 window(我想 运行 我的程序在无头服务器上) .这是我的基本代码:

app = QApplication(sys.argv)
drawer = MyDrawerClass()
drawer.show()
app.exec_()

MyDrawerClass继承自QSvgWidget并实现了printEvent方法,在执行app时调用成功

所以我的问题是:有没有办法 运行 应用程序以无头的方式并在呈现所有内容后退出它?我在 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 的创建更快更轻。

不幸的是,运行ning 显示对于 Q[Gui] 应用程序是 强制性的 ,因此您将无法 运行无头服务器,除非至少有一个最小的虚拟 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_(),只要返回 paint 函数,程序就会自动退出。