python - 运行应用程序并在 PyQt5 上渲染后退出

标签 python pyqt pyqt5 qapplication

我想使用 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/

相关文章:

Python同时进行多个循环

python - 如何使用列表替换文本文件中的列?

winforms - 父窗口未收到窗口消息(关键事件)

python - PyQT5:如何使用单选按钮的状态灰显并停用行编辑

python - 编辑子类中的选项卡名称

python - 使用自定义编码器将带有 Decimal 键的 python 字典转换为 JSON

python - 在 python 中有没有办法删除列的一部分?

python - Pyside Qt centralwidget 设置样式表不工作

python - PYQT:水平和垂直标题

python - PyQt5,我不需要连续打印,但它只改变 QLabel