Matplotlib RectangleSelector killed by PyQt4

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
JoS
User
Beiträge: 5
Registriert: Dienstag 26. Januar 2010, 23:07

Liebes Forum,

ich bin gerade dabei ein Script zum Auswerten von Messdaten zu schreiben. Im Grunde lese ich Tabulator getrennte Text Dateien (über eine pyqt4 GUI) ein und mache ein paar Berechnungen und stelle das Ergebnis u.a. als Graphik dar. Diese erstelle ich mit matplotlib. Soweit scheint alles zu funktionieren. Für die Detailauswertung fände ich es praktisch mit dem RectangleSelector Interessante Bereiche in der Graphik auszuwählen. Das funktioniert dann nicht mehr.
Ich habe jetzt erst einmal alles aus dem Programm entfernt, das nicht unmittelbar mit der Darstellung zu tun hat und aus dem Beispielcode alles übernommen um ein möglicherweise funktionierendes Programm zu erhalten.

Als Fehlermeldung bekomme ich:

Code: Alles auswählen

QCoreApplication::exec: The event loop is already running
Mein Programmskelett (läuft, zeigt mir die Graphik, aber ich kann nichts auswählen):

Code: Alles auswählen

import sys
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import RectangleSelector as rts
from PyQt4 import QtGui, QtCore
from ejvk_dataprocessor_ui import Ui_MainWindow


    
class StartGui(QtGui.QMainWindow):    
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.connect(self.ui.pushButtonOpen, QtCore.SIGNAL("clicked()"), self.opendatafile)

    def opendatafile(self):
        tg=fi_g()

class fi_g(object):
    def __init__(self,parent=None):
        
        self.set_rs()
        
    def set_rs(self):
        current_ax = plt.subplot(111)                    # make a new plotingrange
        N = 100000                                       # If N is large one can see 
        x = np.linspace(0.0, 10.0, N)                    # improvement by use blitting!
        
        plt.plot(x, +np.sin(.2*np.pi*x), lw=3.5, c='b', alpha=.7)  # plot something
        plt.plot(x, +np.cos(.2*np.pi*x), lw=3.5, c='r', alpha=.5)
        plt.plot(x, -np.sin(.2*np.pi*x), lw=3.5, c='g', alpha=.3)
        
        
        
        print "\n      click  -->  release to select a rectangle"
        print " key 'd' to delete previously selected rectangle "
        print " key 'a' to activate rectangle selector "
        print " key 'q' to deactivate rectangle selector "
        RS = rts(current_ax, self.line_select_callback,
                                               drawtype='box', useblit=True,
                                               minspanx=5, minspany=5,
                                               spancoords='pixels')
        plt.show()
    def line_select_callback(self,eclick, erelease):
        'eclick and erelease are the press and release events'
        x1, y1 = eclick.xdata, eclick.ydata
        x2, y2 = erelease.xdata, erelease.ydata
        print "(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2)
        print " The button you used were: ", eclick.button, erelease.button
    
        line, = plt.plot([eclick.xdata, erelease.xdata, erelease.xdata,
                          eclick.xdata, eclick.xdata],
                         [eclick.ydata, eclick.ydata, erelease.ydata,
                          erelease.ydata, eclick.ydata],
                         color='blue')
        rectangles.append(line)
        plt.draw()

if __name__=="__main__":
    app=QtGui.QApplication(sys.argv)
    myapp = StartGui()
    myapp.show()
    sys.exit(app.exec_())
Woran kann das liegen? Fängt hier pyqt4 was ab, was für matplotlib gedacht ist?
Vielen Dank,
mit freundllichen Grüßen
Jo
ps.: Das ganze passiert unter 32bit Windows7 und ich verwende Python(x,y) 2.7.5.1 (Full)
BlackJack

@JoS: Man kann das ja so nicht nachvollziehen weil `ejvk_dataprocessor_ui` fehlt. Das ist übrigens nicht mehr zeitgemäss Quelltext aus der UI-Datei zu erstellen. Mit dem `uic`-Modul kann man die UI-Dateien zur Laufzeit laden und daraus GUI-Objekte erstellen lassen.

Ebenfalls veraltet ist die Art wie Du das Signal verbindest. Das geht schon ziemlich lange kürzer und typsicherer:

Code: Alles auswählen

        # statt
        self.connect(self.ui.pushButtonOpen, QtCore.SIGNAL("clicked()"), self.opendatafile)
        # besser
        self.ui.pushButtonOpen.clicked.connect(self.opendatafile)
Die `fi_g`-Klasse ist unsinnig, das ist keine Klasse. Jedenfalls nicht von der Semantik.

Was das Problem sein könnte, oder zumindest *ein* Problem, ist die Speicherverwaltung. Wenn man sich anschaut was bei einem Klick auf die Schaltfläche passiert, dann wird da nichts von Beständigkeit erstellt. Alles wird nur an lokale Namen gebunden.
Antworten