def __init__(self, parent=None, widgimage=None, ifname='', ofname='./fig.png', help_msg=None, expand=False, fexmod=False, verb=False): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('GUI of buttons') self.setFrame() self.parent = parent self.ifname = ifname self.ofname = ofname self.is_expanded = expand self.guirange = None self.fexmod = fexmod self.verb = verb self.widgimage = widgimage if widgimage is None : self.fig = self # need it to pass pars self.fig.myNBins = 40 self.fig.myGridIsOn = False self.fig.myLogXIsOn = False self.fig.myLogYIsOn = False self.fig.myZmin = None self.fig.myZmax = None else : self.fig = widgimage.fig if help_msg==None : self.help_msg = self.help_message() else : self.help_msg = help_msg self.but_more = QtGui.QPushButton('&More') self.but_reset = QtGui.QPushButton('&Reset') self.but_help = QtGui.QPushButton('&Help') self.but_load = QtGui.QPushButton('Load') self.but_diff = QtGui.QPushButton('Diff') self.but_save = QtGui.QPushButton('&Save') self.but_elog = QtGui.QPushButton('&ELog') #u'\u2192 &ELog' self.but_quit = QtGui.QPushButton('&Close') self.cbox_grid = QtGui.QCheckBox('&Grid') self.cbox_logx = QtGui.QCheckBox('&X') self.cbox_logy = QtGui.QCheckBox('&Y') self.tit_log = QtGui.QLabel('Log:') self.tit_nbins = QtGui.QLabel('N bins:') self.edi_nbins = QtGui.QLineEdit(self.stringOrNone(self.fig.myNBins)) self.set_buttons() self.setIcons() width = 60 self.edi_nbins.setFixedWidth(width) #self.but_reset.setFixedWidth(width) #self.but_help .setFixedWidth(width) #self.but_save .setFixedWidth(width) #self.but_elog .setFixedWidth(width) #self.but_quit .setFixedWidth(width) self.edi_nbins.setValidator(QtGui.QIntValidator(1,1000,self)) self.but_help .setStyleSheet (cp.styleButtonGood) self.but_more .setStyleSheet (cp.styleButton) self.but_reset.setStyleSheet (cp.styleButton) self.but_load .setStyleSheet (cp.styleButton) self.but_diff .setStyleSheet (cp.styleButton) self.but_save .setStyleSheet (cp.styleButton) self.but_quit .setStyleSheet (cp.styleButtonBad) self.connect(self.but_more, QtCore.SIGNAL('clicked()'), self.on_but_more) self.connect(self.but_help, QtCore.SIGNAL('clicked()'), self.on_but_help) self.connect(self.but_reset, QtCore.SIGNAL('clicked()'), self.on_but_reset) self.connect(self.but_load, QtCore.SIGNAL('clicked()'), self.on_but_load) self.connect(self.but_diff, QtCore.SIGNAL('clicked()'), self.on_but_diff) self.connect(self.but_save, QtCore.SIGNAL('clicked()'), self.on_but_save) self.connect(self.but_elog, QtCore.SIGNAL('clicked()'), self.on_but_elog) self.connect(self.but_quit, QtCore.SIGNAL('clicked()'), self.on_but_quit) self.connect(self.cbox_grid, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_grid) self.connect(self.cbox_logx, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_logx) self.connect(self.cbox_logy, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_logy) self.connect(self.edi_nbins, QtCore.SIGNAL('editingFinished ()'), self.on_edit_nbins) #self.setGridLayout() self.setPanelLayout() self.showToolTips() #self.setFixedHeight(50) pbits = 377 if self.verb else 0 self.afe_rd = ArrFileExchange(prefix=self.ifname, rblen=3, print_bits=pbits)
def __init__(self, parent=None, widgimage=None, ifname='', ofname='./fig.png', help_msg=None, expand=False, fexmod=False, verb=False): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('GUI of buttons') self.setFrame() self.parent = parent self.ifname = ifname self.ofname = ofname self.is_expanded = expand self.guirange = None self.fexmod = fexmod self.verb = verb self.widgimage = widgimage if widgimage is None: self.fig = self # need it to pass pars self.fig.myNBins = 40 self.fig.myGridIsOn = False self.fig.myLogXIsOn = False self.fig.myLogYIsOn = False self.fig.myZmin = None self.fig.myZmax = None else: self.fig = widgimage.fig if help_msg == None: self.help_msg = self.help_message() else: self.help_msg = help_msg self.but_more = QtGui.QPushButton('&More') self.but_reset = QtGui.QPushButton('&Reset') self.but_help = QtGui.QPushButton('&Help') self.but_load = QtGui.QPushButton('Load') self.but_diff = QtGui.QPushButton('Diff') self.but_save = QtGui.QPushButton('&Save') self.but_elog = QtGui.QPushButton('&ELog') #u'\u2192 &ELog' self.but_quit = QtGui.QPushButton('&Close') self.cbox_grid = QtGui.QCheckBox('&Grid') self.cbox_logx = QtGui.QCheckBox('&X') self.cbox_logy = QtGui.QCheckBox('&Y') self.tit_log = QtGui.QLabel('Log:') self.tit_nbins = QtGui.QLabel('N bins:') self.edi_nbins = QtGui.QLineEdit(self.stringOrNone(self.fig.myNBins)) self.set_buttons() self.setIcons() width = 60 self.edi_nbins.setFixedWidth(width) #self.but_reset.setFixedWidth(width) #self.but_help .setFixedWidth(width) #self.but_save .setFixedWidth(width) #self.but_elog .setFixedWidth(width) #self.but_quit .setFixedWidth(width) self.edi_nbins.setValidator(QtGui.QIntValidator(1, 1000, self)) self.but_help.setStyleSheet(cp.styleButtonGood) self.but_more.setStyleSheet(cp.styleButton) self.but_reset.setStyleSheet(cp.styleButton) self.but_load.setStyleSheet(cp.styleButton) self.but_diff.setStyleSheet(cp.styleButton) self.but_save.setStyleSheet(cp.styleButton) self.but_quit.setStyleSheet(cp.styleButtonBad) self.connect(self.but_more, QtCore.SIGNAL('clicked()'), self.on_but_more) self.connect(self.but_help, QtCore.SIGNAL('clicked()'), self.on_but_help) self.connect(self.but_reset, QtCore.SIGNAL('clicked()'), self.on_but_reset) self.connect(self.but_load, QtCore.SIGNAL('clicked()'), self.on_but_load) self.connect(self.but_diff, QtCore.SIGNAL('clicked()'), self.on_but_diff) self.connect(self.but_save, QtCore.SIGNAL('clicked()'), self.on_but_save) self.connect(self.but_elog, QtCore.SIGNAL('clicked()'), self.on_but_elog) self.connect(self.but_quit, QtCore.SIGNAL('clicked()'), self.on_but_quit) self.connect(self.cbox_grid, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_grid) self.connect(self.cbox_logx, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_logx) self.connect(self.cbox_logy, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_logy) self.connect(self.edi_nbins, QtCore.SIGNAL('editingFinished ()'), self.on_edit_nbins) #self.setGridLayout() self.setPanelLayout() self.showToolTips() #self.setFixedHeight(50) pbits = 377 if self.verb else 0 self.afe_rd = ArrFileExchange(prefix=self.ifname, rblen=3, print_bits=pbits)
class PlotImgSpeButtons (QtGui.QWidget) : """Buttons for interactive plot of the image and spectrum for 2-d array.""" #---------------- # Constructor -- #---------------- def __init__(self, parent=None, widgimage=None, ifname='', ofname='./fig.png', help_msg=None, expand=False, fexmod=False, verb=False): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('GUI of buttons') self.setFrame() self.parent = parent self.ifname = ifname self.ofname = ofname self.is_expanded = expand self.guirange = None self.fexmod = fexmod self.verb = verb self.widgimage = widgimage if widgimage is None : self.fig = self # need it to pass pars self.fig.myNBins = 40 self.fig.myGridIsOn = False self.fig.myLogXIsOn = False self.fig.myLogYIsOn = False self.fig.myZmin = None self.fig.myZmax = None else : self.fig = widgimage.fig if help_msg==None : self.help_msg = self.help_message() else : self.help_msg = help_msg self.but_more = QtGui.QPushButton('&More') self.but_reset = QtGui.QPushButton('&Reset') self.but_help = QtGui.QPushButton('&Help') self.but_load = QtGui.QPushButton('Load') self.but_diff = QtGui.QPushButton('Diff') self.but_save = QtGui.QPushButton('&Save') self.but_elog = QtGui.QPushButton('&ELog') #u'\u2192 &ELog' self.but_quit = QtGui.QPushButton('&Close') self.cbox_grid = QtGui.QCheckBox('&Grid') self.cbox_logx = QtGui.QCheckBox('&X') self.cbox_logy = QtGui.QCheckBox('&Y') self.tit_log = QtGui.QLabel('Log:') self.tit_nbins = QtGui.QLabel('N bins:') self.edi_nbins = QtGui.QLineEdit(self.stringOrNone(self.fig.myNBins)) self.set_buttons() self.setIcons() width = 60 self.edi_nbins.setFixedWidth(width) #self.but_reset.setFixedWidth(width) #self.but_help .setFixedWidth(width) #self.but_save .setFixedWidth(width) #self.but_elog .setFixedWidth(width) #self.but_quit .setFixedWidth(width) self.edi_nbins.setValidator(QtGui.QIntValidator(1,1000,self)) self.but_help .setStyleSheet (cp.styleButtonGood) self.but_more .setStyleSheet (cp.styleButton) self.but_reset.setStyleSheet (cp.styleButton) self.but_load .setStyleSheet (cp.styleButton) self.but_diff .setStyleSheet (cp.styleButton) self.but_save .setStyleSheet (cp.styleButton) self.but_quit .setStyleSheet (cp.styleButtonBad) self.connect(self.but_more, QtCore.SIGNAL('clicked()'), self.on_but_more) self.connect(self.but_help, QtCore.SIGNAL('clicked()'), self.on_but_help) self.connect(self.but_reset, QtCore.SIGNAL('clicked()'), self.on_but_reset) self.connect(self.but_load, QtCore.SIGNAL('clicked()'), self.on_but_load) self.connect(self.but_diff, QtCore.SIGNAL('clicked()'), self.on_but_diff) self.connect(self.but_save, QtCore.SIGNAL('clicked()'), self.on_but_save) self.connect(self.but_elog, QtCore.SIGNAL('clicked()'), self.on_but_elog) self.connect(self.but_quit, QtCore.SIGNAL('clicked()'), self.on_but_quit) self.connect(self.cbox_grid, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_grid) self.connect(self.cbox_logx, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_logx) self.connect(self.cbox_logy, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_logy) self.connect(self.edi_nbins, QtCore.SIGNAL('editingFinished ()'), self.on_edit_nbins) #self.setGridLayout() self.setPanelLayout() self.showToolTips() #self.setFixedHeight(50) pbits = 377 if self.verb else 0 self.afe_rd = ArrFileExchange(prefix=self.ifname, rblen=3, print_bits=pbits) def setIcons(self) : cp.setIcons() self.but_elog .setIcon(cp.icon_mail_forward) self.but_load .setIcon(cp.icon_browser) # icon_contents) self.but_diff .setIcon(cp.icon_minus) # icon_contents) self.but_save .setIcon(cp.icon_save) self.but_quit .setIcon(cp.icon_exit) self.but_help .setIcon(cp.icon_help) self.but_reset.setIcon(cp.icon_reset) def setPanelLayoutV1(self): self.hbox = QtGui.QHBoxLayout() self.hbox.addWidget(self.but_help) self.hbox.addWidget(self.tit_nbins) self.hbox.addWidget(self.edi_nbins) self.hbox.addWidget(self.cbox_grid) self.hbox.addWidget(self.tit_log) self.hbox.addWidget(self.cbox_logx) self.hbox.addWidget(self.cbox_logy) self.hbox.addWidget(self.but_reset) self.hbox.addStretch(1) self.hbox.addWidget(self.but_load) self.hbox.addWidget(self.but_diff) self.hbox.addWidget(self.but_save) self.hbox.addWidget(self.but_elog) self.hbox.addWidget(self.but_quit) self.hbox.addWidget(self.but_more) self.setLayout(self.hbox) self.setPannel() def setPanelLayout(self): self.hbox1 = QtGui.QHBoxLayout() self.hbox1.addWidget(self.but_help) self.hbox1.addWidget(self.tit_nbins) self.hbox1.addWidget(self.edi_nbins) self.hbox1.addWidget(self.cbox_grid) self.hbox1.addWidget(self.tit_log) self.hbox1.addWidget(self.cbox_logx) self.hbox1.addWidget(self.cbox_logy) self.hbox1.addWidget(self.but_reset) self.hbox1.addStretch(1) self.hbox1.addWidget(self.but_elog) self.hbox1.addWidget(self.but_quit) self.hbox1.addWidget(self.but_more) self.guirange = GUIRangeIntensity(self, None, None, txt_from='Spec range', txt_to=':') self.hbox2 = QtGui.QHBoxLayout() self.hbox2.addWidget(self.but_load) self.hbox2.addWidget(self.but_diff) self.hbox2.addWidget(self.guirange) self.hbox2.addStretch(1) self.hbox2.addWidget(self.but_save) self.vbox = QtGui.QVBoxLayout() self.vbox.addLayout(self.hbox2) self.vbox.addLayout(self.hbox1) self.vbox.addStretch(1) self.setLayout(self.vbox) self.setContentsMargins (QtCore.QMargins(0,-5,0,-5)) self.setPannel() def setZMin(self, zmin=None) : if self.guirange is None : return self.guirange.setParamFrom(zmin) def setZMax(self, zmin=None) : if self.guirange is None : return self.guirange.setParamTo(zmax) def setZRange(self, str_from=None, str_to=None) : if self.guirange is None : return self.guirange.setParams(str_from, str_to) def setPannel(self): self.but_quit.setVisible(False) self.but_elog.setVisible(False) #self.but_help.setVisible(False) self.but_load.setVisible(self.is_expanded) self.but_diff.setVisible(self.is_expanded) self.but_save.setVisible(self.is_expanded) self.guirange.setVisible(self.is_expanded) height = 78 if self.is_expanded else 40 #self.setMinimumHeight(height) self.setFixedHeight(height) def setGridLayout(self): self.grid = QtGui.QGridLayout() self.grid.addWidget(self.but_help, 0, 0) self.grid.addWidget(self.tit_nbins, 0, 1) self.grid.addWidget(self.edi_nbins, 0, 2) self.grid.addWidget(self.cbox_grid, 0, 3) self.grid.addWidget(self.tit_log, 0, 4) self.grid.addWidget(self.cbox_logx, 0, 5) self.grid.addWidget(self.cbox_logy, 0, 6) self.grid.addWidget(self.but_reset, 0, 7) self.grid.addWidget(self.but_load, 0, 8) self.grid.addWidget(self.but_diff, 0, 9) self.grid.addWidget(self.but_save, 0, 10) self.grid.addWidget(self.but_quit, 0, 11) self.grid.addWidget(self.but_more, 0, 12) self.setLayout(self.grid) def showToolTips(self): self.but_reset.setToolTip('Reset original view') self.but_quit .setToolTip('Quit this GUI') self.but_load .setToolTip('Load image from file') self.but_load .setToolTip('Load subtracting image from file') self.but_save .setToolTip('Save the figure in file') self.but_elog .setToolTip('Send figure to ELog') self.but_help .setToolTip('Click on this button\nand get help') self.cbox_grid.setToolTip('On/Off grid') self.cbox_logx.setToolTip('Log/Linear X scale') self.cbox_logy.setToolTip('Log/Linear Y scale') self.edi_nbins.setToolTip('Edit the number of bins\nfor spectrum [1-1000]') def setFrame(self): self.frame = QtGui.QFrame(self) self.frame.setFrameStyle( QtGui.QFrame.Box | QtGui.QFrame.Sunken ) #Box, Panel | Sunken, Raised self.frame.setLineWidth(0) self.frame.setMidLineWidth(1) self.frame.setGeometry(self.rect()) #self.frame.setVisible(False) def resizeEvent(self, e): #print 'resizeEvent' self.frame.setGeometry(self.rect()) #print 'PlotImgSpeButtons resizeEvent: %s' % str(self.size()) def closeEvent(self, event): # is called for self.close() or when click on "x" #print 'Close application' try : self.guihelp.close() except : pass try : self.parent.close() except : pass def on_but_quit(self): logger.debug('on_but_quit', __name__ ) self.close() def stringOrNone(self,value): if value == None : return 'None' else : return str(value) def intOrNone(self,value): if value == None : return None else : return int(value) def set_buttons(self) : self.cbox_grid.setChecked(self.fig.myGridIsOn) self.cbox_logx.setChecked(self.fig.myLogXIsOn) self.cbox_logy.setChecked(self.fig.myLogYIsOn) self.edi_nbins.setText(self.stringOrNone(self.fig.myNBins)) def on_edit_nbins(self): self.fig.myNBins = int(self.edi_nbins.displayText()) logger.info('Set for spectrum the number of bins ='+str(self.fig.myNBins), __name__ ) self.widgimage.processDraw() def on_but_more(self): logger.debug('on_but_more', __name__ ) if self.is_expanded : self.but_more.setText('&More') self.is_expanded = False else : self.but_more.setText('&Less') self.is_expanded = True self.setPannel() def on_but_reset(self): logger.debug('on_but_reset', __name__ ) self.widgimage.initParameters() self.set_buttons() self.widgimage.on_draw() def on_but_load(self): logger.debug('on_but_load', __name__ ) if self.fexmod : if self.afe_rd.is_new_arr_available() : logger.info('WAIT for image loading', __name__ ) arr = self.afe_rd.get_arr_latest() self.widgimage.set_image_array_new(arr, rot_ang_n90 = self.widgimage.rot_ang_n90, y_is_flip = self.widgimage.y_is_flip) #title='Image from %s...' % self.ifname, logger.info('Image is loaded', __name__ ) return else : logger.info('New image is N/A !', __name__ ) return file_filter = 'Files (*.txt *.data *.npy)\nAll files (*)' path = gu.get_open_fname_through_dialog_box(self, self.ifname, 'Select file with image', filter=file_filter) if path == None or path == '' : logger.info('Loading is cancelled...', __name__ ) return self.ifname = path arr = gu.get_image_array_from_file(path) # dtype=np.float32) if arr is None : return #arr = gu.get_array_from_file(path) # dtype=np.float32) #print 'arr:\n', arr self.widgimage.set_image_array_new(arr, rot_ang_n90 = self.widgimage.rot_ang_n90, y_is_flip = self.widgimage.y_is_flip) def on_but_diff(self): logger.info('on_but_diff', __name__ ) list_of_opts = ['Load from WORK directory', 'Load from CALIB directory', 'Load initial image', 'Cancel' ] selected = gu.selectFromListInPopupMenu(list_of_opts) logger.debug('selected option: %s' % selected, __name__ ) path0 = self.ifname if selected is None : return elif selected == list_of_opts[0] : path0 = fnm.path_dir_work() elif selected == list_of_opts[1] : path0 = fnm.path_to_calib_dir() elif selected == list_of_opts[2] : path0 = self.ifname elif selected == list_of_opts[3] : return else : return file_filter = 'Files (*.txt *.data *.npy)\nAll files (*)' path = gu.get_open_fname_through_dialog_box(self, path0, 'Select file to subtract', filter=file_filter) if path == None or path == '' : logger.info('Loading is cancelled...', __name__ ) return arr_sub = gu.get_image_array_from_file(path) # dtype=np.float32) if arr_sub is None : return if arr_sub.size != self.widgimage.arr.size : msg = 'Subtracted array size: %d is different from current image size: %d. Diff plotting is cancelled.' % \ (arr_sub.size, self.widgimage.arr.size) logger.warning(msg, __name__ ) #print msg return self.widgimage.subtract_from_image_array(arr_sub) def on_but_save(self): logger.debug('on_but_save', __name__ ) path = self.ofname #dir, fname = os.path.split(path) path = str( QtGui.QFileDialog.getSaveFileName(self, caption='Select file to save the plot', directory = path, filter = '*.png, *.eps, *pdf, *.ps' ) ) if path == '' : logger.debug('Saving is cancelled.', __name__ ) return logger.info('Save plot in file: ' + path, __name__ ) self.widgimage.saveFigure(path) def on_but_elog(self): logger.info('Send message to ELog:', __name__ ) path = self.ofname logger.info('1. Save plot in file: ' + path, __name__ ) self.widgimage.saveFigure(path) logger.info('2. Submit message with plot to ELog', __name__ ) wdialog = GUIELogPostingDialog (self, fname=path) resp=wdialog.exec_() def on_cbox_logx(self): logger.info('Set log10 for X scale', __name__ ) self.fig.myLogXIsOn = self.cbox_logx.isChecked() self.fig.myZmin = None self.fig.myZmax = None self.widgimage.processDraw() def on_cbox_logy(self): logger.info('Set log10 for Y scale', __name__ ) self.fig.myLogYIsOn = self.cbox_logy.isChecked() self.fig.myZmin = None self.fig.myZmax = None self.widgimage.processDraw() def on_cbox_grid(self): logger.info('On/Off grid.', __name__ ) self.fig.myGridIsOn = self.cbox_grid.isChecked() self.widgimage.processDraw() def on_but_help(self): logger.debug('on_but_help - is not implemented yet...', __name__ ) try : self.guihelp.close() del self.guihelp except : self.guihelp = GUIHelp(None, self.help_msg) self.guihelp.setMinimumSize(620, 200) self.guihelp.move(self.parentWidget().pos().__add__(QtCore.QPoint(250,60))) self.guihelp.show() def help_message(self): msg = 'Mouse control functions:' msg += '\nZoom-in image: left mouse click, move, and release in another image position.' msg += '\nMiddle mouse button click on image - restores full size image' msg += '\nLeft/right mouse click on histogram or color bar - sets min/max amplitude.' msg += '\nMiddle mouse click on histogram or color bar - resets amplitude limits to default.' msg += '\n"Reset" button - resets all parameters to default values.' return msg def popup_confirmation_box(self): """Pop-up box for help""" msg = QtGui.QMessageBox(self, windowTitle='Help for interactive plot', text='This is a help', #standardButtons=QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel) standardButtons=QtGui.QMessageBox.Close) msg.setDefaultButton(msg.Close) clicked = msg.exec_()
class PlotImgSpeButtons(QtGui.QWidget): """Buttons for interactive plot of the image and spectrum for 2-d array.""" #---------------- # Constructor -- #---------------- def __init__(self, parent=None, widgimage=None, ifname='', ofname='./fig.png', help_msg=None, expand=False, fexmod=False, verb=False): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('GUI of buttons') self.setFrame() self.parent = parent self.ifname = ifname self.ofname = ofname self.is_expanded = expand self.guirange = None self.fexmod = fexmod self.verb = verb self.widgimage = widgimage if widgimage is None: self.fig = self # need it to pass pars self.fig.myNBins = 40 self.fig.myGridIsOn = False self.fig.myLogXIsOn = False self.fig.myLogYIsOn = False self.fig.myZmin = None self.fig.myZmax = None else: self.fig = widgimage.fig if help_msg == None: self.help_msg = self.help_message() else: self.help_msg = help_msg self.but_more = QtGui.QPushButton('&More') self.but_reset = QtGui.QPushButton('&Reset') self.but_help = QtGui.QPushButton('&Help') self.but_load = QtGui.QPushButton('Load') self.but_diff = QtGui.QPushButton('Diff') self.but_save = QtGui.QPushButton('&Save') self.but_elog = QtGui.QPushButton('&ELog') #u'\u2192 &ELog' self.but_quit = QtGui.QPushButton('&Close') self.cbox_grid = QtGui.QCheckBox('&Grid') self.cbox_logx = QtGui.QCheckBox('&X') self.cbox_logy = QtGui.QCheckBox('&Y') self.tit_log = QtGui.QLabel('Log:') self.tit_nbins = QtGui.QLabel('N bins:') self.edi_nbins = QtGui.QLineEdit(self.stringOrNone(self.fig.myNBins)) self.set_buttons() self.setIcons() width = 60 self.edi_nbins.setFixedWidth(width) #self.but_reset.setFixedWidth(width) #self.but_help .setFixedWidth(width) #self.but_save .setFixedWidth(width) #self.but_elog .setFixedWidth(width) #self.but_quit .setFixedWidth(width) self.edi_nbins.setValidator(QtGui.QIntValidator(1, 1000, self)) self.but_help.setStyleSheet(cp.styleButtonGood) self.but_more.setStyleSheet(cp.styleButton) self.but_reset.setStyleSheet(cp.styleButton) self.but_load.setStyleSheet(cp.styleButton) self.but_diff.setStyleSheet(cp.styleButton) self.but_save.setStyleSheet(cp.styleButton) self.but_quit.setStyleSheet(cp.styleButtonBad) self.connect(self.but_more, QtCore.SIGNAL('clicked()'), self.on_but_more) self.connect(self.but_help, QtCore.SIGNAL('clicked()'), self.on_but_help) self.connect(self.but_reset, QtCore.SIGNAL('clicked()'), self.on_but_reset) self.connect(self.but_load, QtCore.SIGNAL('clicked()'), self.on_but_load) self.connect(self.but_diff, QtCore.SIGNAL('clicked()'), self.on_but_diff) self.connect(self.but_save, QtCore.SIGNAL('clicked()'), self.on_but_save) self.connect(self.but_elog, QtCore.SIGNAL('clicked()'), self.on_but_elog) self.connect(self.but_quit, QtCore.SIGNAL('clicked()'), self.on_but_quit) self.connect(self.cbox_grid, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_grid) self.connect(self.cbox_logx, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_logx) self.connect(self.cbox_logy, QtCore.SIGNAL('stateChanged(int)'), self.on_cbox_logy) self.connect(self.edi_nbins, QtCore.SIGNAL('editingFinished ()'), self.on_edit_nbins) #self.setGridLayout() self.setPanelLayout() self.showToolTips() #self.setFixedHeight(50) pbits = 377 if self.verb else 0 self.afe_rd = ArrFileExchange(prefix=self.ifname, rblen=3, print_bits=pbits) def setIcons(self): cp.setIcons() self.but_elog.setIcon(cp.icon_mail_forward) self.but_load.setIcon(cp.icon_browser) # icon_contents) self.but_diff.setIcon(cp.icon_minus) # icon_contents) self.but_save.setIcon(cp.icon_save) self.but_quit.setIcon(cp.icon_exit) self.but_help.setIcon(cp.icon_help) self.but_reset.setIcon(cp.icon_reset) def setPanelLayoutV1(self): self.hbox = QtGui.QHBoxLayout() self.hbox.addWidget(self.but_help) self.hbox.addWidget(self.tit_nbins) self.hbox.addWidget(self.edi_nbins) self.hbox.addWidget(self.cbox_grid) self.hbox.addWidget(self.tit_log) self.hbox.addWidget(self.cbox_logx) self.hbox.addWidget(self.cbox_logy) self.hbox.addWidget(self.but_reset) self.hbox.addStretch(1) self.hbox.addWidget(self.but_load) self.hbox.addWidget(self.but_diff) self.hbox.addWidget(self.but_save) self.hbox.addWidget(self.but_elog) self.hbox.addWidget(self.but_quit) self.hbox.addWidget(self.but_more) self.setLayout(self.hbox) self.setPannel() def setPanelLayout(self): self.hbox1 = QtGui.QHBoxLayout() self.hbox1.addWidget(self.but_help) self.hbox1.addWidget(self.tit_nbins) self.hbox1.addWidget(self.edi_nbins) self.hbox1.addWidget(self.cbox_grid) self.hbox1.addWidget(self.tit_log) self.hbox1.addWidget(self.cbox_logx) self.hbox1.addWidget(self.cbox_logy) self.hbox1.addWidget(self.but_reset) self.hbox1.addStretch(1) self.hbox1.addWidget(self.but_elog) self.hbox1.addWidget(self.but_quit) self.hbox1.addWidget(self.but_more) self.guirange = GUIRangeIntensity(self, None, None, txt_from='Spec range', txt_to=':') self.hbox2 = QtGui.QHBoxLayout() self.hbox2.addWidget(self.but_load) self.hbox2.addWidget(self.but_diff) self.hbox2.addWidget(self.guirange) self.hbox2.addStretch(1) self.hbox2.addWidget(self.but_save) self.vbox = QtGui.QVBoxLayout() self.vbox.addLayout(self.hbox2) self.vbox.addLayout(self.hbox1) self.vbox.addStretch(1) self.setLayout(self.vbox) self.setContentsMargins(QtCore.QMargins(0, -5, 0, -5)) self.setPannel() def setZMin(self, zmin=None): if self.guirange is None: return self.guirange.setParamFrom(zmin) def setZMax(self, zmin=None): if self.guirange is None: return self.guirange.setParamTo(zmax) def setZRange(self, str_from=None, str_to=None): if self.guirange is None: return self.guirange.setParams(str_from, str_to) def setPannel(self): self.but_quit.setVisible(False) self.but_elog.setVisible(False) #self.but_help.setVisible(False) self.but_load.setVisible(self.is_expanded) self.but_diff.setVisible(self.is_expanded) self.but_save.setVisible(self.is_expanded) self.guirange.setVisible(self.is_expanded) height = 78 if self.is_expanded else 40 #self.setMinimumHeight(height) self.setFixedHeight(height) def setGridLayout(self): self.grid = QtGui.QGridLayout() self.grid.addWidget(self.but_help, 0, 0) self.grid.addWidget(self.tit_nbins, 0, 1) self.grid.addWidget(self.edi_nbins, 0, 2) self.grid.addWidget(self.cbox_grid, 0, 3) self.grid.addWidget(self.tit_log, 0, 4) self.grid.addWidget(self.cbox_logx, 0, 5) self.grid.addWidget(self.cbox_logy, 0, 6) self.grid.addWidget(self.but_reset, 0, 7) self.grid.addWidget(self.but_load, 0, 8) self.grid.addWidget(self.but_diff, 0, 9) self.grid.addWidget(self.but_save, 0, 10) self.grid.addWidget(self.but_quit, 0, 11) self.grid.addWidget(self.but_more, 0, 12) self.setLayout(self.grid) def showToolTips(self): self.but_reset.setToolTip('Reset original view') self.but_quit.setToolTip('Quit this GUI') self.but_load.setToolTip('Load image from file') self.but_load.setToolTip('Load subtracting image from file') self.but_save.setToolTip('Save the figure in file') self.but_elog.setToolTip('Send figure to ELog') self.but_help.setToolTip('Click on this button\nand get help') self.cbox_grid.setToolTip('On/Off grid') self.cbox_logx.setToolTip('Log/Linear X scale') self.cbox_logy.setToolTip('Log/Linear Y scale') self.edi_nbins.setToolTip( 'Edit the number of bins\nfor spectrum [1-1000]') def setFrame(self): self.frame = QtGui.QFrame(self) self.frame.setFrameStyle( QtGui.QFrame.Box | QtGui.QFrame.Sunken) #Box, Panel | Sunken, Raised self.frame.setLineWidth(0) self.frame.setMidLineWidth(1) self.frame.setGeometry(self.rect()) #self.frame.setVisible(False) def resizeEvent(self, e): #print 'resizeEvent' self.frame.setGeometry(self.rect()) #print 'PlotImgSpeButtons resizeEvent: %s' % str(self.size()) def closeEvent(self, event): # is called for self.close() or when click on "x" #print 'Close application' try: self.guihelp.close() except: pass try: self.parent.close() except: pass def on_but_quit(self): logger.debug('on_but_quit', __name__) self.close() def stringOrNone(self, value): if value == None: return 'None' else: return str(value) def intOrNone(self, value): if value == None: return None else: return int(value) def set_buttons(self): self.cbox_grid.setChecked(self.fig.myGridIsOn) self.cbox_logx.setChecked(self.fig.myLogXIsOn) self.cbox_logy.setChecked(self.fig.myLogYIsOn) self.edi_nbins.setText(self.stringOrNone(self.fig.myNBins)) def on_edit_nbins(self): self.fig.myNBins = int(self.edi_nbins.displayText()) logger.info( 'Set for spectrum the number of bins =' + str(self.fig.myNBins), __name__) self.widgimage.processDraw() def on_but_more(self): logger.debug('on_but_more', __name__) if self.is_expanded: self.but_more.setText('&More') self.is_expanded = False else: self.but_more.setText('&Less') self.is_expanded = True self.setPannel() def on_but_reset(self): logger.debug('on_but_reset', __name__) self.widgimage.initParameters() self.set_buttons() self.widgimage.on_draw() def on_but_load(self): logger.debug('on_but_load', __name__) if self.fexmod: if self.afe_rd.is_new_arr_available(): logger.info('WAIT for image loading', __name__) arr = self.afe_rd.get_arr_latest() self.widgimage.set_image_array_new( arr, rot_ang_n90=self.widgimage.rot_ang_n90, y_is_flip=self.widgimage.y_is_flip) #title='Image from %s...' % self.ifname, logger.info('Image is loaded', __name__) return else: logger.info('New image is N/A !', __name__) return path = gu.get_open_fname_through_dialog_box(self, self.ifname, 'Select file with image', filter='*.txt *.npy') if path == None or path == '': logger.info('Loading is cancelled...', __name__) return self.ifname = path arr = gu.get_image_array_from_file(path) # dtype=np.float32) if arr is None: return #arr = gu.get_array_from_file(path) # dtype=np.float32) #print 'arr:\n', arr self.widgimage.set_image_array_new( arr, rot_ang_n90=self.widgimage.rot_ang_n90, y_is_flip=self.widgimage.y_is_flip) def on_but_diff(self): logger.info('on_but_diff', __name__) list_of_opts = [ 'Load from WORK directory', 'Load from CALIB directory', 'Load initial image', 'Cancel' ] selected = gu.selectFromListInPopupMenu(list_of_opts) logger.debug('selected option: %s' % selected, __name__) path0 = self.ifname if selected is None: return elif selected == list_of_opts[0]: path0 = fnm.path_dir_work() elif selected == list_of_opts[1]: path0 = fnm.path_to_calib_dir() elif selected == list_of_opts[2]: path0 = self.ifname elif selected == list_of_opts[3]: return else: return file_filter = 'Files (*.txt *.data *.npy)\nAll files (*)' path = gu.get_open_fname_through_dialog_box(self, path0, 'Select file to subtract', filter=file_filter) if path == None or path == '': logger.info('Loading is cancelled...', __name__) return arr_sub = gu.get_image_array_from_file(path) # dtype=np.float32) if arr_sub is None: return if arr_sub.size != self.widgimage.arr.size: msg = 'Subtracted array size: %d is different from current image size: %d. Diff plotting is cancelled.' % \ (arr_sub.size, self.widgimage.arr.size) logger.warning(msg, __name__) #print msg return self.widgimage.subtract_from_image_array(arr_sub) def on_but_save(self): logger.debug('on_but_save', __name__) path = self.ofname #dir, fname = os.path.split(path) path = str( QtGui.QFileDialog.getSaveFileName( self, caption='Select file to save the plot', directory=path, filter='*.png, *.eps, *pdf, *.ps')) if path == '': logger.debug('Saving is cancelled.', __name__) return logger.info('Save plot in file: ' + path, __name__) self.widgimage.saveFigure(path) def on_but_elog(self): logger.info('Send message to ELog:', __name__) path = self.ofname logger.info('1. Save plot in file: ' + path, __name__) self.widgimage.saveFigure(path) logger.info('2. Submit message with plot to ELog', __name__) wdialog = GUIELogPostingDialog(self, fname=path) resp = wdialog.exec_() def on_cbox_logx(self): logger.info('Set log10 for X scale', __name__) self.fig.myLogXIsOn = self.cbox_logx.isChecked() self.fig.myZmin = None self.fig.myZmax = None self.widgimage.processDraw() def on_cbox_logy(self): logger.info('Set log10 for Y scale', __name__) self.fig.myLogYIsOn = self.cbox_logy.isChecked() self.fig.myZmin = None self.fig.myZmax = None self.widgimage.processDraw() def on_cbox_grid(self): logger.info('On/Off grid.', __name__) self.fig.myGridIsOn = self.cbox_grid.isChecked() self.widgimage.processDraw() def on_but_help(self): logger.debug('on_but_help - is not implemented yet...', __name__) try: self.guihelp.close() del self.guihelp except: self.guihelp = GUIHelp(None, self.help_msg) self.guihelp.setMinimumSize(620, 200) self.guihelp.move(self.parentWidget().pos().__add__( QtCore.QPoint(250, 60))) self.guihelp.show() def help_message(self): msg = 'Mouse control functions:' msg += '\nZoom-in image: left mouse click, move, and release in another image position.' msg += '\nMiddle mouse button click on image - restores full size image' msg += '\nLeft/right mouse click on histogram or color bar - sets min/max amplitude.' msg += '\nMiddle mouse click on histogram or color bar - resets amplitude limits to default.' msg += '\n"Reset" button - resets all parameters to default values.' return msg def popup_confirmation_box(self): """Pop-up box for help""" msg = QtGui.QMessageBox( self, windowTitle='Help for interactive plot', text='This is a help', #standardButtons=QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel) standardButtons=QtGui.QMessageBox.Close) msg.setDefaultButton(msg.Close) clicked = msg.exec_()
def __init__(self, parent=None, widgimage=None, ifname=None, ofname='./roi-mask.png', mfname='./roi-mask', \ xyc=None, lw=2, col='b', picker=5, verb=False, ccd_rot_n90=0, y_is_flip=False, fexmod=False): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('GUI of buttons') self.setFrame() self.parent = parent self.ifname = ifname self.ofname = ofname self.mfname = mfname self.fexmod = fexmod self.verb = verb self.ccd_rot_n90 = ccd_rot_n90 self.y_is_flip = y_is_flip self.mfname_img = ifname self.mfname_mask = self.mfname + '.txt' self.mfname_objs = self.mfname + '-shape-objs.txt' self.widgimage = widgimage if self.widgimage != None : self.fig = self.widgimage.fig self.axes = self.widgimage.get_axim() if xyc != None : self.fig.my_xyc = xyc else : self.fig.my_xyc = self.widgimage.get_xy_img_center() if self.verb : print 'Image center: ', self.fig.my_xyc self.set_lines = DragObjectSet(self.fig, self.axes, DragLine, useKeyboard=False, lw=lw, col=col, picker=picker) self.set_wedges = DragObjectSet(self.fig, self.axes, DragWedge, useKeyboard=False, lw=lw, col=col, picker=picker, use_xyc=True) self.set_rectangles = DragObjectSet(self.fig, self.axes, DragRectangle, useKeyboard=False, lw=lw, col=col, picker=picker) self.set_circles = DragObjectSet(self.fig, self.axes, DragCircle, useKeyboard=False, lw=lw, col=col, picker=picker) #self.set_centers = DragObjectSet(self.fig, self.axes, DragCenter, useKeyboard=False, lw=lw, col=col, picker=picker, is_single_obj=True) self.set_polygons = DragObjectSet(self.fig, self.axes, DragPolygon, useKeyboard=False, lw=lw, col=col, picker=picker) self.disconnect_all() else : # for self-testing mode only self.fig = self # in order to get rid of crash... self.list_of_modes = ['Zoom', 'Add', 'Move', 'Select', 'Remove'] self.list_of_forms = ['Rectangle', 'Wedge', 'Circle', 'Line', 'Polygon'] #, 'Center'] #self.list_of_io_tits = ['Load Image', 'Load Forms', 'Save Forms', 'Save Mask', 'Save Inv-M', 'Print Forms', 'Clear Forms', 'Excg-Load', 'Excg-Save'] self.list_of_io_tits = ['Load Image', 'Load Forms', 'Save Forms', 'Save Mask', 'Save Inv-M', 'Print Forms', 'Clear Forms'] self.list_of_io_tips = ['Load image for \ndisplay from file', 'Load forms of masked \nregions from file', 'Save forms of masked \nregions in text file', 'Save mask as a 2D array \nof ones and zeros in text file', 'Save inversed-mask as a 2D array\n of ones and zeros in text file', 'Prints parameters of \ncurrently entered forms', 'Clear all forms from the image' ] #'Load image from file with pre-defined name', #'Save mask in file with pre-defined name' #self.list_of_fnames = [self.mfname_img, self.mfname_objs, self.mfname_objs, self.mfname_mask, self.mfname_mask, None, None, self.mfname_img, self.mfname_mask] self.list_of_fnames = [self.mfname_img, self.mfname_objs, self.mfname_objs, self.mfname_mask, self.mfname_mask, None, None] zoom_tip_msg = 'Zoom mode for image and spactrom.' + \ '\nZoom-in image: left mouse button click-drug-release.' + \ '\nZoom-in spectrum: left/right mouse button click for min/max limit.' + \ '\nReset to full size: middle mouse button click.' self.list_of_buts = [] self.list_of_io_buts = [] self.fig.my_mode = self.list_of_modes[0] #self.current_form = self.list_of_forms[0] self.current_form = None self.tit_modes = QtGui.QLabel('Modes:') self.tit_forms = QtGui.QLabel('Forms:') self.tit_io = QtGui.QLabel('I/O:') self.tit_status = QtGui.QLabel('Status:') self.lab_status = QtGui.QPushButton('Good') #self.lab_status = QtGui.QLabel('Good') #self.lab_status = QtGui.QTextEdit() self.vbox = QtGui.QVBoxLayout() self.vbox.addWidget(self.tit_forms) for form in self.list_of_forms : but = QtGui.QPushButton(form) self.list_of_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_but) but.setToolTip('Select form to draw on image \nas ROI or masked region') self.vbox.addStretch(1) self.vbox.addWidget(self.tit_modes) for mode in self.list_of_modes : but = QtGui.QPushButton(mode) self.list_of_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_but) if mode == 'Zoom' : but.setToolTip(zoom_tip_msg) elif mode == 'Select' : but.setToolTip('Select forms for inversed masking. \nSelected forms are marked by different color') else : but.setToolTip('Select mode of manipulation with form') self.vbox.addStretch(1) self.vbox.addWidget(self.tit_io) for io_tit, io_tip in zip(self.list_of_io_tits, self.list_of_io_tips) : but = QtGui.QPushButton(io_tit) self.list_of_io_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_io_but) but.setToolTip(io_tip) self.vbox.addStretch(1) self.vbox.addWidget(self.tit_status) self.vbox.addWidget(self.lab_status) self.setLayout(self.vbox) self.showToolTips() self.setStyle() self.setStatus() pbits = 377 if self.verb else 0 self.afe_rd = ArrFileExchange(prefix=self.ifname, rblen=3, print_bits=pbits) self.afe_wr = ArrFileExchange(prefix=self.mfname, rblen=3, print_bits=pbits)
class MaskEditorButtons (QtGui.QWidget) : """Buttons for interactive plot of the image and spectrum for 2-d array.""" #---------------- # Constructor -- #---------------- def __init__(self, parent=None, widgimage=None, ifname=None, ofname='./roi-mask.png', mfname='./roi-mask', \ xyc=None, lw=2, col='b', picker=5, verb=False, ccd_rot_n90=0, y_is_flip=False, fexmod=False): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('GUI of buttons') self.setFrame() self.parent = parent self.ifname = ifname self.ofname = ofname self.mfname = mfname self.fexmod = fexmod self.verb = verb self.ccd_rot_n90 = ccd_rot_n90 self.y_is_flip = y_is_flip self.mfname_img = ifname self.mfname_mask = self.mfname + '.txt' self.mfname_objs = self.mfname + '-shape-objs.txt' self.widgimage = widgimage if self.widgimage != None : self.fig = self.widgimage.fig self.axes = self.widgimage.get_axim() if xyc != None : self.fig.my_xyc = xyc else : self.fig.my_xyc = self.widgimage.get_xy_img_center() if self.verb : print 'Image center: ', self.fig.my_xyc self.set_lines = DragObjectSet(self.fig, self.axes, DragLine, useKeyboard=False, lw=lw, col=col, picker=picker) self.set_wedges = DragObjectSet(self.fig, self.axes, DragWedge, useKeyboard=False, lw=lw, col=col, picker=picker, use_xyc=True) self.set_rectangles = DragObjectSet(self.fig, self.axes, DragRectangle, useKeyboard=False, lw=lw, col=col, picker=picker) self.set_circles = DragObjectSet(self.fig, self.axes, DragCircle, useKeyboard=False, lw=lw, col=col, picker=picker) #self.set_centers = DragObjectSet(self.fig, self.axes, DragCenter, useKeyboard=False, lw=lw, col=col, picker=picker, is_single_obj=True) self.set_polygons = DragObjectSet(self.fig, self.axes, DragPolygon, useKeyboard=False, lw=lw, col=col, picker=picker) self.disconnect_all() else : # for self-testing mode only self.fig = self # in order to get rid of crash... self.list_of_modes = ['Zoom', 'Add', 'Move', 'Select', 'Remove'] self.list_of_forms = ['Rectangle', 'Wedge', 'Circle', 'Line', 'Polygon'] #, 'Center'] #self.list_of_io_tits = ['Load Image', 'Load Forms', 'Save Forms', 'Save Mask', 'Save Inv-M', 'Print Forms', 'Clear Forms', 'Excg-Load', 'Excg-Save'] self.list_of_io_tits = ['Load Image', 'Load Forms', 'Save Forms', 'Save Mask', 'Save Inv-M', 'Print Forms', 'Clear Forms'] self.list_of_io_tips = ['Load image for \ndisplay from file', 'Load forms of masked \nregions from file', 'Save forms of masked \nregions in text file', 'Save mask as a 2D array \nof ones and zeros in text file', 'Save inversed-mask as a 2D array\n of ones and zeros in text file', 'Prints parameters of \ncurrently entered forms', 'Clear all forms from the image' ] #'Load image from file with pre-defined name', #'Save mask in file with pre-defined name' #self.list_of_fnames = [self.mfname_img, self.mfname_objs, self.mfname_objs, self.mfname_mask, self.mfname_mask, None, None, self.mfname_img, self.mfname_mask] self.list_of_fnames = [self.mfname_img, self.mfname_objs, self.mfname_objs, self.mfname_mask, self.mfname_mask, None, None] zoom_tip_msg = 'Zoom mode for image and spactrom.' + \ '\nZoom-in image: left mouse button click-drug-release.' + \ '\nZoom-in spectrum: left/right mouse button click for min/max limit.' + \ '\nReset to full size: middle mouse button click.' self.list_of_buts = [] self.list_of_io_buts = [] self.fig.my_mode = self.list_of_modes[0] #self.current_form = self.list_of_forms[0] self.current_form = None self.tit_modes = QtGui.QLabel('Modes:') self.tit_forms = QtGui.QLabel('Forms:') self.tit_io = QtGui.QLabel('I/O:') self.tit_status = QtGui.QLabel('Status:') self.lab_status = QtGui.QPushButton('Good') #self.lab_status = QtGui.QLabel('Good') #self.lab_status = QtGui.QTextEdit() self.vbox = QtGui.QVBoxLayout() self.vbox.addWidget(self.tit_forms) for form in self.list_of_forms : but = QtGui.QPushButton(form) self.list_of_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_but) but.setToolTip('Select form to draw on image \nas ROI or masked region') self.vbox.addStretch(1) self.vbox.addWidget(self.tit_modes) for mode in self.list_of_modes : but = QtGui.QPushButton(mode) self.list_of_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_but) if mode == 'Zoom' : but.setToolTip(zoom_tip_msg) elif mode == 'Select' : but.setToolTip('Select forms for inversed masking. \nSelected forms are marked by different color') else : but.setToolTip('Select mode of manipulation with form') self.vbox.addStretch(1) self.vbox.addWidget(self.tit_io) for io_tit, io_tip in zip(self.list_of_io_tits, self.list_of_io_tips) : but = QtGui.QPushButton(io_tit) self.list_of_io_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_io_but) but.setToolTip(io_tip) self.vbox.addStretch(1) self.vbox.addWidget(self.tit_status) self.vbox.addWidget(self.lab_status) self.setLayout(self.vbox) self.showToolTips() self.setStyle() self.setStatus() pbits = 377 if self.verb else 0 self.afe_rd = ArrFileExchange(prefix=self.ifname, rblen=3, print_bits=pbits) self.afe_wr = ArrFileExchange(prefix=self.mfname, rblen=3, print_bits=pbits) #def updateCenter(self,x,y): # print 'updateCenter, x,y=', x, y def showToolTips(self): #self.but_remove.setToolTip('Remove') pass def setFrame(self): self.frame = QtGui.QFrame(self) self.frame.setFrameStyle( QtGui.QFrame.Box | QtGui.QFrame.Sunken ) #Box, Panel | Sunken, Raised self.frame.setLineWidth(0) self.frame.setMidLineWidth(1) self.frame.setGeometry(self.rect()) #self.frame.setVisible(False) def setStyle(self): self .setFixedWidth(100) #self .setStyleSheet (cp.styleBkgd) self.tit_modes .setStyleSheet (cp.styleLabel) self.tit_forms .setStyleSheet (cp.styleLabel) self.tit_io .setStyleSheet (cp.styleLabel) self.tit_status.setStyleSheet (cp.styleLabel) self.tit_modes .setAlignment (QtCore.Qt.AlignCenter) self.tit_forms .setAlignment (QtCore.Qt.AlignCenter) self.tit_io .setAlignment (QtCore.Qt.AlignCenter) self.tit_status.setAlignment (QtCore.Qt.AlignCenter) self.lab_status.setFixedHeight(50) self.setButtonStyle() def setButtonStyle(self): for but in self.list_of_buts : but_text = str(but.text()) if but_text == self.fig.my_mode : but.setStyleSheet (cp.styleButtonGood) elif but_text == self.current_form : but.setStyleSheet (cp.styleButtonGood) else : but.setStyleSheet (cp.styleButton) #self.but_help .setStyleSheet (cp.styleButtonGood) #self.but_quit .setStyleSheet (cp.styleButtonBad) #self.edi_nbins.setValidator(QtGui.QIntValidator(1,1000,self)) def resizeEvent(self, e): self.frame.setGeometry(self.rect()) def closeEvent(self, event): # is called for self.close() or when click on "x" #print 'Close application' try : self.guihelp.close() except : pass #try : self.parent.close() #except : pass def on_but_quit(self): logger.debug('on_but_quit', __name__ ) self.close() #def set_buttons(self) : # self.cbox_grid.setChecked(self.fig.myGridIsOn) # self.cbox_log .setChecked(self.fig.myLogIsOn) # self.edi_nbins.setText(self.stringOrNone(self.fig.myNBins)) def get_pushed_but(self): for but in self.list_of_buts : if but.hasFocus() : return but def disconnect_all(self): self.set_lines .disconnect_objs() self.set_rectangles.disconnect_objs() self.set_circles .disconnect_objs() self.set_wedges .disconnect_objs() self.set_polygons .disconnect_objs() #self.set_centers .disconnect_objs() def connect_all(self): self.set_lines .connect_objs() self.set_rectangles.connect_objs() self.set_circles .connect_objs() self.set_wedges .connect_objs() self.set_polygons .connect_objs() #self.set_centers .connect_objs() def disconnect_form(self, form='Line'): if form == 'Line' : self.set_lines .disconnect_objs() elif form == 'Rectangle' : self.set_rectangles.disconnect_objs() elif form == 'Circle' : self.set_circles .disconnect_objs() elif form == 'Wedge' : self.set_wedges .disconnect_objs() elif form == 'Polygon' : self.set_polygons .disconnect_objs() #elif form == 'Center' : self.set_centers .disconnect_objs() else : pass def connect_form(self, form='Line'): if form == 'Line' : self.set_lines .connect_objs() elif form == 'Rectangle' : self.set_rectangles.connect_objs() elif form == 'Circle' : self.set_circles .connect_objs() elif form == 'Wedge' : self.set_wedges .connect_objs() elif form == 'Polygon' : self.set_polygons .connect_objs() #elif form == 'Center' : self.set_centers .connect_objs() else : pass def add_obj(self, str_of_pars) : """Add object when load the forms from file""" obj_type = str_of_pars.split(' ',1)[0] if obj_type == 'Line' : self.set_lines .add_obj_for_str_of_pars(str_of_pars) elif obj_type == 'Rectangle' : self.set_rectangles.add_obj_for_str_of_pars(str_of_pars) elif obj_type == 'Circle' : self.set_circles .add_obj_for_str_of_pars(str_of_pars) elif obj_type == 'Wedge' : self.set_wedges .add_obj_for_str_of_pars(str_of_pars) elif obj_type == 'Polygon' : self.set_polygons .add_obj_for_str_of_pars(str_of_pars) #elif obj_type == 'Center' : self.set_centers .add_obj_for_str_of_pars(str_of_pars) else : pass #def on_but_old(self): def on_but(self): but = self.get_pushed_but() msg = 'on_but ' + str(but.text()) logger.debug(msg, __name__ ) #if self.verb : print msg but_text = str(but.text()) #Set MODE if but_text in self.list_of_modes : self.fig.my_mode = but_text # Sets mode for Drag objects if self.fig.my_mode == 'Zoom' : self.widgimage.connectZoomMode() self.disconnect_all() self.current_form = None else : self.widgimage.disconnectZoomMode() #Set FORM if but_text in self.list_of_forms : self.disconnect_all() self.current_form = but_text self.connect_form(self.current_form) # Connect objects for NEW form self.setButtonStyle() self.setStatus() def on_but_new(self): #def on_but(self): but = self.get_pushed_but() msg = 'on_but ' + str(but.text()) logger.debug(msg, __name__ ) #if self.verb : print msg #Set MODE but_text = str(but.text()) if but_text in self.list_of_modes : self.fig.my_mode = but_text # Sets mode for Drag objects if self.fig.my_mode == 'Zoom' : self.widgimage.connectZoomMode() self.disconnect_all() self.current_form = None elif self.fig.my_mode == 'Add' : self.widgimage.disconnectZoomMode() self.disconnect_all() #self.current_form = None else : self.widgimage.disconnectZoomMode() self.connect_all() self.current_form = None #Set FORM if but_text in self.list_of_forms : if self.current_form == None : self.disconnect_all() else : self.disconnect_form(self.current_form) # Disconnect objects for OLD form self.current_form = but_text self.connect_form(self.current_form) # Connect objects for NEW form self.setButtonStyle() self.setStatus() def get_pushed_io_but(self): for ind, but in enumerate(self.list_of_io_buts) : if but.hasFocus() : return but, ind, self.list_of_fnames[ind] def on_io_but(self): but, ind, fname = self.get_pushed_io_but() but_text = str(but.text()) msg = but_text + ', default file name: ' + str(fname) logger.debug(msg, __name__ ) if self.verb : print msg if fname == None : path0 = '.' else : path0 = fname if but_text == self.list_of_io_tits[0] : # 'Load Img' if self.fexmod : self.exchange_image_load() return self.setStatus(1, 'Waiting\nfor input...') path = gu.get_open_fname_through_dialog_box(self, path0, but_text, filter='*.txt *.npy') if path == None : self.setStatus() return self.setStatus(2, 'WAIT!\nLoad image') arr = gu.get_array_from_file(path) self.parent.set_image_array_new(arr, title='Image from '+path ) self.setStatus(0, 'Image \nloaded') if but_text == self.list_of_io_tits[1] : # 'Load Forms' self.setStatus(1, 'Waiting\nfor input') path = gu.get_open_fname_through_dialog_box(self, path0, but_text, filter='*.txt') if path == None : self.setStatus() return msg='Load shaping-objects for mask from file: ' + path logger.debug(msg, __name__ ) if self.verb : print msg #text = gu.get_text_file_content(path) self.setStatus(2,'WAIT\nLoad forms') f=open(path,'r') for str_of_pars in f : self.add_obj(str_of_pars.rstrip('\n')) f.close() self.setStatus(0, 'Forms\nloaded') if but_text == self.list_of_io_tits[2] : # 'Save Forms' #self.parent.set_image_array_new( get_array2d_for_test(), title='New array' ) if self.list_of_objs_for_mask_is_empty() : return self.setStatus(1, 'Waiting\nfor input...') path = gu.get_save_fname_through_dialog_box(self, path0, but_text, filter='*.txt') if path == None : self.setStatus() return msg='Save shaping-objects for mask in file: ' + path logger.debug(msg, __name__ ) self.setStatus(2, 'WAIT!\nSave forms') f=open(path,'w') for obj in self.get_list_of_objs_for_mask() : str_of_pars = obj.get_str_of_pars() if self.verb : print str_of_pars f.write(str_of_pars + '\n') f.close() self.setStatus(0, 'Forms\nsaved') if but_text == self.list_of_io_tits[3] : # 'Save Mask' if self.list_of_objs_for_mask_is_empty() : print 'WARNING: Empty mask is NOT saved!' self.setStatus(2, 'Empty mask\nNOT saved!') return self.setStatus(2, 'WAIT!\nMask is\nprocessing') self.enforceStatusRepaint() #print 'WAIT for mask processing' mask_total = self.get_mask_total() self.parent.set_image_array_new(mask_total, title='Mask') if self.fexmod : self.exchange_mask_save(mask_total) return self.setStatus(1, 'Waiting\nfor input...') path = gu.get_save_fname_through_dialog_box(self, path0, but_text, filter='*.txt') if path == None : self.setStatus() return np.savetxt(path, mask_total, fmt='%1i', delimiter=' ') self.setStatus(0, 'Mask\nis saved') if but_text == self.list_of_io_tits[4] : # 'Save Inv-Mask' if self.list_of_objs_for_mask_is_empty() : print 'WARNING: Empty mask is NOT saved!' self.setStatus(2, 'Empty mask\nNOT saved!') return self.setStatus(2, 'Wait!\nInv-mask is\nprocessing') self.enforceStatusRepaint() mask_total = ~self.get_mask_total() self.parent.set_image_array_new(mask_total, title='Inverse Mask') if self.fexmod : self.exchange_mask_save(mask_total) return self.setStatus(1, 'Waiting\nfor input') path = gu.get_save_fname_through_dialog_box(self, path0, but_text, filter='*.txt') if path == None : self.setStatus() return np.savetxt(path, mask_total, fmt='%1i', delimiter=' ') self.setStatus(0, 'Mask\nis ready') if but_text == self.list_of_io_tits[5] : # 'Print Forms' #self.parent.set_image_array_new( get_array2d_for_test(), title='New array' ) msg = '\nForm parameters for composition of the mask' if self.verb : print msg logger.info(msg, __name__ ) for obj in self.get_list_of_objs_for_mask() : str_of_pars = obj.get_str_of_pars() if self.verb : print str_of_pars logger.info(str_of_pars) if but_text == self.list_of_io_tits[6] : # 'Clear Forms' self.setStatus(2, 'WAIT!\nremoving\nforms') self.set_lines .remove_all_objs_from_img_by_call() self.set_rectangles.remove_all_objs_from_img_by_call() self.set_circles .remove_all_objs_from_img_by_call() self.set_wedges .remove_all_objs_from_img_by_call() self.set_polygons .remove_all_objs_from_img_by_call() self.setStatus(0, 'Forms\nremoved') def exchange_image_load(self): if self.afe_rd.is_new_arr_available() : self.setStatus(2, 'WAIT!\nLoad image') arr = self.afe_rd.get_arr_latest() self.parent.set_image_array_new(arr, title='Image from %s...' % self.ifname ) self.setStatus(0, 'Image is\nloaded') else : self.setStatus(1, 'New image\nis N/A !') return def exchange_mask_save(self, mask): self.setStatus(2, 'WAIT!\nSave mask') self.afe_wr.save_arr(mask) self.setStatus(0, 'Mask\nis saved') def get_mask_total(self): shape = self.widgimage.get_img_shape() if self.verb : print 'get_img_shape():', shape self.mask_total = None for i, obj in enumerate(self.get_list_of_objs_for_mask()) : if obj.isSelected : continue # Loop over ROI-type objects if self.mask_total == None : self.mask_total = obj.get_obj_mask(shape) else : self.mask_total = np.logical_or(self.mask_total, obj.get_obj_mask(shape)) msg = 'mask for ROI-type object %i is ready...' % (i) logger.info(msg, __name__ ) for i, obj in enumerate(self.get_list_of_objs_for_mask()) : if not obj.isSelected : continue # Loop over inversed objects if self.mask_total == None : self.mask_total = obj.get_obj_mask(shape) else : self.mask_total = np.logical_and(self.mask_total, obj.get_obj_mask(shape)) msg = 'mask for inversed object %i is ready...' % (i) logger.info(msg, __name__ ) if self.y_is_flip : self.mask_total = np.flipud(gu.arr_rot_n90(self.mask_total, self.ccd_rot_n90)) else : rot_ang = self.ccd_rot_n90 if self.ccd_rot_n90 == 90 : rot_ang=270 if self.ccd_rot_n90 == 270 : rot_ang=90 self.mask_total = gu.arr_rot_n90(self.mask_total, rot_ang) return self.mask_total def list_of_objs_for_mask_is_empty(self): if len(self.get_list_of_objs_for_mask()) == 0 : logger.warning('List of objects for mask IS EMPTY!', __name__ ) return True else : return False def get_list_of_objs_for_mask(self): return self.set_rectangles.get_list_of_objs() \ +self.set_wedges .get_list_of_objs() \ +self.set_circles .get_list_of_objs() \ +self.set_lines .get_list_of_objs() \ +self.set_polygons .get_list_of_objs() #+self.set_centers def help_message(self): msg = 'Mouse control functions:' msg += '\nZoom-in image: left mouse click, move, and release in another image position.' msg += '\nMiddle mouse button click on image - restores full size image' msg += '\nLeft/right mouse click on histogram or color bar - sets min/max amplitude.' msg += '\nMiddle mouse click on histogram or color bar - resets amplitude limits to default.' msg += '\n"Reset" button - resets all parameters to default values.' return msg def popup_confirmation_box(self): """Pop-up box for help""" msg = QtGui.QMessageBox(self, windowTitle='Help for interactive plot', text='This is a help', #standardButtons=QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel) standardButtons=QtGui.QMessageBox.Close) msg.setDefaultButton(msg.Close) clicked = msg.exec_() #if clicked == QtGui.QMessageBox.Save : # logger.debug('Saving is requested', __name__) #elif clicked == QtGui.QMessageBox.Discard : # logger.debug('Discard is requested', __name__) #else : # logger.debug('Cancel is requested', __name__) #return clicked def setStatus(self, ind=None, msg='') : if ind == None and msg == '' : self.stat_msg = self.fig.my_mode if self.current_form != None : self.stat_msg += '\n' + str(self.current_form) self.stat_ind = 0 if self.fig.my_mode == 'Zoom' and self.current_form != None : self.stat_ind = 2 self.stat_msg = 'What to do\nwith\n' + self.current_form + '?' elif self.fig.my_mode != 'Zoom' and self.current_form == None : self.stat_ind = 2 self.stat_msg = self.fig.my_mode + '\nwhat form?' else : self.stat_ind = ind self.stat_msg = msg #self.lab_status.clear() if self.stat_ind == 0 : self.lab_status.setStyleSheet(cp.styleButtonGood) # cp.styleStatusGood) elif self.stat_ind == 1 : self.lab_status.setStyleSheet(cp.styleButtonWarning) # cp.styleStatusWarning) elif self.stat_ind == 2 : self.lab_status.setStyleSheet(cp.styleButtonBad) # cp.styleStatusAlarm) self.lab_status.setText(self.stat_msg) def enforceStatusRepaint(self) : self.lab_status.repaint() self.repaint()
def __init__(self, parent=None, widgimage=None, ifname=None, ofname='./roi-mask.png', mfname='./roi-mask', \ xyc=None, lw=2, col='b', picker=5, verb=False, ccd_rot_n90=0, y_is_flip=False, fexmod=False): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('GUI of buttons') self.setFrame() self.parent = parent self.ifname = ifname self.ofname = ofname self.mfname = mfname self.fexmod = fexmod self.verb = verb self.ccd_rot_n90 = ccd_rot_n90 self.y_is_flip = y_is_flip self.mfname_img = ifname self.mfname_mask = self.mfname + '.txt' self.mfname_objs = self.mfname + '-shape-objs.txt' self.widgimage = widgimage if self.widgimage != None: self.fig = self.widgimage.fig self.axes = self.widgimage.get_axim() if xyc != None: self.fig.my_xyc = xyc else: self.fig.my_xyc = self.widgimage.get_xy_img_center() if self.verb: print 'Image center: ', self.fig.my_xyc self.set_lines = DragObjectSet(self.fig, self.axes, DragLine, useKeyboard=False, lw=lw, col=col, picker=picker) self.set_wedges = DragObjectSet(self.fig, self.axes, DragWedge, useKeyboard=False, lw=lw, col=col, picker=picker, use_xyc=True) self.set_rectangles = DragObjectSet(self.fig, self.axes, DragRectangle, useKeyboard=False, lw=lw, col=col, picker=picker) self.set_circles = DragObjectSet(self.fig, self.axes, DragCircle, useKeyboard=False, lw=lw, col=col, picker=picker) #self.set_centers = DragObjectSet(self.fig, self.axes, DragCenter, useKeyboard=False, lw=lw, col=col, picker=picker, is_single_obj=True) self.set_polygons = DragObjectSet(self.fig, self.axes, DragPolygon, useKeyboard=False, lw=lw, col=col, picker=picker) self.disconnect_all() else: # for self-testing mode only self.fig = self # in order to get rid of crash... self.list_of_modes = ['Zoom', 'Add', 'Move', 'Select', 'Remove'] self.list_of_forms = [ 'Rectangle', 'Wedge', 'Circle', 'Line', 'Polygon' ] #, 'Center'] #self.list_of_io_tits = ['Load Image', 'Load Forms', 'Save Forms', 'Save Mask', 'Save Inv-M', 'Print Forms', 'Clear Forms', 'Excg-Load', 'Excg-Save'] self.list_of_io_tits = [ 'Load Image', 'Load Forms', 'Save Forms', 'Save Mask', 'Save Inv-M', 'Print Forms', 'Clear Forms' ] self.list_of_io_tips = [ 'Load image for \ndisplay from file', 'Load forms of masked \nregions from file', 'Save forms of masked \nregions in text file', 'Save mask as a 2D array \nof ones and zeros in text file', 'Save inversed-mask as a 2D array\n of ones and zeros in text file', 'Prints parameters of \ncurrently entered forms', 'Clear all forms from the image' ] #'Load image from file with pre-defined name', #'Save mask in file with pre-defined name' #self.list_of_fnames = [self.mfname_img, self.mfname_objs, self.mfname_objs, self.mfname_mask, self.mfname_mask, None, None, self.mfname_img, self.mfname_mask] self.list_of_fnames = [ self.mfname_img, self.mfname_objs, self.mfname_objs, self.mfname_mask, self.mfname_mask, None, None ] zoom_tip_msg = 'Zoom mode for image and spactrom.' + \ '\nZoom-in image: left mouse button click-drug-release.' + \ '\nZoom-in spectrum: left/right mouse button click for min/max limit.' + \ '\nReset to full size: middle mouse button click.' self.list_of_buts = [] self.list_of_io_buts = [] self.fig.my_mode = self.list_of_modes[0] #self.current_form = self.list_of_forms[0] self.current_form = None self.tit_modes = QtGui.QLabel('Modes:') self.tit_forms = QtGui.QLabel('Forms:') self.tit_io = QtGui.QLabel('I/O:') self.tit_status = QtGui.QLabel('Status:') self.lab_status = QtGui.QPushButton('Good') #self.lab_status = QtGui.QLabel('Good') #self.lab_status = QtGui.QTextEdit() self.vbox = QtGui.QVBoxLayout() self.vbox.addWidget(self.tit_forms) for form in self.list_of_forms: but = QtGui.QPushButton(form) self.list_of_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_but) but.setToolTip( 'Select form to draw on image \nas ROI or masked region') self.vbox.addStretch(1) self.vbox.addWidget(self.tit_modes) for mode in self.list_of_modes: but = QtGui.QPushButton(mode) self.list_of_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_but) if mode == 'Zoom': but.setToolTip(zoom_tip_msg) elif mode == 'Select': but.setToolTip( 'Select forms for inversed masking. \nSelected forms are marked by different color' ) else: but.setToolTip('Select mode of manipulation with form') self.vbox.addStretch(1) self.vbox.addWidget(self.tit_io) for io_tit, io_tip in zip(self.list_of_io_tits, self.list_of_io_tips): but = QtGui.QPushButton(io_tit) self.list_of_io_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_io_but) but.setToolTip(io_tip) self.vbox.addStretch(1) self.vbox.addWidget(self.tit_status) self.vbox.addWidget(self.lab_status) self.setLayout(self.vbox) self.showToolTips() self.setStyle() self.setStatus() pbits = 377 if self.verb else 0 self.afe_rd = ArrFileExchange(prefix=self.ifname, rblen=3, print_bits=pbits) self.afe_wr = ArrFileExchange(prefix=self.mfname, rblen=3, print_bits=pbits)
class MaskEditorButtons(QtGui.QWidget): """Buttons for interactive plot of the image and spectrum for 2-d array.""" #---------------- # Constructor -- #---------------- def __init__(self, parent=None, widgimage=None, ifname=None, ofname='./roi-mask.png', mfname='./roi-mask', \ xyc=None, lw=2, col='b', picker=5, verb=False, ccd_rot_n90=0, y_is_flip=False, fexmod=False): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('GUI of buttons') self.setFrame() self.parent = parent self.ifname = ifname self.ofname = ofname self.mfname = mfname self.fexmod = fexmod self.verb = verb self.ccd_rot_n90 = ccd_rot_n90 self.y_is_flip = y_is_flip self.mfname_img = ifname self.mfname_mask = self.mfname + '.txt' self.mfname_objs = self.mfname + '-shape-objs.txt' self.widgimage = widgimage if self.widgimage != None: self.fig = self.widgimage.fig self.axes = self.widgimage.get_axim() if xyc != None: self.fig.my_xyc = xyc else: self.fig.my_xyc = self.widgimage.get_xy_img_center() if self.verb: print 'Image center: ', self.fig.my_xyc self.set_lines = DragObjectSet(self.fig, self.axes, DragLine, useKeyboard=False, lw=lw, col=col, picker=picker) self.set_wedges = DragObjectSet(self.fig, self.axes, DragWedge, useKeyboard=False, lw=lw, col=col, picker=picker, use_xyc=True) self.set_rectangles = DragObjectSet(self.fig, self.axes, DragRectangle, useKeyboard=False, lw=lw, col=col, picker=picker) self.set_circles = DragObjectSet(self.fig, self.axes, DragCircle, useKeyboard=False, lw=lw, col=col, picker=picker) #self.set_centers = DragObjectSet(self.fig, self.axes, DragCenter, useKeyboard=False, lw=lw, col=col, picker=picker, is_single_obj=True) self.set_polygons = DragObjectSet(self.fig, self.axes, DragPolygon, useKeyboard=False, lw=lw, col=col, picker=picker) self.disconnect_all() else: # for self-testing mode only self.fig = self # in order to get rid of crash... self.list_of_modes = ['Zoom', 'Add', 'Move', 'Select', 'Remove'] self.list_of_forms = [ 'Rectangle', 'Wedge', 'Circle', 'Line', 'Polygon' ] #, 'Center'] #self.list_of_io_tits = ['Load Image', 'Load Forms', 'Save Forms', 'Save Mask', 'Save Inv-M', 'Print Forms', 'Clear Forms', 'Excg-Load', 'Excg-Save'] self.list_of_io_tits = [ 'Load Image', 'Load Forms', 'Save Forms', 'Save Mask', 'Save Inv-M', 'Print Forms', 'Clear Forms' ] self.list_of_io_tips = [ 'Load image for \ndisplay from file', 'Load forms of masked \nregions from file', 'Save forms of masked \nregions in text file', 'Save mask as a 2D array \nof ones and zeros in text file', 'Save inversed-mask as a 2D array\n of ones and zeros in text file', 'Prints parameters of \ncurrently entered forms', 'Clear all forms from the image' ] #'Load image from file with pre-defined name', #'Save mask in file with pre-defined name' #self.list_of_fnames = [self.mfname_img, self.mfname_objs, self.mfname_objs, self.mfname_mask, self.mfname_mask, None, None, self.mfname_img, self.mfname_mask] self.list_of_fnames = [ self.mfname_img, self.mfname_objs, self.mfname_objs, self.mfname_mask, self.mfname_mask, None, None ] zoom_tip_msg = 'Zoom mode for image and spactrom.' + \ '\nZoom-in image: left mouse button click-drug-release.' + \ '\nZoom-in spectrum: left/right mouse button click for min/max limit.' + \ '\nReset to full size: middle mouse button click.' self.list_of_buts = [] self.list_of_io_buts = [] self.fig.my_mode = self.list_of_modes[0] #self.current_form = self.list_of_forms[0] self.current_form = None self.tit_modes = QtGui.QLabel('Modes:') self.tit_forms = QtGui.QLabel('Forms:') self.tit_io = QtGui.QLabel('I/O:') self.tit_status = QtGui.QLabel('Status:') self.lab_status = QtGui.QPushButton('Good') #self.lab_status = QtGui.QLabel('Good') #self.lab_status = QtGui.QTextEdit() self.vbox = QtGui.QVBoxLayout() self.vbox.addWidget(self.tit_forms) for form in self.list_of_forms: but = QtGui.QPushButton(form) self.list_of_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_but) but.setToolTip( 'Select form to draw on image \nas ROI or masked region') self.vbox.addStretch(1) self.vbox.addWidget(self.tit_modes) for mode in self.list_of_modes: but = QtGui.QPushButton(mode) self.list_of_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_but) if mode == 'Zoom': but.setToolTip(zoom_tip_msg) elif mode == 'Select': but.setToolTip( 'Select forms for inversed masking. \nSelected forms are marked by different color' ) else: but.setToolTip('Select mode of manipulation with form') self.vbox.addStretch(1) self.vbox.addWidget(self.tit_io) for io_tit, io_tip in zip(self.list_of_io_tits, self.list_of_io_tips): but = QtGui.QPushButton(io_tit) self.list_of_io_buts.append(but) self.vbox.addWidget(but) self.connect(but, QtCore.SIGNAL('clicked()'), self.on_io_but) but.setToolTip(io_tip) self.vbox.addStretch(1) self.vbox.addWidget(self.tit_status) self.vbox.addWidget(self.lab_status) self.setLayout(self.vbox) self.showToolTips() self.setStyle() self.setStatus() pbits = 377 if self.verb else 0 self.afe_rd = ArrFileExchange(prefix=self.ifname, rblen=3, print_bits=pbits) self.afe_wr = ArrFileExchange(prefix=self.mfname, rblen=3, print_bits=pbits) #def updateCenter(self,x,y): # print 'updateCenter, x,y=', x, y def showToolTips(self): #self.but_remove.setToolTip('Remove') pass def setFrame(self): self.frame = QtGui.QFrame(self) self.frame.setFrameStyle( QtGui.QFrame.Box | QtGui.QFrame.Sunken) #Box, Panel | Sunken, Raised self.frame.setLineWidth(0) self.frame.setMidLineWidth(1) self.frame.setGeometry(self.rect()) #self.frame.setVisible(False) def setStyle(self): self.setFixedWidth(100) #self .setStyleSheet (cp.styleBkgd) self.tit_modes.setStyleSheet(cp.styleLabel) self.tit_forms.setStyleSheet(cp.styleLabel) self.tit_io.setStyleSheet(cp.styleLabel) self.tit_status.setStyleSheet(cp.styleLabel) self.tit_modes.setAlignment(QtCore.Qt.AlignCenter) self.tit_forms.setAlignment(QtCore.Qt.AlignCenter) self.tit_io.setAlignment(QtCore.Qt.AlignCenter) self.tit_status.setAlignment(QtCore.Qt.AlignCenter) self.lab_status.setFixedHeight(50) self.setButtonStyle() def setButtonStyle(self): for but in self.list_of_buts: but_text = str(but.text()) if but_text == self.fig.my_mode: but.setStyleSheet(cp.styleButtonGood) elif but_text == self.current_form: but.setStyleSheet(cp.styleButtonGood) else: but.setStyleSheet(cp.styleButton) #self.but_help .setStyleSheet (cp.styleButtonGood) #self.but_quit .setStyleSheet (cp.styleButtonBad) #self.edi_nbins.setValidator(QtGui.QIntValidator(1,1000,self)) def resizeEvent(self, e): self.frame.setGeometry(self.rect()) def closeEvent(self, event): # is called for self.close() or when click on "x" #print 'Close application' try: self.guihelp.close() except: pass #try : self.parent.close() #except : pass def on_but_quit(self): logger.debug('on_but_quit', __name__) self.close() #def set_buttons(self) : # self.cbox_grid.setChecked(self.fig.myGridIsOn) # self.cbox_log .setChecked(self.fig.myLogIsOn) # self.edi_nbins.setText(self.stringOrNone(self.fig.myNBins)) def get_pushed_but(self): for but in self.list_of_buts: if but.hasFocus(): return but def disconnect_all(self): self.set_lines.disconnect_objs() self.set_rectangles.disconnect_objs() self.set_circles.disconnect_objs() self.set_wedges.disconnect_objs() self.set_polygons.disconnect_objs() #self.set_centers .disconnect_objs() def connect_all(self): self.set_lines.connect_objs() self.set_rectangles.connect_objs() self.set_circles.connect_objs() self.set_wedges.connect_objs() self.set_polygons.connect_objs() #self.set_centers .connect_objs() def disconnect_form(self, form='Line'): if form == 'Line': self.set_lines.disconnect_objs() elif form == 'Rectangle': self.set_rectangles.disconnect_objs() elif form == 'Circle': self.set_circles.disconnect_objs() elif form == 'Wedge': self.set_wedges.disconnect_objs() elif form == 'Polygon': self.set_polygons.disconnect_objs() #elif form == 'Center' : self.set_centers .disconnect_objs() else: pass def connect_form(self, form='Line'): if form == 'Line': self.set_lines.connect_objs() elif form == 'Rectangle': self.set_rectangles.connect_objs() elif form == 'Circle': self.set_circles.connect_objs() elif form == 'Wedge': self.set_wedges.connect_objs() elif form == 'Polygon': self.set_polygons.connect_objs() #elif form == 'Center' : self.set_centers .connect_objs() else: pass def add_obj(self, str_of_pars): """Add object when load the forms from file""" obj_type = str_of_pars.split(' ', 1)[0] if obj_type == 'Line': self.set_lines.add_obj_for_str_of_pars(str_of_pars) elif obj_type == 'Rectangle': self.set_rectangles.add_obj_for_str_of_pars(str_of_pars) elif obj_type == 'Circle': self.set_circles.add_obj_for_str_of_pars(str_of_pars) elif obj_type == 'Wedge': self.set_wedges.add_obj_for_str_of_pars(str_of_pars) elif obj_type == 'Polygon': self.set_polygons.add_obj_for_str_of_pars(str_of_pars) #elif obj_type == 'Center' : self.set_centers .add_obj_for_str_of_pars(str_of_pars) else: pass #def on_but_old(self): def on_but(self): but = self.get_pushed_but() msg = 'on_but ' + str(but.text()) logger.debug(msg, __name__) #if self.verb : print msg but_text = str(but.text()) #Set MODE if but_text in self.list_of_modes: self.fig.my_mode = but_text # Sets mode for Drag objects if self.fig.my_mode == 'Zoom': self.widgimage.connectZoomMode() self.disconnect_all() self.current_form = None else: self.widgimage.disconnectZoomMode() #Set FORM if but_text in self.list_of_forms: self.disconnect_all() self.current_form = but_text self.connect_form( self.current_form) # Connect objects for NEW form self.setButtonStyle() self.setStatus() def on_but_new(self): #def on_but(self): but = self.get_pushed_but() msg = 'on_but ' + str(but.text()) logger.debug(msg, __name__) #if self.verb : print msg #Set MODE but_text = str(but.text()) if but_text in self.list_of_modes: self.fig.my_mode = but_text # Sets mode for Drag objects if self.fig.my_mode == 'Zoom': self.widgimage.connectZoomMode() self.disconnect_all() self.current_form = None elif self.fig.my_mode == 'Add': self.widgimage.disconnectZoomMode() self.disconnect_all() #self.current_form = None else: self.widgimage.disconnectZoomMode() self.connect_all() self.current_form = None #Set FORM if but_text in self.list_of_forms: if self.current_form == None: self.disconnect_all() else: self.disconnect_form( self.current_form) # Disconnect objects for OLD form self.current_form = but_text self.connect_form( self.current_form) # Connect objects for NEW form self.setButtonStyle() self.setStatus() def get_pushed_io_but(self): for ind, but in enumerate(self.list_of_io_buts): if but.hasFocus(): return but, ind, self.list_of_fnames[ind] def on_io_but(self): but, ind, fname = self.get_pushed_io_but() but_text = str(but.text()) msg = but_text + ', default file name: ' + str(fname) logger.debug(msg, __name__) if self.verb: print msg if fname == None: path0 = '.' else: path0 = fname if but_text == self.list_of_io_tits[0]: # 'Load Img' if self.fexmod: self.exchange_image_load() return self.setStatus(1, 'Waiting\nfor input...') path = gu.get_open_fname_through_dialog_box(self, path0, but_text, filter='*.txt *.npy') if path == None: self.setStatus() return self.setStatus(2, 'WAIT!\nLoad image') arr = gu.get_array_from_file(path) self.parent.set_image_array_new(arr, title='Image from ' + path) self.setStatus(0, 'Image \nloaded') if but_text == self.list_of_io_tits[1]: # 'Load Forms' self.setStatus(1, 'Waiting\nfor input') path = gu.get_open_fname_through_dialog_box(self, path0, but_text, filter='*.txt') if path == None: self.setStatus() return msg = 'Load shaping-objects for mask from file: ' + path logger.debug(msg, __name__) if self.verb: print msg #text = gu.get_text_file_content(path) self.setStatus(2, 'WAIT\nLoad forms') f = open(path, 'r') for str_of_pars in f: self.add_obj(str_of_pars.rstrip('\n')) f.close() self.setStatus(0, 'Forms\nloaded') if but_text == self.list_of_io_tits[2]: # 'Save Forms' #self.parent.set_image_array_new( get_array2d_for_test(), title='New array' ) if self.list_of_objs_for_mask_is_empty(): return self.setStatus(1, 'Waiting\nfor input...') path = gu.get_save_fname_through_dialog_box(self, path0, but_text, filter='*.txt') if path == None: self.setStatus() return msg = 'Save shaping-objects for mask in file: ' + path logger.debug(msg, __name__) self.setStatus(2, 'WAIT!\nSave forms') f = open(path, 'w') for obj in self.get_list_of_objs_for_mask(): str_of_pars = obj.get_str_of_pars() if self.verb: print str_of_pars f.write(str_of_pars + '\n') f.close() self.setStatus(0, 'Forms\nsaved') if but_text == self.list_of_io_tits[3]: # 'Save Mask' if self.list_of_objs_for_mask_is_empty(): print 'WARNING: Empty mask is NOT saved!' self.setStatus(2, 'Empty mask\nNOT saved!') return self.setStatus(2, 'WAIT!\nMask is\nprocessing') self.enforceStatusRepaint() #print 'WAIT for mask processing' mask_total = self.get_mask_total() self.parent.set_image_array_new(mask_total, title='Mask') if self.fexmod: self.exchange_mask_save(mask_total) return self.setStatus(1, 'Waiting\nfor input...') path = gu.get_save_fname_through_dialog_box(self, path0, but_text, filter='*.txt') if path == None: self.setStatus() return np.savetxt(path, mask_total, fmt='%1i', delimiter=' ') self.setStatus(0, 'Mask\nis saved') if but_text == self.list_of_io_tits[4]: # 'Save Inv-Mask' if self.list_of_objs_for_mask_is_empty(): print 'WARNING: Empty mask is NOT saved!' self.setStatus(2, 'Empty mask\nNOT saved!') return self.setStatus(2, 'Wait!\nInv-mask is\nprocessing') self.enforceStatusRepaint() mask_total = ~self.get_mask_total() self.parent.set_image_array_new(mask_total, title='Inverse Mask') if self.fexmod: self.exchange_mask_save(mask_total) return self.setStatus(1, 'Waiting\nfor input') path = gu.get_save_fname_through_dialog_box(self, path0, but_text, filter='*.txt') if path == None: self.setStatus() return np.savetxt(path, mask_total, fmt='%1i', delimiter=' ') self.setStatus(0, 'Mask\nis ready') if but_text == self.list_of_io_tits[5]: # 'Print Forms' #self.parent.set_image_array_new( get_array2d_for_test(), title='New array' ) msg = '\nForm parameters for composition of the mask' if self.verb: print msg logger.info(msg, __name__) for obj in self.get_list_of_objs_for_mask(): str_of_pars = obj.get_str_of_pars() if self.verb: print str_of_pars logger.info(str_of_pars) if but_text == self.list_of_io_tits[6]: # 'Clear Forms' self.setStatus(2, 'WAIT!\nremoving\nforms') self.set_lines.remove_all_objs_from_img_by_call() self.set_rectangles.remove_all_objs_from_img_by_call() self.set_circles.remove_all_objs_from_img_by_call() self.set_wedges.remove_all_objs_from_img_by_call() self.set_polygons.remove_all_objs_from_img_by_call() self.setStatus(0, 'Forms\nremoved') def exchange_image_load(self): if self.afe_rd.is_new_arr_available(): self.setStatus(2, 'WAIT!\nLoad image') arr = self.afe_rd.get_arr_latest() self.parent.set_image_array_new(arr, title='Image from %s...' % self.ifname) self.setStatus(0, 'Image is\nloaded') else: self.setStatus(1, 'New image\nis N/A !') return def exchange_mask_save(self, mask): self.setStatus(2, 'WAIT!\nSave mask') self.afe_wr.save_arr(mask) self.setStatus(0, 'Mask\nis saved') def get_mask_total(self): shape = self.widgimage.get_img_shape() if self.verb: print 'get_img_shape():', shape self.mask_total = None for i, obj in enumerate(self.get_list_of_objs_for_mask()): if obj.isSelected: continue # Loop over ROI-type objects if self.mask_total == None: self.mask_total = obj.get_obj_mask(shape) else: self.mask_total = np.logical_or(self.mask_total, obj.get_obj_mask(shape)) msg = 'mask for ROI-type object %i is ready...' % (i) logger.info(msg, __name__) for i, obj in enumerate(self.get_list_of_objs_for_mask()): if not obj.isSelected: continue # Loop over inversed objects if self.mask_total == None: self.mask_total = obj.get_obj_mask(shape) else: self.mask_total = np.logical_and(self.mask_total, obj.get_obj_mask(shape)) msg = 'mask for inversed object %i is ready...' % (i) logger.info(msg, __name__) if self.y_is_flip: self.mask_total = np.flipud( gu.arr_rot_n90(self.mask_total, self.ccd_rot_n90)) else: rot_ang = self.ccd_rot_n90 if self.ccd_rot_n90 == 90: rot_ang = 270 if self.ccd_rot_n90 == 270: rot_ang = 90 self.mask_total = gu.arr_rot_n90(self.mask_total, rot_ang) return self.mask_total def list_of_objs_for_mask_is_empty(self): if len(self.get_list_of_objs_for_mask()) == 0: logger.warning('List of objects for mask IS EMPTY!', __name__) return True else: return False def get_list_of_objs_for_mask(self): return self.set_rectangles.get_list_of_objs() \ +self.set_wedges .get_list_of_objs() \ +self.set_circles .get_list_of_objs() \ +self.set_lines .get_list_of_objs() \ +self.set_polygons .get_list_of_objs() #+self.set_centers def help_message(self): msg = 'Mouse control functions:' msg += '\nZoom-in image: left mouse click, move, and release in another image position.' msg += '\nMiddle mouse button click on image - restores full size image' msg += '\nLeft/right mouse click on histogram or color bar - sets min/max amplitude.' msg += '\nMiddle mouse click on histogram or color bar - resets amplitude limits to default.' msg += '\n"Reset" button - resets all parameters to default values.' return msg def popup_confirmation_box(self): """Pop-up box for help""" msg = QtGui.QMessageBox( self, windowTitle='Help for interactive plot', text='This is a help', #standardButtons=QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard | QtGui.QMessageBox.Cancel) standardButtons=QtGui.QMessageBox.Close) msg.setDefaultButton(msg.Close) clicked = msg.exec_() #if clicked == QtGui.QMessageBox.Save : # logger.debug('Saving is requested', __name__) #elif clicked == QtGui.QMessageBox.Discard : # logger.debug('Discard is requested', __name__) #else : # logger.debug('Cancel is requested', __name__) #return clicked def setStatus(self, ind=None, msg=''): if ind == None and msg == '': self.stat_msg = self.fig.my_mode if self.current_form != None: self.stat_msg += '\n' + str(self.current_form) self.stat_ind = 0 if self.fig.my_mode == 'Zoom' and self.current_form != None: self.stat_ind = 2 self.stat_msg = 'What to do\nwith\n' + self.current_form + '?' elif self.fig.my_mode != 'Zoom' and self.current_form == None: self.stat_ind = 2 self.stat_msg = self.fig.my_mode + '\nwhat form?' else: self.stat_ind = ind self.stat_msg = msg #self.lab_status.clear() if self.stat_ind == 0: self.lab_status.setStyleSheet( cp.styleButtonGood) # cp.styleStatusGood) elif self.stat_ind == 1: self.lab_status.setStyleSheet( cp.styleButtonWarning) # cp.styleStatusWarning) elif self.stat_ind == 2: self.lab_status.setStyleSheet( cp.styleButtonBad) # cp.styleStatusAlarm) self.lab_status.setText(self.stat_msg) def enforceStatusRepaint(self): self.lab_status.repaint() self.repaint()