把matplotlib嵌入到qt中

# coding:utf-8
# 原理:matplotlib中的FigureCanvasQTAgg继承自qt的QWidget类型
# 因此使用 matplotlib中的 FigureCanvasQTAgg绘图,可以直接嵌入到qt中
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QDialog, QPushButton, QVBoxLayout, QLineEdit, QTextBrowser
import matplotlib.pyplot as plt
import sys
import networkx as nx
import random

"""将matplotlib的画布嵌入到qt中"""

class Main_window(QDialog):
    def __init__(self):
        super().__init__()
        # 创建matplotlib的界面
        self.figure = plt.figure(figsize=(5, 3), facecolor='#FFD7C4')
        # 创建存储结构
        self.G = nx.Graph()
        # 顶点及对应的颜色索引:(1: 0, 2: 1, 3: 2, 4: 1, 5: 2, 6: 0)
        self.node_list = [
            (1, {"color": 0}),
            (2, {"color": 1}),
            (3, {"color": 1}),
            (4, {"color": 2}),
            (5, {"color": 2}),
            (6, {"color": 0})]
        # 边集:(1, 2), (1, 4), (1, 3), (2, 5), (3, 6), (5, 6)
        self.edge_list = [(1, 2), (1, 4), (1, 3), (2, 3), (2, 5), (2, 6), (3, 4), (3, 6), (5, 6)]
        self.G.add_nodes_from(self.node_list)
        self.G.add_edges_from(self.edge_list)
        # 设置颜色索引
        self.color_dict = {0: 'red', 1: 'yellow', 2: 'green'}
        # 根据颜色索引拿到实际颜色
        self.color_list = [self.color_dict[node[1]['color']] for node in self.node_list]
        # 画图,此时未设置颜色,默认蓝色,即直接进入猜图模式
        nx.draw(self.G, with_labels=True)

        # 文本展示框
        self.text_info = QTextBrowser()
        self.text_info.setText('现在是猜图模式哦~')
        # 输入框,输入要查看的两个顶点号,中间用空格隔开
        self.edit_guess = QLineEdit()
        self.edit_guess.setPlaceholderText('亲,请输入想要验证的两个顶点号,中间用空格隔开')
        # 创建按钮
        self.button_check = QPushButton("验证")
        # 创建按钮
        self.button_origin = QPushButton("原图")
        # 核心:把matplotlib的Figure类转化为qt可以直接使用的FigureCanvas类(它继承自QWidget类),即matplotlib提供了兼容qt的类
        self.canvas = FigureCanvas(self.figure)
        # 设置垂直布局,并将之前创建的各个widget添加到布局中
        layout = QVBoxLayout()
        layout.addWidget(self.canvas)
        layout.addWidget(self.text_info)
        layout.addWidget(self.edit_guess)
        layout.addWidget(self.button_check)
        layout.addWidget(self.button_origin)
        # 最后把布局设置到窗口中
        self.setLayout(layout)
        # 连接信号槽,即按钮被点击时调用的函数
        self.button_check.clicked.connect(self.Check)
        self.button_origin.clicked.connect(self.Origin)

    # 查看原图
    def Origin(self):
        # 清除已经画的图
        plt.cla()
        self.text_info.setText('原图')
        self.color_list = [self.color_dict[node[1]['color']] for node in self.node_list]
        # 画一幅新的,带有颜色的图
        nx.draw(self.G, node_color=self.color_list, with_labels=True)
        plt.draw()

    # 一次验证
    def Check(self):
        # 颜色列表
        color_list = ['aliceblue',
                      'antiquewhite',
                      'aqua',
                      'aquamarine',
                      'azure',
                      'beige',
                      'bisque',
                      'black',
                      'blanchedalmond',
                      'blue',
                      'blueviolet',
                      'brown',
                      'burlywood',
                      'cadetblue',
                      'chartreuse',
                      'chocolate',
                      'coral',
                      'cornflowerblue',
                      'cornsilk',
                      'crimson',
                      'cyan',
                      'darkblue',
                      'darkcyan',
                      'darkgoldenrod',
                      'darkgray',
                      'darkgreen',
                      'darkkhaki',
                      'darkmagenta',
                      'darkolivegreen',
                      'darkorange',
                      'darkorchid',
                      'darkred',
                      'darksalmon',
                      'darkseagreen',
                      'darkslateblue',
                      'darkslategray',
                      'darkturquoise',
                      'darkviolet',
                      'deeppink',
                      'deepskyblue',
                      'dimgray',
                      'dodgerblue',
                      'firebrick',
                      'floralwhite',
                      'forestgreen',
                      'fuchsia',
                      'gainsboro',
                      'ghostwhite',
                      'gold',
                      'goldenrod',
                      'gray',
                      'green',
                      'greenyellow',
                      'honeydew',
                      'hotpink',
                      'indianred',
                      'indigo',
                      'ivory',
                      'khaki',
                      'lavender',
                      'lavenderblush',
                      'lawngreen',
                      'lemonchiffon',
                      'lightblue',
                      'lightcoral',
                      'lightcyan',
                      'lightgoldenrodyellow',
                      'lightgreen',
                      'lightgray',
                      'lightpink',
                      'lightsalmon',
                      'lightseagreen',
                      'lightskyblue',
                      'lightslategray',
                      'lightsteelblue',
                      'lightyellow',
                      'lime',
                      'limegreen',
                      'linen',
                      'magenta',
                      'maroon',
                      'mediumaquamarine',
                      'mediumblue',
                      'mediumorchid',
                      'mediumpurple',
                      'mediumseagreen',
                      'mediumslateblue',
                      'mediumspringgreen',
                      'mediumturquoise',
                      'mediumvioletred',
                      'midnightblue',
                      'mintcream',
                      'mistyrose',
                      'moccasin',
                      'navajowhite',
                      'navy',
                      'oldlace',
                      'olive',
                      'olivedrab',
                      'orange',
                      'orangered',
                      'orchid',
                      'palegoldenrod',
                      'palegreen',
                      'paleturquoise',
                      'palevioletred',
                      'papayawhip',
                      'peachpuff',
                      'peru',
                      'pink',
                      'plum',
                      'powderblue',
                      'purple',
                      'red',
                      'rosybrown',
                      'royalblue',
                      'saddlebrown',
                      'salmon',
                      'sandybrown',
                      'seagreen',
                      'seashell',
                      'sienna',
                      'silver',
                      'skyblue',
                      'slateblue',
                      'slategray',
                      'snow',
                      'springgreen',
                      'steelblue',
                      'tan',
                      'teal',
                      'thistle',
                      'tomato',
                      'turquoise',
                      'violet',
                      'wheat',
                      'white',
                      'whitesmoke',
                      'yellow',
                      'yellowgreen']
        # 产生一个长度为3的随机序列,即从0-140(不含)这140个数中随机抽取三个
        changelist = random.sample(range(0, 140), 3)
        # 根据随机序列设置颜色,即随机抽取三个颜色
        self.color_dict = {0: color_list[changelist[0]], 1: color_list[changelist[1]], 2: color_list[changelist[2]]}

        plt.cla()
        # 获取输入框内容
        input_text = self.edit_guess.text()
        guess_set = set()
        try:
            node1, node2 = input_text.split(' ')
            guess_set.add(int(node1))
            guess_set.add(int(node2))
        except Exception as e:
            # 防止输入格式错误导致的程序崩溃
            print(e)
            return
        self.color_list.clear()
        for node in self.node_list:
            # 如果节点是被选中的两个节点之一,则显示它的本来颜色
            if node[0] in guess_set:
                self.color_list.append(self.color_dict[node[1]['color']])
            else:
                # 否则默认蓝色
                self.color_list.append('blue')
        # 显示部分解密的图
        nx.draw(self.G, node_color=self.color_list, with_labels=True)
        plt.draw()

# 运行程序
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    main_window = Main_window()
    main_window.setWindowTitle('零知识证明')
    main_window.show()
    # 进入qt的事件循环
    app.exec()