diff --git a/graphExample.py b/graphExample.py new file mode 100755 index 0000000..5ddbcec --- /dev/null +++ b/graphExample.py @@ -0,0 +1,243 @@ +#!/usr/bin/env python +# *-----------------------------------------------------------------------* +# | | +# | Copyright (c) 2022 by Paul Scherrer Institute (http://www.psi.ch) | +# | | +# | Author Thierry Zamofing (thierry.zamofing@psi.ch) | +# *-----------------------------------------------------------------------* + +from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QApplication +from PyQt5.QtGui import QPainter, QColor, QBrush + +from pyqtgraph.Qt import QtCore, QtGui +import numpy as np +import PyQt5.QtGui as QtGui +import PyQt5.QtCore as QtCore +import PyQt5.QtWidgets as QtW +import numpy as np + +import sys + +def obj_info(obj,p=''): + print(f"{p}obj_info:{obj}") + try: + pos=obj.pos() + print(f"{p}pos:({pos.x():.6g},{pos.y():.6g})") # in coordinate value on the scene (no change by zooming) + except AttributeError: + pass + try: + sz=obj.size() + print(f"{p}size:({sz.x():.6g},{sz.y():.6g})") # in coordinate value on the scene (no change by zooming) + except AttributeError: + pass + try: + for k, v in (('Viewport', obj.viewport()), ('Window', obj.window())): + print( + f"{p}{k} (x,y)(w,h):({v.x():.6g},{v.y():.6g})({v.width():.6g},{v.height():.6g})") # in coordinate value on the scene (no change by zooming) + except AttributeError: + pass + try: + scnPos=obj.scenePos() + print(f"{p}scenePos:({scnPos.x():.6g},{scnPos.y():.6g})") # in pixel on the scene (changes by zooming) + except AttributeError: + pass + try: + if type(obj)==QtGui.QTransform: + t=obj + else: + t=obj.transform() + print(f"{p}QTransform:{t.m11():8.5g} {t.m12():8.5g} {t.m13():8.5g}") + print(f"{p} {t.m21():8.5g} {t.m22():8.5g} {t.m23():8.5g}") + print(f"{p} {t.m31():8.5g} {t.m32():8.5g} {t.m33():8.5g}") + except AttributeError: + pass + +def drawArrow(): + pass + + + +class RIXSgirder(QWidget): + + def __init__(self): + super().__init__() + + self.initUI() + + def initUI(self): + self.setGeometry(300, 300, 850, 800) + self.setWindowTitle('RIXS girder') + #label = QLabel('Python', self) + #label.move(50,50) + b1 = QPushButton("Button1",self) + b1.move(400,150) + + self.show() + + def paintEvent(self, e): + qp = QPainter() + qp.begin(self) + qp.translate(200,200) + qp.setPen(QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)) + qp.setBrush(QColor(255, 80, 0, 128)) + + qp.drawEllipse(-100, -100, 200, 200) # big chamber + qp.drawEllipse(-10, -10, 20, 20) # target + qp.drawLine(0,-150,0,-10) #beam + qp.rotate(-45) + qp.drawRect(-50, 100, 100, 300) # girder + qp.drawEllipse(-50, 100+150, 20, 20) #pusher left + qp.drawEllipse( 50-20, 100+150, 20, 20) #pusher right + + qp.end() + +class RIXSgrating(QWidget): + + def __init__(self): + super().__init__() + self._param={'ctr':(400,400), # location of vlsg + 'aa':20, #grating angle + 'gg':90, #detector angle + 'r1':350,#distance probe grating + 'r2':450,#distance grating detector + 'szG':(200,5), #size VLS grating + 'szD':(150,5), #size detector + } + self.initUI() + + def initUI(self): + #p=self.palette() + #p.setColor(self.backgroundRole(), QtCore.Qt.black) + #self.setPalette(p) + self.setGeometry(300, 300, 850, 800) + self.setWindowTitle('RIXS grating') + #label = QLabel('Python', self) + #label.move(50,50) + b1 = QPushButton("Button1",self) + b1.move(400,150) + + w = QWidget(self) + w.move(100,100) + self._wgGrid1=grid=QtGui.QGridLayout(w) + #grid.move(20, 200) + w=QLabel('QLabel') + grid.addWidget(w, 0,0) + w=QPushButton('QPushButton') + grid.addWidget(w, 0,1) + #self.setLayout(grid) + + + sld={} + for key,rng,tk,pos in (('aa',(0,90),5,20),('gg',(0,180),5,40),('r1',(200,500),5,60),('r2',(200,500),5,80)): + sl=QtGui.QSlider(QtCore.Qt.Horizontal,self) + sl.setFixedWidth(200);sl.setMinimum(rng[0]);sl.setMaximum(rng[1]) + sl.setValue(self._param[key]) + sl.setTickPosition(QtGui.QSlider.TicksBelow);sl.setTickInterval(tk) + sl.move(20,pos) + sl.valueChanged.connect(lambda val,key=key: self.sldChanged(key,val)) + sld[key]=sl + + self.show() + + def sldChanged(self,key,val,*args,**kwargs): + print(key,val) + self._param[key]=val + self.update() + + + def paintEvent(self, e): + p=self._param + r1=p['r1'] + r2=p['r2'] + aa=p['aa'] + gg=p['gg'] + szG=p['szG'] + szD=p['szD'] + ctr=p['ctr'] + + qp = QPainter() + qp.begin(self) + + #plot black background + w=int(max(szG[0],szD[0])/2) + ctr=(max(ctr[0],w+r1),max(w+r2*np.sin(aa*2*np.pi/180),ctr[1])) + qp.translate(ctr[0],ctr[1]) + qp.setBrush(QColor(0, 0, 0)) + qp.drawRect(-r1, -w, r1, 2*w) + qp.drawEllipse(-r1-w, -w, 2*w, 2*w) + qp.drawEllipse(-w, -w, 2*w, 2*w) + qp.rotate(180-2*aa) + qp.drawRect(-r2, -w, r2, 2*w) + qp.drawEllipse(-r2-w, -w, 2*w, 2*w) + + #plot beam path + qp.setTransform(QtGui.QTransform()) + qp.translate(ctr[0],ctr[1]) + qp.setCompositionMode(QtGui.QPainter.CompositionMode_Lighten) + + + tf0=qp.transform() + qp.setPen(QtGui.QPen(QtCore.Qt.white, 1, QtCore.Qt.SolidLine)) + qp.setBrush(QColor(255, 80, 0, 128)) + + qp.drawEllipse(-r1-20, -10, 20, 20) # target + qp.drawLine(-r1,0,0,0) #beam + qp.rotate(-aa) + tf1=qp.transform() + qp.drawRect(int(-szG[0]/2), 0, szG[0], szG[1]) # grating + qp.rotate(-aa) + qp.drawLine(0,0,r2,0) #beam + qp.translate(r2,0) + qp.rotate(-gg) + tf2=qp.transform() + qp.drawRect(int(-szD[0]/2),0 , szD[0], szD[1]) # detector + + #beam target to vlsg + qp.setTransform(QtGui.QTransform()) + p0=QtCore.QPointF(*tf0.map(-r1-10, 10)) + p1=QtCore.QPointF(*tf1.map(-szG[0]/2, 0)) + qp.drawLine(p0,p1) + p0=QtCore.QPointF(*tf0.map(-r1-10, -10)) + p1=QtCore.QPointF(*tf1.map(szG[0]/2, 0)) + qp.drawLine(p0,p1) + + # beam vlsg to detector + n=16 + pen=QtGui.QPen(QtCore.Qt.black, 3, QtCore.Qt.SolidLine) + col=pen.color() + p0=QtCore.QPointF(*tf1.map(-szG[0]/2, 0)) + p1=QtCore.QPointF(*tf1.map(szG[0]/2, 0)) + for i in range(n): + col.setHsv(i*16,255,255,120) + pen.setColor(col) + qp.setPen(pen) + p2=QtCore.QPointF(*tf2.map(-szD[0]/2+szD[0]*i/(n-1),0)) + qp.drawLine(p0,p2) + qp.drawLine(p1,p2) + + + return + + + qp.drawEllipse(-100, -100, 200, 200) # big chamber + qp.drawEllipse(-10, -10, 20, 20) # target + qp.drawLine(0,-150,0,-10) #beam + qp.rotate(-45) + qp.drawRect(-50, 100, 100, 300) # girder + qp.drawEllipse(-50, 100+150, 20, 20) #pusher left + qp.drawEllipse( 50-20, 100+150, 20, 20) #pusher right + + qp.end() + + + + +def main(): + app = QApplication(sys.argv) + #ex = RIXSgirder() + ex = RIXSgrating() + sys.exit(app.exec_()) + + +if __name__ == '__main__': + main() \ No newline at end of file