def __init__(self, preffix='', suffix='', labels=False, parent=None): TaurusWidget.__init__(self, parent) self.preffix = preffix self.suffix = suffix self.labels = labels if preffix or suffix: self.setWindowTitle('%s ... %s' % (preffix, suffix)) self.setLayout(Qt.QVBoxLayout()) self.bar = Qt.QWidget(self) self.search = Qt.QLineEdit() self.button = Qt.QPushButton('Load') self.connect(self.button, Qt.SIGNAL("pressed()"), self.apply_search) self.bar.setLayout(Qt.QHBoxLayout()) self.bar.layout().addWidget(self.search) self.bar.layout().addWidget(self.button) self.layout().addWidget(self.bar) self.form = TaurusForm(self) self.layout().addWidget(self.form)
def pickPlotPoint(self, pos, scope=20, showMarker=True, targetCurveNames=None, xlabels=None): '''Finds the pyxel-wise closest data point to the given position. The valid search space is constrained by the scope and targetCurveNames parameters. :param pos: (Qt.QPoint or Qt.QPolygon) the position around which to look for a data point. The position should be passed as a Qt.QPoint (if a Qt.QPolygon is given, the first point of the polygon is used). The position is expected in pixel units, with (0,0) being the top-left corner of the plot canvas. :param scope: (int) defines the area around the given position to be considered when searching for data points. A data point is considered within scope if its manhattan distance to position (in pixels) is less than the value of the scope parameter. (default=20) :param showMarker: (bool) If True, a marker will be put on the picked data point. (default=True) :param targetCurveNames: (sequence<str>) the names of the curves to be searched. If None passed, all curves will be searched :return: (tuple<Qt.QPointF,str,int> or tuple<None,None,None>) if a point was picked within the scope, it returns a tuple containing the picked point (as a Qt.QPointF), the curve name and the index of the picked point in the curve data. If no point was found within the scope, it returns None,None,None ''' print "pickPlotPoint(...)" if isinstance(pos, Qt.QPolygon): pos = pos.first() scopeRect = Qt.QRect(0, 0, scope, scope) scopeRect.moveCenter(pos) mindist = scope picked = None pickedCurveName = None pickedIndex = None self.curves_lock.acquire() try: if targetCurveNames is None: targetCurveNames = self.curves.keys() #print '%d targetCurveNames'%len(targetCurveNames) for name in targetCurveNames: curve = self.curves.get(name, None) if curve is None: #print("Curve '%s' not found"%name) continue if not curve.isVisible(): #print("Curve '%s' not visible"%name) continue data = curve.data() #print("Curve '%s' has %d points"%(name,data.size())) for i in xrange(data.size()): point = Qt.QPoint(self.transform(curve.xAxis(), data.x(i)), self.transform(curve.yAxis(), data.y(i))) if scopeRect.contains(point): #print( 'Comparing %s,%s vs %s'%(pos,scopeRect,point)) dist = (pos - point).manhattanLength() if dist < mindist: mindist = dist picked = Qt.QPointF(data.x(i), data.y(i)) pickedCurveName = name pickedIndex = i pickedAxes = curve.xAxis(), curve.yAxis() found = True #if picked: print("Curve '%s' contains %s"%(name,pos)) finally: self.curves_lock.release() if picked is None: print 'pickPlotPoint(%s)> No matching point found for any curve' % pos return xlabels = xlabels or [] print("pickPlotPoint(x=%s,y=%s,xlabels=[%s])" % (picked.x(), picked.y(), len(xlabels))) if showMarker and picked is not None: print 'showing pickedMarker' self._pickedMarker.detach() self._pickedMarker.setValue(picked) self._pickedMarker.setAxis(*pickedAxes) self._pickedMarker.attach(self) self._pickedCurveName = pickedCurveName self._pickedMarker.pickedIndex = pickedIndex self.replot() label = self._pickedMarker.label() try: xi, xl = ([(x[0], x[1]) for x in (xlabels or []) if x[0] <= picked.x()] or [[-1, None]])[-1] c = self.curves[pickedCurveName] #xc = [self.transform(c.xAxis(),x) for x in c.data().xData()] xc = [x for x in c.data().xData()] xx = len([x for x in xc if x >= xi and x <= picked.x()]) #print [x[0] for x in xlabels] #print 'picked point: %s'%picked.x() #print 'last label %s at %s'%(xl,xi) #print 'data point are %s'%(xc) #print 'data points between pick and label: %s'%xx index = xx tag = '%s-%02d' % (xl, index) if xl and '/ip' in pickedCurveName.lower(): try: tag = PyTango.AttributeProxy( tag.replace('-', '/VC/IP-') + '/Controller').read().value except: import traceback print traceback.format_exc() except: import traceback print traceback.format_exc() index, xl = (-1, None) tag = '' if xl: infotxt = "'%s'[%i]:\n\t (%s,%.2e)" % ( pickedCurveName, pickedIndex, tag, picked.y()) elif self.getXIsTime(): infotxt = "'%s'[%i]:\n\t (x=%s,%.3g)" % ( pickedCurveName, pickedIndex, datetime.fromtimestamp( picked.x()).ctime(), picked.y()) else: infotxt = "'%s'[%i]:\n\t (x=%.3g, y=%.3g)" % ( pickedCurveName, pickedIndex, picked.x(), picked.y()) label.setText(infotxt) print '\t%s' % infotxt fits = label.textSize().width() < self.size().width() if fits: label.setText(infotxt) self._pickedMarker.setLabel(Qwt5.QwtText(label)) self._pickedMarker.alignLabel() self.replot() else: popup = Qt.QWidget(self, Qt.Qt.Popup) popup.setLayout(Qt.QVBoxLayout()) popup.layout().addWidget( Qt.QLabel(infotxt) ) #@todo: make the widget background semitransparent green! popup.setWindowOpacity(self._pickedMarker.labelOpacity) popup.show() popup.move(self.pos().x() - popup.size().width(), self.pos().y()) popup.move(self.pos()) Qt.QTimer.singleShot(5000, popup.hide) return picked, pickedCurveName, pickedIndex