首页 > 解决方案 > 如何在 Python 中显示 SVG 图像

问题描述

我正在关注如何用 Python 编写国际象棋程序的本教程。

它使用python-chess引擎。该引擎的函数显然返回 SVG 数据,可用于显示棋盘。

import chess
import chess.svg

from IPython.display import SVG

board = chess.Board()
SVG(chess.svg.board(board=board,size=400))  

但是当我运行该代码时,我看到的只是终端中的一行,没有图像。

<IPython.core.display.SVG object>

本教程简要介绍了Jupyter Notebooks 以及如何使用它们来显示 SVG 图像。我没有使用 Jupyter Notebooks 的经验,即使我从 pip 安装了该软件包,并且对如何使用它进行了一些尝试,但对于我最初的棋盘问题,我并没有取得太大进展。但我所拥有的是使用 C++ 进行 Qt 开发的经验,并且由于 Qt 具有 Python 绑定,我决定使用这些绑定。

这是我写的:

import sys
import chess
import chess.svg
from PyQt5 import QtGui, QtSvg
from PyQt5.QtWidgets import QApplication
from IPython.display import SVG, display

app = QApplication(sys.argv);

board = chess.Board(); 
svgWidget = QtSvg.QSvgWidget(chess.svg.board(board=board, size=400));
#svgWidget.setGeometry(50,50,759,668)
svgWidget.show()

sys.exit(app.exec_())

一个 Qt 窗口打开并且什么都不显示,在终端中我看到很多文本 - (显然 SVG 数据最终出现在控制台中,而不是在打开的 Qt 窗口中?)。

我想我必须在 python 下安装一些 SVG 库,所以我从 pip安装了drawSvg 。但似乎该库会生成 SVG 图像。而且对我没用。

更奇怪的是,在看到这个 SO question之后,我尝试了以下方法:

import sys
import chess
import chess.svg
from PyQt5 import QtGui, QtSvg
from PyQt5.QtWidgets import QApplication
from IPython.display import SVG, display

app = QApplication(sys.argv);

board = chess.Board(); 
svgWidget = QtSvg.QSvgWidget('d:\projects\python_chess\Zeichen_123.svg');
#svgWidget.setGeometry(50,50,759,668)
svgWidget.show()

sys.exit(app.exec_())

它显示了一个图像 - 一个 SVG 图像!那我的案子和这个案子有什么区别呢?

问题:所以我的问题是,在棋盘 SVG 数据的情况下我做错了什么?python-chess库生成的SVG数据是不是和QtSvg不兼容?

标签: pythonsvgpyqtpyqt5python-chess

解决方案


我认为您对 Python 的脚本性质感到困惑。你说,你有在 C++ 下开发 Qt 的经验。您不会先在那里创建一个主窗口小部件,然后将您的 SVG 小部件添加到其中,您将在其中调用或加载 SVG 数据吗?

我会像这样重写你的代码。

import chess
import chess.svg

from PyQt5.QtSvg import QSvgWidget
from PyQt5.QtWidgets import QApplication, QWidget


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.setGeometry(100, 100, 1100, 1100)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 1080, 1080)

        self.chessboard = chess.Board()

        self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)

if __name__ == "__main__":
    app = QApplication([])
    window = MainWindow()
    window.show()
    app.exec()

编辑

如果您将绘画功能添加到 MainWindow 类会更好。因为可以肯定的是,在将来,每当您移动棋子时,您都会想多次重绘棋盘图像。所以我会做这样的事情。

     def paintEvent(self, event):
         self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
         self.widgetSvg.load(self.chessboardSvg) 

推荐阅读