【问题标题】:Using a button to open and close a matplotlib widget使用按钮打开和关闭 matplotlib 小部件
【发布时间】:2019-01-19 07:56:10
【问题描述】:

到目前为止,我所写内容的目的是在我的 GUI 中有一个“温度”按钮,按下该按钮会打开我单独制作的 matplotlib 图 (mplwidget.py)。

但是,当我运行代码时,应用程序和小部件同时打开,并且温度按钮似乎没有任何功能(即使我关闭小部件,按下按钮也不会再次打开它)。

import sys
from PyQt5.QtCore import QCoreApplication

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QPushButton, QAction, QMessageBox
from PyQt5.uic.properties import QtGui

from mplwidget import animate #import animation widget

class window(QMainWindow):

    def __init__(self):
        super(window, self).__init__()
        self.setGeometry(50, 50, 500, 300)
        self.setWindowTitle('Temperature Control')
        self.setWindowIcon(QIcon('adn.png'))

        extractAction = QAction('&Quit', self)
        extractAction.setShortcut('Ctrl+Q')
        extractAction.setStatusTip('leave the app')
        extractAction.triggered.connect(self.close_application)

        self.statusBar()

        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu('&File')
        fileMenu.addAction(extractAction)

        self.home()

    def home(self):
        btn = QPushButton('quit', self)
        btn.clicked.connect(self.close_application)
        btn.resize(btn.sizeHint())
        btn.move(0, 100)

        button = QPushButton('Temperature',self)
        button.clicked.connect(self.opengraph)
        button.move(50,200)
        self.show()

    def opengraph(self):
        animate()

    def close_application(self):

        choice = QMessageBox.question(self, 'Message',
                                     "Are you sure to quit?", QMessageBox.Yes |
                                     QMessageBox.No, QMessageBox.No)

        if choice == QMessageBox.Yes:
            sys.exit()
        else:
            pass

if __name__ == "__main__":

    def run():
        app = QApplication(sys.argv)
        Gui = window()
        sys.exit(app.exec_())

run()

mplwidget 在下面

def GraphWidget():

    fig = plt.figure()
    ax1 = fig.add_subplot(1,1,1)

    Time = []
    Temp = []

    def animate(i):

        x = datetime.datetime.now()
        y = numpy.random.randint(48,52)
        Time.append(x)
        Temp.append(int(y))    

    #    print (Temp)
        ax1.plot(Time,Temp)

    ani = animation.FuncAnimation(fig,animate, interval=1000)
    plt.show()

【问题讨论】:

  • 不能调用模块。相反,您可能会在模块中调用一个函数;类似mplwidget.showmywindow()
  • 你可以发布mplwidget.py ?
  • 当然,我现在就这么做@S.Nick
  • @ImportanceOfBeingErnest 你是这个意思吗?:def opengraph(self): mpl = mplwidget() mpl.show()
  • 当您执行import mymodule 时,代码会直接执行。相反,您希望将其放入可以从导入脚本中调用的函数中。

标签: python matplotlib button pyqt5


【解决方案1】:

试试看:

import sys
from PyQt5.QtGui     import QIcon
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QAction, QMessageBox

from mplwidget import MplWindow                     # +++

class window(QMainWindow):

    def __init__(self):
        super(window, self).__init__()
        self.setGeometry(50, 50, 500, 300)
        self.setWindowTitle('Temperature Control')
        self.setWindowIcon(QIcon('adn.png'))
        extractAction = QAction('&Quit', self)
        extractAction.setShortcut('Ctrl+Q')
        extractAction.setStatusTip('leave the app')
        extractAction.triggered.connect(self.close_application)
        self.statusBar()
        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu('&File')
        fileMenu.addAction(extractAction)

        self.matplWindow = MplWindow()               # +++

        self.home()


    def home(self):
        btn = QPushButton('quit', self)
        btn.clicked.connect(self.close_application)
        btn.resize(btn.sizeHint())
        btn.move(0, 100)
        button = QPushButton('Temperature',self)
        button.clicked.connect(self.opengraph)
        button.move(50,200)
        self.show()

    def opengraph(self):
        self.matplWindow.funAnimation()              # +++

    def close_application(self):
        choice = QMessageBox.question(self, 'Message',
                                     "Are you sure to quit?", QMessageBox.Yes |
                                     QMessageBox.No, QMessageBox.No)
        if choice == QMessageBox.Yes:
            sys.exit()
        else:
            pass

if __name__ == "__main__":
    app = QApplication(sys.argv)
    Gui = window()
    sys.exit(app.exec_())

mplwidget.py

import matplotlib.pyplot as plt
import numpy
import datetime
import matplotlib.animation as animation
from PyQt5.QtWidgets import QDialog, QApplication, QPushButton, QVBoxLayout


class MplWindow(QDialog):
    Time = []
    Temp = []
    def __init__(self, parent=None):
        super(MplWindow, self).__init__(parent)

    def funAnimation(self):        
        self.fig = plt.figure()
        self.ax1 = self.fig.add_subplot(1,1,1)
        self.ani = animation.FuncAnimation(self.fig, self.animate, interval=1000)
        plt.show()

    def animate(self, i):
        x = datetime.datetime.now()
        y = numpy.random.randint(48,52)
        self.Time.append(x)
        self.Temp.append(int(y))    
        self.ax1.plot(self.Time, self.Temp)

【讨论】:

  • 谢谢!这真的很有帮助,因为我认为即使在打开和关闭小部件之间继续绘制点也非常有用
【解决方案2】:

问题是plt.show() 本身无法启动事件循环,因为由于 QT 窗口打开,事件循环已经在运行。在这种情况下,需要调用fig.show(),其中fig 是正在使用的数字。

这反过来又导致mplwidget.py 模块中的函数实际返回的问题。一旦它返回动画的引用就会丢失并且会被垃圾回收;因此屏幕上不会出现动画。

解决的办法是让函数返回动画,并将其存储在主程序的某处。

import sys
from PyQt5.QtCore import QCoreApplication

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QPushButton, QAction, QMessageBox
from PyQt5.uic.properties import QtGui

from mplwidget import showgraph

class window(QMainWindow):

    def __init__(self):
        super(window, self).__init__()
        self.setGeometry(50, 50, 500, 300)
        self.setWindowTitle('Temperature Control')
        self.setWindowIcon(QIcon('adn.png'))

        extractAction = QAction('&Quit', self)
        extractAction.setShortcut('Ctrl+Q')
        extractAction.setStatusTip('leave the app')
        extractAction.triggered.connect(self.close_application)

        self.statusBar()

        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu('&File')
        fileMenu.addAction(extractAction)

        self.home()

    def home(self):
        btn = QPushButton('quit', self)
        btn.clicked.connect(self.close_application)
        btn.resize(btn.sizeHint())
        btn.move(0, 100)

        button = QPushButton('Temperature',self)
        button.clicked.connect(self.opengraph)
        button.move(50,200)
        self.show()

    def opengraph(self):
        self.store = showgraph()

    def close_application(self):

        choice = QMessageBox.question(self, 'Message',
                                     "Are you sure to quit?", QMessageBox.Yes |
                                     QMessageBox.No, QMessageBox.No)

        if choice == QMessageBox.Yes:
            sys.exit()
        else:
            pass

if __name__ == "__main__":

    def run():
        app = QApplication(sys.argv)
        Gui = window()
        sys.exit(app.exec_())

run()

mplwidget.py:

import matplotlib.pyplot as plt
import datetime
import numpy
import matplotlib.animation as animation

def showgraph():

    fig = plt.figure()
    ax1 = fig.add_subplot(1,1,1)

    Time = []
    Temp = []

    def animate(i):

        x = datetime.datetime.now()
        y = numpy.random.randint(48,52)
        Time.append(x)
        Temp.append(int(y))    

        ax1.plot(Time,Temp)

    ani = animation.FuncAnimation(fig,animate, interval=1000)
    fig.show()
    return fig, ani

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    相关资源
    最近更新 更多