#!/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()