【问题标题】:How to display an SVG image in Python如何在 Python 中显示 SVG 图像
【发布时间】:2020-08-09 21:11:04
【问题描述】:

我在关注this tutorial,了解如何用 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 制作了一个 passing reference,以及如何使用它们来显示 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 图像。而且对我没用。

更奇怪的是,看到this 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不兼容?

【问题讨论】:

    标签: python svg pyqt pyqt5 python-chess


    【解决方案1】:

    我认为您对 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) 
    

    【讨论】:

    • 感谢您的快速回复。好的。我了解创建主父小部件。但这似乎由于某种原因仍然不起作用。
    • 好的,我现在编辑了我的答案。使用现在也指定的编码重试。
    • 是的,这解决了我的问题。我现在可以看到棋盘了。我现在只有一点困惑。如何显示 SVG 图像“Zeichen_123.svg”而不显示棋盘?
    • 回复晚了,但问题是QSvgWidget 构造函数需要一个文件名,所以当你给它Zeichen_123.svg 的路径时,它会显示那个。 chess.svg.board 的返回值是实际的 SVG 代码(即文件内容是什么),所以 QSvgWidget 不知道如何处理它。另一方面,load 方法期望接收 SVG 数据,而不是文件名,因此可以正常工作。 (这实际上与使用或不使用“主窗口”的问题有些正交;您不需要 MainWindow 类来显示国际象棋 SVG。)
    猜你喜欢
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    相关资源
    最近更新 更多