Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从Matplotlib绘图中提取信息并在PyQt5 GUI中显示_Python_Qt_Matplotlib_User Interface_Pyqt5 - Fatal编程技术网

Python 从Matplotlib绘图中提取信息并在PyQt5 GUI中显示

Python 从Matplotlib绘图中提取信息并在PyQt5 GUI中显示,python,qt,matplotlib,user-interface,pyqt5,Python,Qt,Matplotlib,User Interface,Pyqt5,我想知道PyQt5 GUI和嵌入式matplotlib绘图如何在它们的属性之间交互/传递信息。具体地说,我了解内置Qt小部件的信号和插槽是如何工作的,但我不知道它如何扩展到自定义小部件或非本机对象,如matplotlib绘图 例子: 考虑下面的示例-我创建了一个Qt GUI,它在左侧显示matplotlib(mpl)绘图,在右侧有4个QLineEdit对象。可以在mpl绘图内单击并拖动以绘制矩形我想知道如何将Qline编辑框连接到矩形的角坐标。单击并拖动矩形时,我希望顶部的两行编辑显示左下角矩

我想知道PyQt5 GUI和嵌入式matplotlib绘图如何在它们的属性之间交互/传递信息。具体地说,我了解内置Qt小部件的信号和插槽是如何工作的,但我不知道它如何扩展到自定义小部件或非本机对象,如matplotlib绘图


例子: 考虑下面的示例-我创建了一个Qt GUI,它在左侧显示matplotlib(mpl)绘图,在右侧有4个QLineEdit对象。可以在mpl绘图内单击并拖动以绘制矩形我想知道如何将Qline编辑框连接到矩形的角坐标。单击并拖动矩形时,我希望顶部的两行编辑显示左下角矩形的X和Y数据,底部的两行编辑实时显示右上角矩形的X和Y数据。相反,我还希望QLineEdit框中的坐标编辑反映在mpl图中。以下是一张供参考的图片:

相关代码可在下面找到。非常感谢您的建议

代码
从PyQt5导入QtCore、QtGui、qtwidget
从matplotlib.figure导入图形
从matplotlib.backends.backend_qt5agg导入(FigureCanvasqtag,NavigationToolbar2QT作为NavigationToolbar)
将numpy作为np导入
类topLevelWindow(QtWidgets.QMainWindow):
定义初始化(自):
super()。\uuuu init\uuuuu()
#创建中心小部件并设置布局
self.centralwidget=qtwidts.QWidget(self)
self.setCentralWidget(self.centralwidget)
self.gridLayout=qtwidts.QGridLayout(self.centralwidget)
#创建显示框,指定给父布局,并创建其自己的布局
self.displayFrame=qtwidts.QFrame(self.centralwidget)
self.gridLayout.addWidget(self.displayFrame,1,0,1,1)
self.verticalLayout_1=qtwidts.QVBoxLayout(self.displayFrame)
#将MPPLOT对象添加到显示框并指定给父布局
self.plotWidget=MplPlot()
self.verticalLayout_1.addWidget(self.plotWidget)
#创建数字、指定给父布局并创建其自己的布局
self.numFrame=qtwidts.QFrame(self.centralwidget)
self.gridLayout.addWidget(self.numFrame,1,1,1)
self.verticalLayout_2=qtwidts.QVBoxLayout(self.numFrame)
#将QLineEdits添加到数字框并指定给父布局
self.bottomLeftCornerX=qtwidts.QLineEdit(self.numFrame)
self.bottomLeftCornerY=qtwidts.QLineEdit(self.numFrame)
self.topRightCornerEx=qtwidts.QLineEdit(self.numFrame)
self.toplightcornery=qtwidts.QLineEdit(self.numFrame)
self.verticalLayout_2.addWidget(self.bottomLeftCornerX)
self.verticalLayout_2.addWidget(self.bottomLeftCornerY)
self.verticalLayout_2.addWidget(self.topRightCornerX)
self.verticalLayout_2.addWidget(self.topRightCornery)
QtCore.QMetaObject.connectSlotsByName(self)
self.show()
类MplPlot(图CANVASQTAGG):
def onclick(自我,事件):
self.bottomLeftX=event.xdata
self.bottomLeftY=event.ydata
self.topRightX=event.xdata
self.topRightY=event.ydata
self.x=np.array(
[
self.leftx,
self.leftx,
self.topRightX,
self.topRightX,
self.bottomLeftX
]
)
self.y=np.array(
[
左撇子,
自命不凡,
自命不凡,
左撇子,
左撇子
]
)
#更新数据
self.ax.lines[0]。设置扩展数据(self.x)
self.ax.line[0]。设置数据(self.y)
self.draw()
self.moving=True
def onrelease(自我、事件):
self.topRightX=event.xdata
self.topRightY=event.ydata
self.x=np.array(
[
self.leftx,
self.leftx,
self.topRightX,
self.topRightX,
self.bottomLeftX
]
)
self.y=np.array(
[
左撇子,
自命不凡,
自命不凡,
左撇子,
左撇子
]
)
#更新数据
self.ax.lines[0]。设置扩展数据(self.x)
self.ax.line[0]。设置数据(self.y)
self.draw()
self.moving=False
def onmotion(自身、事件):
如果不是自动移动:
返回
self.topRightX=event.xdata
self.topRightY=event.ydata
self.x=np.array(
[
self.leftx,
self.leftx,
self.topRightX,
self.topRightX,
self.bottomLeftX
]
)
self.y=np.array(
[
左撇子,
自命不凡,
自命不凡,
左撇子,
左撇子
]
)
self.ax.lines[0]。设置扩展数据(self.x)
self.ax.line[0]。设置数据(self.y)
self.draw()
def uuu init uuu(self,parent=None):
图=图()
超级(mpplot,self)。\uuuuu init\uuuuuu(图)
self.setParent(父级)
self.regionUpdate=QtCore.pyqtSignal()
#创建具有轴的图形
self.ax=self.figure.add_子批次(111)
自定轴集_xlim(-100100))
自身最大设定值(-100100))
self.ax.plot([0],[0])
#初始化垃圾值
self.bottomLeftX=0
self.bottomLeftY=0
self.topRightX=0
self.topRightY=0
self.x=0
self.y=0
#设置移动标志fals
from PyQt5 import QtCore, QtGui, QtWidgets

from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import (
    FigureCanvasQTAgg,
    NavigationToolbar2QT as NavigationToolbar,
)

import numpy as np


class topLevelWindow(QtWidgets.QMainWindow):
    def __init__(self):

        super().__init__()
        # Create central widget and set layout
        self.centralwidget = QtWidgets.QWidget(self)
        self.setCentralWidget(self.centralwidget)
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)

        # Create display frame, assign to parent layout, and create its own layout
        self.displayFrame = QtWidgets.QFrame(self.centralwidget)
        self.gridLayout.addWidget(self.displayFrame, 1, 0, 1, 1)
        self.verticalLayout_1 = QtWidgets.QVBoxLayout(self.displayFrame)

        # Add MplPlot object to display frame and assign to parent layout
        self.plotWidget = MplPlot()
        self.verticalLayout_1.addWidget(self.plotWidget)

        # Create numbers gram, assign to parent layout, and create its own layout
        self.numFrame = QtWidgets.QFrame(self.centralwidget)
        self.gridLayout.addWidget(self.numFrame, 1, 1, 1, 1)
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.numFrame)

        # Add QLineEdits to  numbers frame and assign to parent layout
        self.bottomLeftCornerX = QtWidgets.QLineEdit(self.numFrame)
        self.bottomLeftCornerY = QtWidgets.QLineEdit(self.numFrame)
        self.topRightCornerX = QtWidgets.QLineEdit(self.numFrame)
        self.topRightCornery = QtWidgets.QLineEdit(self.numFrame)
        self.verticalLayout_2.addWidget(self.bottomLeftCornerX)
        self.verticalLayout_2.addWidget(self.bottomLeftCornerY)
        self.verticalLayout_2.addWidget(self.topRightCornerX)
        self.verticalLayout_2.addWidget(self.topRightCornery)

        self.plotWidget.regionUpdated.connect(self.update_le)

    @QtCore.pyqtSlot(QtCore.QRectF)
    def update_le(self, region):
        self.bottomLeftCornerX.setText(str(region.left()))
        self.bottomLeftCornerY.setText(str(region.top()))
        self.topRightCornerX.setText(str(region.right()))
        self.topRightCornery.setText(str(region.bottom()))


class MplPlot(FigureCanvasQTAgg):
    regionUpdated = QtCore.pyqtSignal(QtCore.QRectF)

    def __init__(self, parent=None):
        fig = Figure()
        super(MplPlot, self).__init__(fig)
        self.setParent(parent)
        # Create a figure with axes
        self.ax = self.figure.add_subplot(111)
        self.ax.set_xlim((-100, 100))
        self.ax.set_ylim((-100, 100))
        self.ax.plot([0], [0])

        # Initialize junk values
        self.bottomLeftX = 0
        self.bottomLeftY = 0
        self.topRightX = 0
        self.topRightY = 0
        self.x = 0
        self.y = 0

        # Set moving flag false (determines if mouse is being clicked and dragged inside plot). Set graph snap
        self.moving = False

        # Set up connectivity
        self.cid = self.mpl_connect("button_press_event", self.onclick)
        self.cid = self.mpl_connect("button_release_event", self.onrelease)
        self.cid = self.mpl_connect("motion_notify_event", self.onmotion)

    def onclick(self, event):
        self.bottomLeftX = event.xdata
        self.bottomLeftY = event.ydata
        self.topRightX = event.xdata
        self.topRightY = event.ydata

        self.update_rect()

        self.moving = True

    def onrelease(self, event):
        self.topRightX = event.xdata
        self.topRightY = event.ydata

        self.update_rect()

        self.moving = False

    def onmotion(self, event):
        if not self.moving:
            return

        self.topRightX = event.xdata
        self.topRightY = event.ydata
        self.update_rect()

    def update_rect(self):
        x = np.array(
            [
                self.bottomLeftX,
                self.bottomLeftX,
                self.topRightX,
                self.topRightX,
                self.bottomLeftX,
            ]
        )
        y = np.array(
            [
                self.bottomLeftY,
                self.topRightY,
                self.topRightY,
                self.bottomLeftY,
                self.bottomLeftY,
            ]
        )

        self.ax.lines[0].set_xdata(x)
        self.ax.lines[0].set_ydata(y)

        if any(
            e is None
            for e in [
                self.topRightX,
                self.topRightY,
                self.bottomLeftX,
                self.bottomLeftY,
            ]
        ):
            return

        rect = QtCore.QRectF(
            self.topRightX, self.topRightY, self.bottomLeftX, self.bottomLeftY
        )
        self.regionUpdated.emit(rect)
        self.draw()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = topLevelWindow()
    w.show()
    sys.exit(app.exec_())