Ich versuche, ein Programm zu machen, in dem ich ein Hauptfenster und ein zweites Fenster habe. Das zweite Fenster sollte geöffnet werden, indem eine Check-Box im Hauptfenster aktiviert und durch Deaktivieren der Checkbox geschlossen wird.Erstellen eines Diagramms in einem zweiten Fenster mit Daten aus dem Hauptfenster
Das folgende minimale Beispiel funktioniert bereits gut (dank ImportanceOfBeingErnest!), Aber ich möchte den Pfeil (der, der bereits beim Ausführen des Beispiels gebogen ist) durch Drehen der SpinBox im Hauptfenster drehen.
Lösung: Siehe 5. Kommentar in der ersten Antwort!
import sys
from PyQt4 import QtGui, QtCore
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib import animation
import numpy as np
class Newsphere(QtGui.QMainWindow):
def __init__(self):
super(Newsphere, self).__init__()
self.mainbox = QtGui.QWidget()
self.mainbox.setLayout(QtGui.QHBoxLayout())
self.setCentralWidget(self.mainbox)
self.spin = QtGui.QSpinBox()
self.spin.setValue(20)
self.spin.setMaximum(100)
self.spin.setMinimum(-100)
self.checkPlot = QtGui.QCheckBox("Check")
self.mainbox.layout().addWidget(self.spin)
self.mainbox.layout().addWidget(self.checkPlot)
self.Plot = None
self.checkPlot.clicked.connect(self.showPlot)
def showPlot(self):
if self.Plot == None:
self.Plot = Plot(self.kinematic())
self.Plot.show()
# register signal for closure
self.Plot.signalClose.connect(self.uncheck)
# register signal for spin value changed
self.spin.valueChanged.connect(self.kinematic)
else:
self.Plot.close()
self.Plot = None
def kinematic(self):
x = self.spin.value()/100
v = np.matrix([[1.,x,0.],[0.,1.,0.],[0.,0.,1.]])
zero = np.matrix([[0.,0.,0.],[0.,0.,0.],[0.,0.,0.]])
pos = np.hstack([v, zero])
return pos
def uncheck(self):
self.checkPlot.setChecked(False)
self.Plot = None
class Plot(QtGui.QWidget):
signalClose = QtCore.pyqtSignal()
def __init__(self, pos=None):
super(Plot, self).__init__()
self.setLayout(QtGui.QHBoxLayout())
self.fig = plt.figure()
self.ax = self.fig.add_subplot(111,projection = '3d')
self.fig.tight_layout()
self.ax.view_init(40, 225)
''' dashed coordinate system '''
self.ax.plot([0,1], [0,0], [0,0], label='$X_0$', linestyle="dashed", color="red")
self.ax.plot([0,0], [0,-10], [0,0], label='$Y_0$', linestyle="dashed", color="green")
self.ax.plot([0,0], [0,0], [0,1], label='$Z_0$', linestyle="dashed", color="blue")
self.ax.set_xlim3d(-3,3)
self.ax.set_ylim3d(-3,3)
self.ax.set_zlim3d(-3,3)
self.canvas = FigureCanvas(self.fig)
self.layout().addWidget(self.canvas)
self.pos = pos
self.setup_plot()
self.ani = animation.FuncAnimation(self.fig, self.update_plot, init_func=self.setup_plot, blit=True)
def setup_plot(self):
self.ax.legend(loc='best')
self.position = self.ax.quiver(0, 0, 0, 0, 0, 0, pivot="tail", color="black")
return self.position,
def update_plot(self, i):
x_zero = self.pos[:,3]
y_zero = self.pos[:,4]
z_zero = self.pos[:,5]
v_x = self.pos[0,0:3]
v_y = self.pos[1,0:3]
v_z = self.pos[2,0:3]
self.position = self.ax.quiver(-x_zero, -y_zero, z_zero, -v_x[0,:], v_y[0,:], v_z[0,:], pivot="tail", color="black")
self.canvas.draw()
return self.position,
# We need to make sure the animation stops, when the window is closed
def closeEvent(self, event):
self.signalClose.emit()
self.close()
super(Plot, self).closeEvent(event)
def close(self):
self.ani.event_source.stop()
super(Plot, self).close()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = Newsphere()
main.show()
sys.exit(app.exec_())
Was genau funktioniert nicht? Da Sie nie 'Kinematic' nennen, was würden Sie erwarten? Es scheint auch, dass "self.pos" nirgendwo wirklich definiert ist, also nehme ich an, dass "update_plot" nicht richtig funktioniert? – ImportanceOfBeingErnest
Mischen Sie 'pyplot' nicht mit Ihrer eigenen Einbettung, da dies zu subtilen globalen Statusproblemen führen kann. Sie sollten Signal/Slots verwenden, um zwischen Ihren Klassen zu kommunizieren. – tacaswell
@ImportanceOfBeingErnest: Ah Entschuldigung, ich habe eine Zeile vergessen (Zeile 67). Wenn ich versuche, es jetzt auszuführen, erhalte ich den Fehler "x_zero = self.pos [:, 0] TypeError: 'Funktion' Objekt ist nicht einfügbar". – Michael