class MainWindow(QMainWindow, Ui_MainWindow): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ # calling base initializers super(MainWindow, self).__init__(parent) # calling base setupUi for ui configuration self.setupUi(self) # setting up the gui self.setup_gui() def setup_gui(self): """ """ self.glWidget = GLWidget(parent = self.gridWidget_4, width = 1508, height = 713, bgcolor = (.5, .5, 0.9), enable_light = False) self.gridLayout_4.addWidget(self.glWidget) #for now, pbExtCluster will be invisible self.pbExtCluster.setVisible(False) # adding the editing items to ROI table # double spinbox for x,y and z coordinates self.dspbxcoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(3, 1, self.dspbxcoord) self.dspbycoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(4, 1, self.dspbycoord) self.dspbzcoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(5, 1, self.dspbzcoord) self.spbrad = QtGui.QSpinBox() self.tblROI.setCellWidget(6, 1, self.spbrad) # define method ROI self.roimethod = 1 #tractome inside # color button self.colorlist = [QtGui.QColor('red'), QtGui.QColor('blue'), QtGui.QColor('green'), QtGui.QColor('yellow'), QtGui.QColor('cyan'), QtGui.QColor('black')] self.btncolor = QtGui.QPushButton() self.tblROI.setCellWidget(2, 1, self.btncolor) self.btncolor.setAutoFillBackground(True) # connect button with QColorDialog self.connect(self.btncolor, QtCore.SIGNAL("clicked()"), self.on_btncolor_clicked) # visibility checkbox self.chkbvis = QtGui.QCheckBox() self.chkbvis.setCheckState(QtCore.Qt.Checked) self.connect(self.chkbvis, QtCore.SIGNAL("stateChanged(int)"), self.on_chkbvis_stateChanged) self.tblROI.setCellWidget(1, 1, self.chkbvis) # self.show_hide_rows(True) # creating the main Scene self.tractome= Tractome() self.add_scene(self.tractome.scene) def changenumstreamlines_handler(self, n_stream): """ """ if (n_stream< 1e5) and (n_stream>= 50): default = 50 else: default = n_stream self.spbRecluster.setValue(default) self.spbRecluster.setRange(1, n_stream) self.hSlReCluster.setValue(default) self.hSlReCluster.setMinimum(1) self.hSlReCluster.setMaximum(min(150, n_stream)) self.tblTract.item(1, 1).setText(str(n_stream)) def changenumrepresentatives_handler(self, n_rep): """ """ self.tblTract.item(2, 1).setText(str(n_rep)) def changenumknnextend_handler(self, changenn): """ """ if changenn is True: self.hSlExtclust.setValue(0) def on_dspbxcoord_valueChanged(self, value): """ """ self.tractome.update_ROI(self.tblROI.item(0, 1).text(), coordx = value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_dspbycoord_valueChanged(self, value): """ """ self.tractome.update_ROI(self.tblROI.item(0, 1).text(), coordy = value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_dspbzcoord_valueChanged(self, value): self.tractome.update_ROI(self.tblROI.item(0, 1).text(), coordz = value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_spbrad_valueChanged(self, value): """ """ self.tractome.update_ROI(self.tblROI.item(0, 1).text(), radius=value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_chkbvis_stateChanged(self, state): """ Shows or hides the ROI if the visibility checkbox is checked or not correspondingly. """ self.tractome.show_hide_actor(self.tblROI.item(0, 1).text(), state) self.glWidget.updateGL() @Slot(QtGui.QTreeWidgetItem, int) def on_treeObject_itemClicked(self, item, column): """ If the item selected is a ROI, the corresponding information will be shown in the tableROI. """ name = str(item.text(0)) xcoord, ycoord, zcoord, radius, color= self.tractome.information_from_ROI(name) index= self.treeObject.indexFromItem(item) self.activeROI = index.row() self.disconnect(self.tblROI, QtCore.SIGNAL("itemChanged(QtGui.QTableWidgetItem)"), self.on_tblROI_itemChanged) self.updateROItable(name, xcoord, ycoord, zcoord, radius, color) self.connect(self.tblROI, QtCore.SIGNAL("itemChanged(QtGui.QTableWidgetItem)"), self.on_tblROI_itemChanged) def on_btncolor_clicked(self): """ """ color = QtGui.QColorDialog().getColor() self.btncolor.setStyleSheet( u'background-color:%s' % color.name()) self.tractome.update_ROI(self.tblROI.item(0, 1).text(), color = color.getRgbF()) @Slot(int) def on_chkbShowTract_stateChanged(self, state): """ Shows or hides the tractography if the Checkbox is checked or not correspondingly """ self.tractome.show_hide_actor('Bundle Picker', state) self.glWidget.updateGL() @Slot(int) def on_chkbShowStruct_stateChanged(self, state): """ Shows or hides the structural image if the Checkbox is checked or not correspondingly """ self.tractome.show_hide_actor('Volume Slicer', state) self.glWidget.updateGL() # @Slot(bool) # def on_rdbInsSphere_toggled(self, checked): # """ # Use method of Tractome inside sphere to compute the ROI # """ # if checked: # self.roimethod = 1 # self.tractome.update_ROI(self.tblROI.item(0, 1).text(), method = self.roimethod, rebuild= True) # if len(self.list_chkROIS)>0: # self.tractome.compute_streamlines_ROIS() # @Slot(bool) # def on_rdbtrackvis_toggled(self, checked): # """ # Use method of Trackvis to compute the ROI # """ # if checked: # self.roimethod = 0 # self.tractome.update_ROI(self.tblROI.item(0, 1).text(), method = self.roimethod, rebuild= True) # if len(self.list_chkROIS)>0: # self.tractome.compute_streamlines_ROIS() @Slot(int) def on_spbRecluster_valueChanged(self, p0): """ Update slider Recluster """ self.hSlReCluster.setValue(p0) @Slot(int) def on_hSlReCluster_valueChanged(self, value): """ Update spbRecluster """ self.spbRecluster.setValue(value) @Slot() def on_pbRecluster_clicked(self): """ Call re-cluster function from tractome and update values of possible number of clusters for related objects. """ self.tractome.recluster(self.spbRecluster.value()) self.hSlExtclust.setValue(0) self.glWidget.updateGL() @Slot(int) def on_spbExtClust_valueChanged(self, p0): """ Update hSlExtclust and call method that computes kdtree-query. """ self.hSlExtclust.setValue(p0) try: self.tractome.compute_kqueries(p0) self.glWidget.updateGL() except TractomeError,e: msgBox = QtGui.QMessageBox.critical(self, "Tractome Message", ''.join(e.args))
class MainWindow(QMainWindow, Ui_MainWindow): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ # calling base initializers super(MainWindow, self).__init__(parent) # calling base setupUi for ui configuration self.setupUi(self) # setting up the gui self.setup_gui() def setup_gui(self): """ """ self.glWidget = GLWidget(parent = self.gridWidget_4, width = 1508, height = 713, bgcolor = (.5, .5, 0.9), enable_light = False) self.gridLayout_4.addWidget(self.glWidget) # adding the editing items to ROI table # double spinbox for x,y and z coordinates self.dspbxcoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(3, 1, self.dspbxcoord) self.dspbycoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(4, 1, self.dspbycoord) self.dspbzcoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(5, 1, self.dspbzcoord) self.spbrad = QtGui.QSpinBox() self.tblROI.setCellWidget(6, 1, self.spbrad) # define method ROI self.roimethod = 1 #tractome inside # color button self.colorlist = [QtGui.QColor('red'), QtGui.QColor('blue'), QtGui.QColor('green'), QtGui.QColor('yellow'), QtGui.QColor('cyan'), QtGui.QColor('black')] self.btncolor = QtGui.QPushButton() self.tblROI.setCellWidget(2, 1, self.btncolor) self.btncolor.setAutoFillBackground(True) # connect button with QColorDialog self.connect(self.btncolor, QtCore.SIGNAL("clicked()"), self.on_btncolor_clicked) # visibility checkbox self.chkbvis = QtGui.QCheckBox() self.chkbvis.setCheckState(QtCore.Qt.Checked) self.connect(self.chkbvis, QtCore.SIGNAL("stateChanged(int)"), self.on_chkbvis_stateChanged) self.tblROI.setCellWidget(1, 1, self.chkbvis) # self.show_hide_rows(True) # creating the main Scene self.tractome= Tractome() self.add_scene(self.tractome.scene) def changenumstreamlines_handler(self, n_stream): """ """ if (n_stream< 1e5) and (n_stream>= 50): default = 50 else: default = n_stream self.spbRecluster.setValue(default) self.spbRecluster.setRange(1, n_stream) self.hSlReCluster.setValue(default) self.hSlReCluster.setMinimum(1) self.hSlReCluster.setMaximum(min(150, n_stream)) self.tblTract.item(1, 1).setText(str(n_stream)) def changenumrepresentatives_handler(self, n_rep): """ """ self.tblTract.item(2, 1).setText(str(n_rep)) def on_dspbxcoord_valueChanged(self, value): """ """ self.tractome.update_ROI(self.tblROI.item(0, 1).text(), coordx = value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_dspbycoord_valueChanged(self, value): """ """ self.tractome.update_ROI(self.tblROI.item(0, 1).text(), coordy = value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_dspbzcoord_valueChanged(self, value): self.tractome.update_ROI(self.tblROI.item(0, 1).text(), coordz = value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_spbrad_valueChanged(self, value): """ """ self.tractome.update_ROI(self.tblROI.item(0, 1).text(), radius=value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_chkbvis_stateChanged(self, state): """ Shows or hides the ROI if the visibility checkbox is checked or not correspondingly. """ self.tractome.show_hide_actor(self.tblROI.item(0, 1).text(), state) self.glWidget.updateGL() @Slot(QtGui.QTreeWidgetItem, int) def on_treeObject_itemClicked(self, item, column): """ If the item selected is a ROI, the corresponding information will be shown in the tableROI. """ name = str(item.text(0)) xcoord, ycoord, zcoord, radius, color= self.tractome.information_from_ROI(name) index= self.treeObject.indexFromItem(item) self.activeROI = index.row() self.disconnect(self.tblROI, QtCore.SIGNAL("itemChanged(QtGui.QTableWidgetItem)"), self.on_tblROI_itemChanged) self.updateROItable(name, xcoord, ycoord, zcoord, radius, color) self.connect(self.tblROI, QtCore.SIGNAL("itemChanged(QtGui.QTableWidgetItem)"), self.on_tblROI_itemChanged) def on_btncolor_clicked(self): """ """ color = QtGui.QColorDialog().getColor() self.btncolor.setStyleSheet( u'background-color:%s' % color.name()) self.tractome.update_ROI(self.tblROI.item(0, 1).text(), color = color.getRgbF()) @Slot(int) def on_chkbShowTract_stateChanged(self, state): """ Shows or hides the tractography if the Checkbox is checked or not correspondingly """ self.tractome.show_hide_actor('Bundle Picker', state) self.glWidget.updateGL() @Slot(int) def on_chkbShowStruct_stateChanged(self, state): """ Shows or hides the structural image if the Checkbox is checked or not correspondingly """ self.tractome.show_hide_actor('Volume Slicer', state) self.glWidget.updateGL() # @Slot(bool) # def on_rdbInsSphere_toggled(self, checked): # """ # Use method of Tractome inside sphere to compute the ROI # """ # if checked: # self.roimethod = 1 # self.tractome.update_ROI(self.tblROI.item(0, 1).text(), method = self.roimethod, rebuild= True) # if len(self.list_chkROIS)>0: # self.tractome.compute_streamlines_ROIS() # @Slot(bool) # def on_rdbtrackvis_toggled(self, checked): # """ # Use method of Trackvis to compute the ROI # """ # if checked: # self.roimethod = 0 # self.tractome.update_ROI(self.tblROI.item(0, 1).text(), method = self.roimethod, rebuild= True) # if len(self.list_chkROIS)>0: # self.tractome.compute_streamlines_ROIS() @Slot(int) def on_spbRecluster_valueChanged(self, p0): """ Update slider Recluster """ self.hSlReCluster.setValue(p0) @Slot(int) def on_hSlReCluster_valueChanged(self, value): """ Update spbRecluster """ self.spbRecluster.setValue(value) @Slot() def on_pbRecluster_clicked(self): """ Call re-cluster function from tractome and update values of possible number of clusters for related objects. """ self.tractome.recluster(self.spbRecluster.value()) self.glWidget.updateGL() @Slot() def on_actionLoad_Structural_Image_triggered(self): """ Opens a dialog to allow the user to choose the structural file. """ #Creating filedialog to search for the structural file filedialog=QtGui.QFileDialog() filedialog.setNameFilter(str("((*.gz *.nii *.img)")) fileStruct, _= filedialog.getOpenFileName(self,"Open Structural file", os.getcwd(), str("(*.gz *.nii *.img)")) if fileStruct != "": struct_basename = os.path.basename(fileStruct) self.create_update_Item('slicer') self.tractome.loading_structural(fileStruct) self.structnameitem.setText(0, struct_basename) self.refocus_camera() @Slot() def on_actionLoad_MASk_triggered(self): """ Opens a dialog to allow the user to choose the mask file. """ #Creating filedialog to search for the structural file filedialog=QtGui.QFileDialog() filedialog.setNameFilter(str("((*.gz *.nii *.img)")) fileMask, _= filedialog.getOpenFileName(self,"Open Mask file", os.getcwd(), str("(*.gz *.nii *.img)")) if fileMask !="": mask_basename = os.path.basename(fileMask) self.prepare_interface_ROI('mask', nameroi = mask_basename) self.tractome.loading_mask(fileMask, self.roi_color) self.updateROItable(mask_basename, color = self.roi_color.name()) self.glWidget.updateGL() @Slot() def on_actionLoad_Tractography_triggered(self): """ Opens a dialog to allow the user to choose the tractography file. """ filedialog=QtGui.QFileDialog() filedialog.setNameFilter(str("(*.dpy *.trk)")) fileTract, _= filedialog.getOpenFileName(self,"Open Tractography file", os.getcwd(), str("(*.dpy *.trk)")) if fileTract !="": tracks_basename = os.path.basename(fileTract) self.create_update_Item('tractography') self.tractome.loading_full_tractograpy(tracpath=fileTract) self.set_clustering_values() self.tractnameitem.setText(0, tracks_basename) # connecting event that is fired when number of streamlines is changed after some action on the streamlinelabeler actor self.tractome.streamlab.numstream_handler += self.changenumstreamlines_handler self.tractome.streamlab.numrep_handler += self.changenumrepresentatives_handler #add information to tab in Table self.tblTract.item(0, 1).setText(tracks_basename) trackcount = len(self.tractome.T) self.tblTract.item(1, 1).setText(str(trackcount)) self.tblTract.item(2, 1).setText(str(len(self.tractome.streamlab.representative_ids))) if hasattr(self.tractome, 'hdr'): hdr = self.tractome.hdr self.tblTract.item(3, 1).setText(str(hdr['voxel_size'])) self.tblTract.item(4, 1).setText(str(hdr['dim'])) self.tblTract.item(5, 1).setText(str(hdr['voxel_order'])) else: self.tblTract.item(3, 1).setText('No info') self.tblTract.item(4, 1).setText('No info') self.tblTract.item(5, 1).setText('LAS') self.grbCluster.setEnabled(True) def create_update_Item(self, object): """ Creates or updates the specified item in the TreeObject and the corresponding actor in the Scene (if neccesary). """ if object == 'tractography': #checking if there is already a tractography open to substitute it try: self.tractnameitem self.tractome.clear_actor('Bundle Picker') self.clear_all_session() #if there is no tractography open except AttributeError: self.tractnameitem = QtGui.QTreeWidgetItem(self.treeObject) self.chkbShowTract.setEnabled(True) self.tblTract.setEnabled(True) self.actionSave_Segmentation.setEnabled(True) self.actionSave_as_trackvis_file.setEnabled(True) self.menuROI.setEnabled(True) if object == 'slicer': try: self.structnameitem self.treeObject.clear() self.tractome.clear_all() self.clear_all_session() except AttributeError: #If this is the first opening we create the tree item self.chkbShowStruct.setEnabled(True) self.actionLoad_Tractography.setEnabled(True) self.structnameitem = QtGui.QTreeWidgetItem(self.treeObject) @Slot() def on_actionLoad_Saved_Segmentation_triggered(self): """ Opens a dialog to allow the user to choose a file of a previously saved session. """ filedialog=QtGui.QFileDialog() filedialog.setNameFilter(str("(*.seg)")) fileSeg, _ = filedialog.getOpenFileName(self,"Open Segmentation file", os.getcwd(), str("(*.seg)")) if fileSeg !="": #checking if there is already a tractography open to substitute it try: self.structnameitem self.tractnameitem self.treeObject.clear() self.tractome.clear_all() self.clear_all_session() #if there is no tractography open except AttributeError: self.chkbShowStruct.setEnabled(True) self.chkbShowTract.setEnabled(True) self.tblTract.setEnabled(True) self.menuROI.setEnabled(True) self.grbCluster.setEnabled(True) self.actionLoad_Tractography.setEnabled(True) self.actionSave_Segmentation.setEnabled(True) self.actionSave_as_trackvis_file.setEnabled(True) self.structnameitem = QtGui.QTreeWidgetItem(self.treeObject) self.tractnameitem = QtGui.QTreeWidgetItem(self.treeObject) self.tractome.load_segmentation(fileSeg) #add structural and tractography file names to the treeview struct_basename = os.path.basename(self.tractome.structpath) self.structnameitem.setText(0, struct_basename) tracks_basename = os.path.basename(self.tractome.tracpath) self.set_clustering_values() self.tractnameitem.setText(0, tracks_basename) # connecting event that is fired when number of streamlines is changed after some action on the streamlinelabeler actor self.tractome.streamlab.numstream_handler += self.changenumstreamlines_handler self.tractome.streamlab.numrep_handler += self.changenumrepresentatives_handler #add information to tab in Table self.tblTract.item(0, 1).setText(tracks_basename) trackcount = len(self.tractome.streamlab.streamline_ids) self.tblTract.item(1, 1).setText(str(trackcount)) self.tblTract.item(2, 1).setText(str(len(self.tractome.streamlab.representative_ids))) try: hdr = self.tractome.hdr self.tblTract.item(3, 1).setText(str(hdr['voxel_size'])) self.tblTract.item(4, 1).setText(str(hdr['dim'])) self.tblTract.item(5, 1).setText(str(hdr['voxel_order'])) except AttributeError: self.tblTract.item(3, 1).setText('No info') self.tblTract.item(4, 1).setText('No info') self.tblTract.item(5, 1).setText('LAS') self.refocus_camera() def clear_all_session(self): """ Clear all the objects related to ROIs """ self.list_chkROIS = [] self.list_ands = [] self.list_ors = [] self.tblROISlist.clear() self.tblROI.setEnabled(False) self.tblROISlist.setEnabled(False) self.tabProps_4.setCurrentIndex(0) @Slot() def on_actionSave_as_trackvis_file_triggered(self): """ Save streamlines of actual session in .trk file """ filename = QtGui.QFileDialog.getSaveFileName(self, 'Save Segmentation in .trk', os.getcwd(), str("(*.trk)")) self.tractome.save_trk(filename) @Slot() def on_actionSave_Segmentation_triggered(self): """ Saves the current session. """ filename = QtGui.QFileDialog.getSaveFileName(self, 'Save Segmentation', os.getcwd(), str("(*.seg)")) self.tractome.save_segmentation(filename) @Slot() def on_actionClose_triggered(self): """ Close application """ self.close() def disconnect_signals(self): """ Disconnect signal of spinboxes in ROI tables. If they are connected when updating min_max values of spinbox, the valueChanged signal is unnecessarily called. """ self.disconnect(self.spbrad, QtCore.SIGNAL("valueChanged(int)"), self.on_spbrad_valueChanged) self.disconnect(self.dspbxcoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbxcoord_valueChanged) self.disconnect(self.dspbycoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbycoord_valueChanged) self.disconnect(self.dspbzcoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbzcoord_valueChanged) def connect_signals(self): """ Reconnect signals of spinboxes in ROI tables, after min_max values have been updated """ self.connect(self.spbrad, QtCore.SIGNAL("valueChanged(int)"), self.on_spbrad_valueChanged) self.connect(self.dspbxcoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbxcoord_valueChanged) self.connect(self.dspbycoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbycoord_valueChanged) self.connect(self.dspbzcoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbzcoord_valueChanged) @Slot() def on_actionCreate_Sphere_triggered(self): """ Create a ROI and plot sphere """ maxcoord = self.tractome.max_coordinates() xmax = maxcoord[0] ymax = maxcoord[1] zmax = maxcoord[2] self.grb_tractomeroi.setEnabled(True) self.rdbInsSphere.toggle() cantrois = 0 if hasattr(self, 'list_chkROIS'): cantrois = len(self.list_chkROIS) number =cantrois + 1 #to define the name of the ROI depending on the number of available ROIs nameroi = 'ROI'+ str(number) self.prepare_interface_ROI('sphere', coords=maxcoord, nameroi = nameroi) self.tractome.create_ROI_sphere(nameroi, xmax/2, ymax/2, zmax/2, 2, self.roimethod, self.roi_color.getRgbF(), self.roi_color.name()) #add info of the ROI to ROI table self.updateROItable(nameroi, xmax/2, ymax/2, zmax/2, 2, self.roi_color.name()) self.tabProps_4.setCurrentIndex(1) self.glWidget.updateGL() def prepare_interface_ROI(self, roi_type, coords=None, nameroi = None): """ Set values and status of all interface elementes related to ROI. """ self.tblROI.setEnabled(True) self.tblROISlist.setEnabled(True) self.show_hide_rows(roi_type == 'mask') try: self.list_chkROIS except AttributeError: self.list_chkROIS = [] self.list_ands = [] self.list_ors = [] # add some fixed information to ROI table if roi_type == 'sphere': maxcoord = coords self.radmax = np.amax(maxcoord) # self.grbROImethod.setEnabled(True) # setting some fixed values in the table self.dspbxcoord.setRange(0, maxcoord[0]) self.dspbycoord.setRange(0,maxcoord[1]) self.dspbzcoord.setRange(0, maxcoord[2]) self.spbrad.setRange(1, self.radmax) self.connect_signals() cantrois = len(self.list_chkROIS) self.activeROI = cantrois # to know which is the ROI shown in the table, in case some information needs to be changed # define color if cantrois < len(self.colorlist): self.roi_color = self.colorlist[self.activeROI] else: poscolor = self.activeROI%len(self.colorlist) self.roi_color = self.colorlist[poscolor] # add item to tractography in tree roinameitem = QtGui.QTreeWidgetItem(self.tractnameitem) roinameitem.setText(0, nameroi) #should we add the whole file path? # roinameitem.setSelected(True) self.treeObject.expandAll() # create checkbox for applying ROI, add to list and to table for applied ROIs newchkroi = QtGui.QCheckBox() newchkroi.setText(nameroi) self.connect(newchkroi, QtCore.SIGNAL("stateChanged(int)"), self.on_chkroi_stateChanged) self.list_chkROIS.append(newchkroi) # create rdbuttons for operators and add checkbox for ROI cantchk = cantrois sizetblROIs = self.tblROISlist.geometry() if cantchk==0: self.tblROISlist.insertRow(0) self.tblROISlist.setCellWidget(0, 0, newchkroi) else: self.tblROISlist.insertRow((2*cantchk)-1) # create groupbox grb_roi_operators= QtGui.QGroupBox() # create radio buttons rdband = QtGui.QRadioButton("AND") rdbor = QtGui.QRadioButton("OR") rdbor.setText('OR') # add radio button to groupbox horizontalLayout_roiop = QtGui.QHBoxLayout() horizontalLayout_roiop.addWidget(rdband) horizontalLayout_roiop.addWidget(rdbor) horizontalLayout_roiop.addStretch(1) grb_roi_operators.setLayout(horizontalLayout_roiop) self.connect(rdband, QtCore.SIGNAL("clicked(bool)"), self.on_rdb_clicked) self.connect(rdbor, QtCore.SIGNAL("clicked(bool)"), self.on_rdb_clicked) # self.tblROISlist.setCellWidget((2*cantchk)-1, 0, grb_roi_operators) self.list_ands.append(rdband) self.list_ors.append(rdbor) self.tblROISlist.insertRow(2*cantchk) self.tblROISlist.setCellWidget(2*cantchk, 0, newchkroi) self.tblROISlist.resizeRowsToContents() #resizing objects sizeandrdb = rdband.geometry() sizeorrdb = rdbor.geometry() rdband.setGeometry(sizeandrdb.left(), sizeandrdb.top(), 5, sizeandrdb.height()) rdbor.setGeometry(sizeorrdb.left(), sizeorrdb.top(), 5, sizeorrdb.height()) #resizing checkbox sizecheckbox = newchkroi.geometry() newchkroi.setGeometry(sizecheckbox.left(), sizecheckbox.top(), sizetblROIs.width(), sizecheckbox.height()) def updateROItable(self, name,coordx=None, coordy=None, coordz=None, radius=None, color=None): """ Information of ROI is inserted in table when new ROI is created or when ROI selection changes in treeview. """ #show info of ROI in the table self.tblROI.item(0, 1).setText(name) if coordx is not None: self.disconnect_signals() self.dspbxcoord.setValue(coordx) self.dspbycoord.setValue(coordy) self.dspbzcoord.setValue(coordz) self.spbrad.setValue(radius) self.connect_signals() self.btncolor.setStyleSheet( u'background-color:%s' % color) def show_hide_rows(self, hide): """ Hides or shows rows from TableROI, depending on the type of ROI is selected on the tree. """ for i in range(3, self.tblROI.rowCount()): self.tblROI.setRowHidden(i, hide) self.tblROI.resizeRowsToContents() def on_chkroi_stateChanged(self, checked): """ Computing streamlines to show according to ROIs that are checked and their operators. """ last_chkd = 0 for pos in range(0, len(self.list_chkROIS)): if self.list_chkROIS[pos].isChecked(): self.tractome.activation_ROIs(pos, True) if pos!=(len(self.list_chkROIS)-1) and ((self.list_ands[pos].isChecked()==False) and (self.list_ors[pos].isChecked()==False)): self.list_ands[pos].setChecked(True) else: self.tractome.activation_ROIs(pos, False, operator = 'and') if pos!=(len(self.list_chkROIS)-1): if self.list_ands[pos].isChecked(): self.list_ands[pos].setAutoExclusive(False) self.list_ands[pos].setChecked(False) self.list_ands[pos].setAutoExclusive(True) if self.list_ors[pos].isChecked(): self.list_ors[pos].setAutoExclusive(False) self.list_ors[pos].setChecked(False) self.list_ors[pos].setAutoExclusive(True) self.tractome.compute_streamlines_ROIS() self.glWidget.updateGL() def on_rdb_clicked(self, clicked): """ Computing streamlines to show according to ROIs that are checked and their operators. """ for pos in range(0, len(self.list_ands)): if self.list_ands[pos].isChecked(): self.tractome.activation_ROIs(pos, True, operator = 'and') if self.list_ors[pos].isChecked(): self.tractome.activation_ROIs(pos, True, operator = 'or') self.tractome.compute_streamlines_ROIS() self.glWidget.updateGL() @Slot(QtGui.QTableWidgetItem) def on_tblROI_itemChanged(self, item): """ Will change name of ROI if this is edited in the table. """ treeitem = self.tractnameitem.child(self.activeROI) if item is self.tblROI.item(0, 1): prev_name_roi = str(treeitem.text(0)) index = self.treeObject.indexFromItem(treeitem, 0) if index.isValid(): self.tractome.update_ROI(prev_name_roi, newname = item.text(), pos_activeroi = self.activeROI) treeitem.setText(0, item.text()) @Slot() def on_actionRe_Cluster_triggered(self): """ Re-cluster. """ self.spbRecluster.setEnabled(True) self.hSlReCluster.setEnabled(True) self.pbRecluster.setEnabled(True) def set_clustering_values(self): """ """ max, default = self.tractome.max_num_clusters() self.spbRecluster. setValue(default) self.spbRecluster.setRange(1, max) self.hSlReCluster.setValue(default) self.hSlReCluster.setMinimum(1) self.hSlReCluster.setMaximum(min(150, max)) def initSpincamera(self, angle = 0.007 ): """ """ if self._spinCameraTimerInit: self.spinCameraTimer.timeout.disconnect() def rotate_camera(): self.glWidget.world.camera.rotate_around_focal( angle, "yup" ) self.glWidget.updateGL() self.spinCameraTimer.timeout.connect(rotate_camera) self._spinCameraTimerInit = True def spinCameraToggle(self): """ """ if not self.spinCameraTimer.isActive(): self.spinCameraTimer.start() else: self.spinCameraTimer.stop() def timerInit(self, interval = 30): """ """ timer = QtCore.QTimer(self) timer.setInterval( interval ) return timer def add_scene(self, scene): """ """ self.glWidget.world.add_scene(scene) def set_camera(self, camera): """ """ self.glWidget.world.camera = camera def refocus_camera(self): """ """ self.glWidget.world.refocus_camera() def update_light_position(self, x, y, z): """ """ if not self.glWidget.world.light is None: self.glWidget.world.update_lightposition(x, y, z) def screenshot(self, filename): """ Store current OpenGL context as image. """ self.glWidget.updateGL() self.glWidget.grabFrameBuffer().save( filename ) def keyPressEvent(self, event): """ Handle all key press events. """ # print 'key pressed', event.key() key = event.key() # self.messages=empty_messages.copy() # self.messages['key_pressed']=key # self.glWidget.world.send_all_messages(self.messages) # F1: fullscreen # F2: next frame # F3: previous frame # F4: start rotating # F12: reset camera # Esc: close window if key == QtCore.Qt.Key_F1: if self.fullscreen: self.showNormal() else: self.showFullScreen() self.fullscreen = not self.fullscreen elif key == QtCore.Qt.Key_F2: self.glWidget.world.nextTimeFrame() elif key == QtCore.Qt.Key_F3: self.glWidget.world.previousTimeFrame() elif key == QtCore.Qt.Key_F12: self.glWidget.world.refocus_camera() self.glWidget.world.camera.update() self.glWidget.updateGL() elif key == QtCore.Qt.Key_F4: if (event.modifiers() & QtCore.Qt.ShiftModifier): self.initSpincamera( angle = -0.01 ) self.spinCameraToggle() else: self.initSpincamera( angle = 0.01 ) self.spinCameraToggle() elif key == QtCore.Qt.Key_Escape: self.close() else: super(MainWindow, self).keyPressEvent( event ) self.glWidget.updateGL()
class PyDartQtWindow(QtGui.QMainWindow): def __init__(self, _title, _sim): super(PyDartQtWindow, self).__init__() # Check and create captures directory if not os.path.isdir('captures'): os.makedirs('captures') self.sim = _sim self.setWindowTitle(_title) self.trackball = None self.initUI() self.initActions() self.initToolbarActions() self.initToolbar() self.initMenu() self.idleTimer = QtCore.QTimer() self.idleTimer.timeout.connect(self.idleTimerEvent) self.idleTimer.start(0) self.renderTimer = QtCore.QTimer() self.renderTimer.timeout.connect(self.renderTimerEvent) self.renderTimer.start(25) self.cam0Event() def setTrackball(self, _trackball): self.trackball = _trackball self.cam0Event() def initUI(self): self.setGeometry(0, 0, 1280, 720) # self.setWindowTitle('Toolbar') self.glwidget = GLWidget(self) self.glwidget.setGeometry(0, 30, 1280, 720) self.glwidget.sim = self.sim def createAction(self, name, handler=None): action = QtGui.QAction(name, self) if handler is not None: action.triggered.connect(handler) return action def initActions(self): # Create actions self.resetAction = QtGui.QAction('Reset', self) self.resetAction.triggered.connect(self.resetEvent) self.playAction = QtGui.QAction('Play', self) self.playAction.setCheckable(True) self.playAction.setShortcut('Space') self.animAction = QtGui.QAction('Anim', self) self.animAction.setCheckable(True) self.captureAction = QtGui.QAction('Capture', self) self.captureAction.setCheckable(True) self.movieAction = QtGui.QAction('Movie', self) self.movieAction.triggered.connect(self.movieEvent) self.screenshotAction = QtGui.QAction('Screenshot', self) self.screenshotAction.triggered.connect(self.screenshotEvent) # Camera Menu self.cam0Action = QtGui.QAction('Camera0', self) self.cam0Action.triggered.connect(self.cam0Event) self.cam1Action = QtGui.QAction('Camera1', self) self.cam1Action.triggered.connect(self.cam1Event) self.printCamAction = QtGui.QAction('Print Camera', self) self.printCamAction.triggered.connect(self.printCamEvent) def initToolbarActions(self): self.toolbar_actions = [] self.toolbar_actions.append(self.resetAction) self.toolbar_actions.append(self.playAction) self.toolbar_actions.append(self.animAction) self.toolbar_actions.append(None) self.toolbar_actions.append(self.screenshotAction) self.toolbar_actions.append(self.captureAction) self.toolbar_actions.append(self.movieAction) def initToolbar(self): """ Read self.toolbar_actions and add them to the toolbar. None will be interpreted as separator """ # Create a toolbar self.toolbar = self.addToolBar('Control') for action in self.toolbar_actions: if action is None: self.toolbar.addSeparator() elif isinstance(action, QtGui.QAction): self.toolbar.addAction(action) elif isinstance(action, QtGui.QWidget): self.toolbar.addWidget(action) self.rangeSlider = QtGui.QSlider(QtCore.Qt.Horizontal, self) self.rangeSlider.valueChanged[int].connect(self.rangeSliderEvent) self.toolbar.addWidget(self.rangeSlider) def initMenu(self): menubar = self.menuBar() self.fileMenu = menubar.addMenu('&File') # Camera menu self.cameraMenu = menubar.addMenu('&Camera') self.cameraMenu.addAction(self.cam0Action) self.cameraMenu.addAction(self.cam1Action) self.cameraMenu.addSeparator() self.cameraMenu.addAction(self.printCamAction) # Recording menu self.recordingMenu = menubar.addMenu('&Recording') self.recordingMenu.addAction(self.screenshotAction) self.recordingMenu.addSeparator() self.recordingMenu.addAction(self.captureAction) self.recordingMenu.addAction(self.movieAction) self.menuBar = menubar def idleTimerEvent(self): doCapture = False # Do animation if self.animAction.isChecked(): for i in range(10): v = self.rangeSlider.value() + 1 if v <= self.rangeSlider.maximum(): self.rangeSlider.setValue(v) else: self.animAction.setChecked(False) if v % 100 == 1: doCapture = True # Do play elif self.playAction.isChecked(): if self._step_callback is not None: self._step_callback(self.sim) result = self.sim.step() if result: self.playAction.setChecked(False) doCapture = (self.sim.num_frames() % 4 == 1) if self.captureAction.isChecked() and doCapture: self.glwidget.capture('capture') def renderTimerEvent(self): self.glwidget.updateGL() if hasattr(self.sim, 'statusMessage'): message = self.sim.statusMessage() else: message = '# frames = %d' % self.sim.num_frames() self.statusBar().showMessage(message) self.rangeSlider.setRange(0, self.sim.num_frames() - 1) def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Escape: print 'Escape key pressed! Bye.' self.close() if 0 <= event.key() and event.key() < 256: # If key is ascii key = chr(event.key()) if self._keyboard_callback is not None: self._keyboard_callback(self.sim, key) if hasattr(self.sim, 'key_pressed'): self.sim.key_pressed(key) def rangeSliderEvent(self, value): self.sim.set_frame(value) def screenshotEvent(self): self.glwidget.capture() def movieEvent(self): cmd = 'avconv -r 200 -i ./captures/capture.%04d.png output.mp4' print 'Movie command:', cmd os.system(cmd) def resetEvent(self): self.sim.reset() def cam0Event(self): if self.trackball is not None: self.glwidget.tb = eval(repr(self.trackball)) # Make a deepcopy return self.glwidget.tb = Trackball(phi=-0.0, theta=0.0, zoom=1.0, rot=[-0.02, -0.71, -0.02, 0.71], trans=[0.02, 0.09, -0.69]) def cam1Event(self): self.glwidget.tb = Trackball(phi=-0.0, theta=0.0, zoom=1.0, rot=[-0.02, -0.71, -0.02, 0.71], trans=[0.06, 0.26, -1.23]) def printCamEvent(self): print 'printCamEvent' print '----' print repr(self.glwidget.tb) print '----'
class MainWindow(QMainWindow, Ui_MainWindow): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ # calling base initializers super(MainWindow, self).__init__(parent) # calling base setupUi for ui configuration self.setupUi(self) # setting up the gui self.setup_gui() def setup_gui(self): """ """ self.glWidget = GLWidget(parent = self.gridWidget_4, width = 1508, height = 713, bgcolor = (.5, .5, 0.9), enable_light = False) self.gridLayout_4.addWidget(self.glWidget) #for now, pbExtCluster will be invisible self.pbExtCluster.setVisible(False) # adding the editing items to ROI table # double spinbox for x,y and z coordinates self.dspbxcoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(3, 1, self.dspbxcoord) self.dspbycoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(4, 1, self.dspbycoord) self.dspbzcoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(5, 1, self.dspbzcoord) self.spbrad = QtGui.QSpinBox() self.tblROI.setCellWidget(6, 1, self.spbrad) # define method ROI self.roimethod = 1 #tractome inside # color button self.colorlist = [QtGui.QColor('red'), QtGui.QColor('blue'), QtGui.QColor('green'), QtGui.QColor('yellow'), QtGui.QColor('cyan'), QtGui.QColor('black')] self.btncolor = QtGui.QPushButton() self.tblROI.setCellWidget(2, 1, self.btncolor) self.btncolor.setAutoFillBackground(True) # connect button with QColorDialog self.connect(self.btncolor, QtCore.SIGNAL("clicked()"), self.on_btncolor_clicked) # visibility checkbox self.chkbvis = QtGui.QCheckBox() self.chkbvis.setCheckState(QtCore.Qt.Checked) self.connect(self.chkbvis, QtCore.SIGNAL("stateChanged(int)"), self.on_chkbvis_stateChanged) self.tblROI.setCellWidget(1, 1, self.chkbvis) # self.show_hide_rows(True) # creating the main Scene self.tractome= Tractome() self.add_scene(self.tractome.scene) def changenumstreamlines_handler(self, n_stream): """ """ if (n_stream< 1e5) and (n_stream>= 50): default = 50 else: default = n_stream self.spbRecluster.setValue(default) self.spbRecluster.setRange(1, n_stream) self.hSlReCluster.setValue(default) self.hSlReCluster.setMinimum(1) self.hSlReCluster.setMaximum(min(150, n_stream)) self.tblTract.item(1, 1).setText(str(n_stream)) def changenumrepresentatives_handler(self, n_rep): """ """ self.tblTract.item(2, 1).setText(str(n_rep)) def changenumknnextend_handler(self, changenn): """ """ if changenn is True: self.hSlExtclust.setValue(0) def on_dspbxcoord_valueChanged(self, value): """ """ self.tractome.update_ROI(self.tblROI.item(0, 1).text(), coordx = value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_dspbycoord_valueChanged(self, value): """ """ self.tractome.update_ROI(self.tblROI.item(0, 1).text(), coordy = value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_dspbzcoord_valueChanged(self, value): self.tractome.update_ROI(self.tblROI.item(0, 1).text(), coordz = value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_spbrad_valueChanged(self, value): """ """ self.tractome.update_ROI(self.tblROI.item(0, 1).text(), radius=value, rebuild = self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_chkbvis_stateChanged(self, state): """ Shows or hides the ROI if the visibility checkbox is checked or not correspondingly. """ self.tractome.show_hide_actor(self.tblROI.item(0, 1).text(), state) self.glWidget.updateGL() @Slot(QtGui.QTreeWidgetItem, int) def on_treeObject_itemClicked(self, item, column): """ If the item selected is a ROI, the corresponding information will be shown in the tableROI. """ name = str(item.text(0)) xcoord, ycoord, zcoord, radius, color= self.tractome.information_from_ROI(name) index= self.treeObject.indexFromItem(item) self.activeROI = index.row() self.disconnect(self.tblROI, QtCore.SIGNAL("itemChanged(QtGui.QTableWidgetItem)"), self.on_tblROI_itemChanged) self.updateROItable(name, xcoord, ycoord, zcoord, radius, color) self.connect(self.tblROI, QtCore.SIGNAL("itemChanged(QtGui.QTableWidgetItem)"), self.on_tblROI_itemChanged) def on_btncolor_clicked(self): """ """ color = QtGui.QColorDialog().getColor() self.btncolor.setStyleSheet( u'background-color:%s' % color.name()) self.tractome.update_ROI(self.tblROI.item(0, 1).text(), color = color.getRgbF()) @Slot(int) def on_chkbShowTract_stateChanged(self, state): """ Shows or hides the tractography if the Checkbox is checked or not correspondingly """ self.tractome.show_hide_actor('Bundle Picker', state) self.glWidget.updateGL() @Slot(int) def on_chkbShowStruct_stateChanged(self, state): """ Shows or hides the structural image if the Checkbox is checked or not correspondingly """ self.tractome.show_hide_actor('Volume Slicer', state) self.glWidget.updateGL() # @Slot(bool) # def on_rdbInsSphere_toggled(self, checked): # """ # Use method of Tractome inside sphere to compute the ROI # """ # if checked: # self.roimethod = 1 # self.tractome.update_ROI(self.tblROI.item(0, 1).text(), method = self.roimethod, rebuild= True) # if len(self.list_chkROIS)>0: # self.tractome.compute_streamlines_ROIS() # @Slot(bool) # def on_rdbtrackvis_toggled(self, checked): # """ # Use method of Trackvis to compute the ROI # """ # if checked: # self.roimethod = 0 # self.tractome.update_ROI(self.tblROI.item(0, 1).text(), method = self.roimethod, rebuild= True) # if len(self.list_chkROIS)>0: # self.tractome.compute_streamlines_ROIS() @Slot(int) def on_spbRecluster_valueChanged(self, p0): """ Update slider Recluster """ self.hSlReCluster.setValue(p0) @Slot(int) def on_hSlReCluster_valueChanged(self, value): """ Update spbRecluster """ self.spbRecluster.setValue(value) @Slot() def on_pbRecluster_clicked(self): """ Call re-cluster function from tractome and update values of possible number of clusters for related objects. """ self.tractome.recluster(self.spbRecluster.value()) self.hSlExtclust.setValue(0) self.glWidget.updateGL() @Slot(int) def on_spbExtClust_valueChanged(self, p0): """ Update hSlExtclust and call method that computes kdtree-query. """ self.hSlExtclust.setValue(p0) try: self.tractome.compute_kqueries(p0) self.glWidget.updateGL() except TractomeError,e: msgBox = QtGui.QMessageBox.critical(self, "Tractome Message", ''.join(e.args))
class PyDartQtWindow(QtGui.QMainWindow): def __init__(self, _title, _sim): super(PyDartQtWindow, self).__init__() # Check and create captures directory if not os.path.isdir('captures'): os.makedirs('captures') self.sim = _sim self.setWindowTitle(_title) self.trackball = None self.initUI() self.initActions() self.initToolbarActions() self.initToolbar() self.initMenu() self.idleTimer = QtCore.QTimer() self.idleTimer.timeout.connect(self.idleTimerEvent) self.idleTimer.start(0) self.renderTimer = QtCore.QTimer() self.renderTimer.timeout.connect(self.renderTimerEvent) self.renderTimer.start(25) self.cam0Event() def setTrackball(self, _trackball): self.trackball = _trackball self.cam0Event() def initUI(self): self.setGeometry(0, 0, 1280, 720) # self.setWindowTitle('Toolbar') self.glwidget = GLWidget(self) self.glwidget.setGeometry(0, 30, 1280, 720) self.glwidget.sim = self.sim def createAction(self, name, handler=None): action = QtGui.QAction(name, self) if handler is not None: action.triggered.connect(handler) return action def initActions(self): # Create actions self.resetAction = QtGui.QAction('Reset', self) self.resetAction.triggered.connect(self.resetEvent) self.playAction = QtGui.QAction('Play', self) self.playAction.setCheckable(True) self.playAction.setShortcut('Space') self.animAction = QtGui.QAction('Anim', self) self.animAction.setCheckable(True) self.captureAction = QtGui.QAction('Capture', self) self.captureAction.setCheckable(True) self.movieAction = QtGui.QAction('Movie', self) self.movieAction.triggered.connect(self.movieEvent) self.screenshotAction = QtGui.QAction('Screenshot', self) self.screenshotAction.triggered.connect(self.screenshotEvent) # Camera Menu self.cam0Action = QtGui.QAction('Camera0', self) self.cam0Action.triggered.connect(self.cam0Event) self.cam1Action = QtGui.QAction('Camera1', self) self.cam1Action.triggered.connect(self.cam1Event) self.printCamAction = QtGui.QAction('Print Camera', self) self.printCamAction.triggered.connect(self.printCamEvent) def initToolbarActions(self): self.toolbar_actions = [] self.toolbar_actions.append(self.resetAction) self.toolbar_actions.append(self.playAction) self.toolbar_actions.append(self.animAction) self.toolbar_actions.append(None) self.toolbar_actions.append(self.screenshotAction) self.toolbar_actions.append(self.captureAction) self.toolbar_actions.append(self.movieAction) def initToolbar(self): """ Read self.toolbar_actions and add them to the toolbar. None will be interpreted as separator """ # Create a toolbar self.toolbar = self.addToolBar('Control') for action in self.toolbar_actions: if action is None: self.toolbar.addSeparator() elif isinstance(action, QtGui.QAction): self.toolbar.addAction(action) elif isinstance(action, QtGui.QWidget): self.toolbar.addWidget(action) self.rangeSlider = QtGui.QSlider(QtCore.Qt.Horizontal, self) self.rangeSlider.valueChanged[int].connect(self.rangeSliderEvent) self.toolbar.addWidget(self.rangeSlider) def initMenu(self): menubar = self.menuBar() self.fileMenu = menubar.addMenu('&File') # Camera menu self.cameraMenu = menubar.addMenu('&Camera') self.cameraMenu.addAction(self.cam0Action) self.cameraMenu.addAction(self.cam1Action) self.cameraMenu.addSeparator() self.cameraMenu.addAction(self.printCamAction) # Recording menu self.recordingMenu = menubar.addMenu('&Recording') self.recordingMenu.addAction(self.screenshotAction) self.recordingMenu.addSeparator() self.recordingMenu.addAction(self.captureAction) self.recordingMenu.addAction(self.movieAction) self.menuBar = menubar def idleTimerEvent(self): doCapture = False # Do animation if self.animAction.isChecked(): for i in range(10): v = self.rangeSlider.value() + 1 if v <= self.rangeSlider.maximum(): self.rangeSlider.setValue(v) else: self.animAction.setChecked(False) if v % 100 == 1: doCapture = True # Do play elif self.playAction.isChecked(): if self._step_callback is not None: self._step_callback(self.sim) result = self.sim.step() if result: self.playAction.setChecked(False) doCapture = (self.sim.num_frames() % 4 == 1) if self.captureAction.isChecked() and doCapture: self.glwidget.capture('capture') def renderTimerEvent(self): self.glwidget.updateGL() if hasattr(self.sim, 'statusMessage'): message = self.sim.statusMessage() else: message = '# frames = %d' % self.sim.num_frames() self.statusBar().showMessage(message) self.rangeSlider.setRange(0, self.sim.num_frames() - 1) def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Escape: print 'Escape key pressed! Bye.' self.close() if 0 <= event.key() and event.key() < 256: # If key is ascii key = chr(event.key()) if self._keyboard_callback is not None: self._keyboard_callback(self.sim, key) if hasattr(self.sim, 'key_pressed'): self.sim.key_pressed(key) def rangeSliderEvent(self, value): self.sim.set_frame(value) def screenshotEvent(self): self.glwidget.capture() def movieEvent(self): cmd = 'avconv -r 200 -i ./captures/capture.%04d.png output.mp4' print 'Movie command:', cmd os.system(cmd) def resetEvent(self): self.sim.reset() def cam0Event(self): if self.trackball is not None: self.glwidget.tb = eval(repr(self.trackball)) # Make a deepcopy return self.glwidget.tb = Trackball(phi=-0.0, theta=0.0, zoom=1.0, rot=[-0.02, -0.71, -0.02, 0.71], trans=[0.02, 0.09, -0.69]) def cam1Event(self): self.glwidget.tb = Trackball(phi=-0.0, theta=0.0, zoom=1.0, rot=[-0.02, -0.71, -0.02, 0.71], trans=[0.06, 0.26, -1.23]) def printCamEvent(self): print 'printCamEvent' print '----' print repr(self.glwidget.tb) print '----'
class MainWindow(QMainWindow, Ui_MainWindow): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ # calling base initializers super(MainWindow, self).__init__(parent) # calling base setupUi for ui configuration self.setupUi(self) # setting up the gui self.setup_gui() def setup_gui(self): """ """ self.glWidget = GLWidget(parent=self.gridWidget_4, width=1508, height=713, bgcolor=(.5, .5, 0.9), enable_light=False) self.gridLayout_4.addWidget(self.glWidget) # adding the editing items to ROI table # double spinbox for x,y and z coordinates self.dspbxcoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(3, 1, self.dspbxcoord) self.dspbycoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(4, 1, self.dspbycoord) self.dspbzcoord = QtGui.QDoubleSpinBox() self.tblROI.setCellWidget(5, 1, self.dspbzcoord) self.spbrad = QtGui.QSpinBox() self.tblROI.setCellWidget(6, 1, self.spbrad) # define method ROI self.roimethod = 1 #tractome inside # color button self.colorlist = [ QtGui.QColor('red'), QtGui.QColor('blue'), QtGui.QColor('green'), QtGui.QColor('yellow'), QtGui.QColor('cyan'), QtGui.QColor('black') ] self.btncolor = QtGui.QPushButton() self.tblROI.setCellWidget(2, 1, self.btncolor) self.btncolor.setAutoFillBackground(True) # connect button with QColorDialog self.connect(self.btncolor, QtCore.SIGNAL("clicked()"), self.on_btncolor_clicked) # visibility checkbox self.chkbvis = QtGui.QCheckBox() self.chkbvis.setCheckState(QtCore.Qt.Checked) self.connect(self.chkbvis, QtCore.SIGNAL("stateChanged(int)"), self.on_chkbvis_stateChanged) self.tblROI.setCellWidget(1, 1, self.chkbvis) # self.show_hide_rows(True) # creating the main Scene self.tractome = Tractome() self.add_scene(self.tractome.scene) def changenumstreamlines_handler(self, n_stream): """ """ if (n_stream < 1e5) and (n_stream >= 50): default = 50 else: default = n_stream self.spbRecluster.setValue(default) self.spbRecluster.setRange(1, n_stream) self.hSlReCluster.setValue(default) self.hSlReCluster.setMinimum(1) self.hSlReCluster.setMaximum(min(150, n_stream)) self.tblTract.item(1, 1).setText(str(n_stream)) def changenumrepresentatives_handler(self, n_rep): """ """ self.tblTract.item(2, 1).setText(str(n_rep)) def on_dspbxcoord_valueChanged(self, value): """ """ self.tractome.update_ROI( self.tblROI.item(0, 1).text(), coordx=value, rebuild=self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_dspbycoord_valueChanged(self, value): """ """ self.tractome.update_ROI( self.tblROI.item(0, 1).text(), coordy=value, rebuild=self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_dspbzcoord_valueChanged(self, value): self.tractome.update_ROI( self.tblROI.item(0, 1).text(), coordz=value, rebuild=self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_spbrad_valueChanged(self, value): """ """ self.tractome.update_ROI( self.tblROI.item(0, 1).text(), radius=value, rebuild=self.list_chkROIS[self.activeROI].isChecked()) self.glWidget.updateGL() def on_chkbvis_stateChanged(self, state): """ Shows or hides the ROI if the visibility checkbox is checked or not correspondingly. """ self.tractome.show_hide_actor(self.tblROI.item(0, 1).text(), state) self.glWidget.updateGL() @Slot(QtGui.QTreeWidgetItem, int) def on_treeObject_itemClicked(self, item, column): """ If the item selected is a ROI, the corresponding information will be shown in the tableROI. """ name = str(item.text(0)) xcoord, ycoord, zcoord, radius, color = self.tractome.information_from_ROI( name) index = self.treeObject.indexFromItem(item) self.activeROI = index.row() self.disconnect(self.tblROI, QtCore.SIGNAL("itemChanged(QtGui.QTableWidgetItem)"), self.on_tblROI_itemChanged) self.updateROItable(name, xcoord, ycoord, zcoord, radius, color) self.connect(self.tblROI, QtCore.SIGNAL("itemChanged(QtGui.QTableWidgetItem)"), self.on_tblROI_itemChanged) def on_btncolor_clicked(self): """ """ color = QtGui.QColorDialog().getColor() self.btncolor.setStyleSheet(u'background-color:%s' % color.name()) self.tractome.update_ROI(self.tblROI.item(0, 1).text(), color=color.getRgbF()) @Slot(int) def on_chkbShowTract_stateChanged(self, state): """ Shows or hides the tractography if the Checkbox is checked or not correspondingly """ self.tractome.show_hide_actor('Bundle Picker', state) self.glWidget.updateGL() @Slot(int) def on_chkbShowStruct_stateChanged(self, state): """ Shows or hides the structural image if the Checkbox is checked or not correspondingly """ self.tractome.show_hide_actor('Volume Slicer', state) self.glWidget.updateGL() # @Slot(bool) # def on_rdbInsSphere_toggled(self, checked): # """ # Use method of Tractome inside sphere to compute the ROI # """ # if checked: # self.roimethod = 1 # self.tractome.update_ROI(self.tblROI.item(0, 1).text(), method = self.roimethod, rebuild= True) # if len(self.list_chkROIS)>0: # self.tractome.compute_streamlines_ROIS() # @Slot(bool) # def on_rdbtrackvis_toggled(self, checked): # """ # Use method of Trackvis to compute the ROI # """ # if checked: # self.roimethod = 0 # self.tractome.update_ROI(self.tblROI.item(0, 1).text(), method = self.roimethod, rebuild= True) # if len(self.list_chkROIS)>0: # self.tractome.compute_streamlines_ROIS() @Slot(int) def on_spbRecluster_valueChanged(self, p0): """ Update slider Recluster """ self.hSlReCluster.setValue(p0) @Slot(int) def on_hSlReCluster_valueChanged(self, value): """ Update spbRecluster """ self.spbRecluster.setValue(value) @Slot() def on_pbRecluster_clicked(self): """ Call re-cluster function from tractome and update values of possible number of clusters for related objects. """ self.tractome.recluster(self.spbRecluster.value()) self.glWidget.updateGL() @Slot() def on_actionLoad_Structural_Image_triggered(self): """ Opens a dialog to allow the user to choose the structural file. """ #Creating filedialog to search for the structural file filedialog = QtGui.QFileDialog() filedialog.setNameFilter(str("((*.gz *.nii *.img)")) fileStruct, _ = filedialog.getOpenFileName(self, "Open Structural file", os.getcwd(), str("(*.gz *.nii *.img)")) if fileStruct != "": struct_basename = os.path.basename(fileStruct) self.create_update_Item('slicer') self.tractome.loading_structural(fileStruct) self.structnameitem.setText(0, struct_basename) self.refocus_camera() @Slot() def on_actionLoad_MASk_triggered(self): """ Opens a dialog to allow the user to choose the mask file. """ #Creating filedialog to search for the structural file filedialog = QtGui.QFileDialog() filedialog.setNameFilter(str("((*.gz *.nii *.img)")) fileMask, _ = filedialog.getOpenFileName(self, "Open Mask file", os.getcwd(), str("(*.gz *.nii *.img)")) if fileMask != "": mask_basename = os.path.basename(fileMask) self.prepare_interface_ROI('mask', nameroi=mask_basename) self.tractome.loading_mask(fileMask, self.roi_color) self.updateROItable(mask_basename, color=self.roi_color.name()) self.glWidget.updateGL() @Slot() def on_actionLoad_Tractography_triggered(self): """ Opens a dialog to allow the user to choose the tractography file. """ filedialog = QtGui.QFileDialog() filedialog.setNameFilter(str("(*.dpy *.trk)")) fileTract, _ = filedialog.getOpenFileName(self, "Open Tractography file", os.getcwd(), str("(*.dpy *.trk)")) if fileTract != "": tracks_basename = os.path.basename(fileTract) self.create_update_Item('tractography') self.tractome.loading_full_tractograpy(tracpath=fileTract) self.set_clustering_values() self.tractnameitem.setText(0, tracks_basename) # connecting event that is fired when number of streamlines is changed after some action on the streamlinelabeler actor self.tractome.streamlab.numstream_handler += self.changenumstreamlines_handler self.tractome.streamlab.numrep_handler += self.changenumrepresentatives_handler #add information to tab in Table self.tblTract.item(0, 1).setText(tracks_basename) trackcount = len(self.tractome.T) self.tblTract.item(1, 1).setText(str(trackcount)) self.tblTract.item(2, 1).setText( str(len(self.tractome.streamlab.representative_ids))) if hasattr(self.tractome, 'hdr'): hdr = self.tractome.hdr self.tblTract.item(3, 1).setText(str(hdr['voxel_size'])) self.tblTract.item(4, 1).setText(str(hdr['dim'])) self.tblTract.item(5, 1).setText(str(hdr['voxel_order'])) else: self.tblTract.item(3, 1).setText('No info') self.tblTract.item(4, 1).setText('No info') self.tblTract.item(5, 1).setText('LAS') self.grbCluster.setEnabled(True) def create_update_Item(self, object): """ Creates or updates the specified item in the TreeObject and the corresponding actor in the Scene (if neccesary). """ if object == 'tractography': #checking if there is already a tractography open to substitute it try: self.tractnameitem self.tractome.clear_actor('Bundle Picker') self.clear_all_session() #if there is no tractography open except AttributeError: self.tractnameitem = QtGui.QTreeWidgetItem(self.treeObject) self.chkbShowTract.setEnabled(True) self.tblTract.setEnabled(True) self.actionSave_Segmentation.setEnabled(True) self.actionSave_as_trackvis_file.setEnabled(True) self.menuROI.setEnabled(True) if object == 'slicer': try: self.structnameitem self.treeObject.clear() self.tractome.clear_all() self.clear_all_session() except AttributeError: #If this is the first opening we create the tree item self.chkbShowStruct.setEnabled(True) self.actionLoad_Tractography.setEnabled(True) self.structnameitem = QtGui.QTreeWidgetItem(self.treeObject) @Slot() def on_actionLoad_Saved_Segmentation_triggered(self): """ Opens a dialog to allow the user to choose a file of a previously saved session. """ filedialog = QtGui.QFileDialog() filedialog.setNameFilter(str("(*.seg)")) fileSeg, _ = filedialog.getOpenFileName(self, "Open Segmentation file", os.getcwd(), str("(*.seg)")) if fileSeg != "": #checking if there is already a tractography open to substitute it try: self.structnameitem self.tractnameitem self.treeObject.clear() self.tractome.clear_all() self.clear_all_session() #if there is no tractography open except AttributeError: self.chkbShowStruct.setEnabled(True) self.chkbShowTract.setEnabled(True) self.tblTract.setEnabled(True) self.menuROI.setEnabled(True) self.grbCluster.setEnabled(True) self.actionLoad_Tractography.setEnabled(True) self.actionSave_Segmentation.setEnabled(True) self.actionSave_as_trackvis_file.setEnabled(True) self.structnameitem = QtGui.QTreeWidgetItem(self.treeObject) self.tractnameitem = QtGui.QTreeWidgetItem(self.treeObject) self.tractome.load_segmentation(fileSeg) #add structural and tractography file names to the treeview struct_basename = os.path.basename(self.tractome.structpath) self.structnameitem.setText(0, struct_basename) tracks_basename = os.path.basename(self.tractome.tracpath) self.set_clustering_values() self.tractnameitem.setText(0, tracks_basename) # connecting event that is fired when number of streamlines is changed after some action on the streamlinelabeler actor self.tractome.streamlab.numstream_handler += self.changenumstreamlines_handler self.tractome.streamlab.numrep_handler += self.changenumrepresentatives_handler #add information to tab in Table self.tblTract.item(0, 1).setText(tracks_basename) trackcount = len(self.tractome.streamlab.streamline_ids) self.tblTract.item(1, 1).setText(str(trackcount)) self.tblTract.item(2, 1).setText( str(len(self.tractome.streamlab.representative_ids))) try: hdr = self.tractome.hdr self.tblTract.item(3, 1).setText(str(hdr['voxel_size'])) self.tblTract.item(4, 1).setText(str(hdr['dim'])) self.tblTract.item(5, 1).setText(str(hdr['voxel_order'])) except AttributeError: self.tblTract.item(3, 1).setText('No info') self.tblTract.item(4, 1).setText('No info') self.tblTract.item(5, 1).setText('LAS') self.refocus_camera() def clear_all_session(self): """ Clear all the objects related to ROIs """ self.list_chkROIS = [] self.list_ands = [] self.list_ors = [] self.tblROISlist.clear() self.tblROI.setEnabled(False) self.tblROISlist.setEnabled(False) self.tabProps_4.setCurrentIndex(0) @Slot() def on_actionSave_as_trackvis_file_triggered(self): """ Save streamlines of actual session in .trk file """ filename = QtGui.QFileDialog.getSaveFileName( self, 'Save Segmentation in .trk', os.getcwd(), str("(*.trk)")) self.tractome.save_trk(filename) @Slot() def on_actionSave_Segmentation_triggered(self): """ Saves the current session. """ filename = QtGui.QFileDialog.getSaveFileName(self, 'Save Segmentation', os.getcwd(), str("(*.seg)")) self.tractome.save_segmentation(filename) @Slot() def on_actionClose_triggered(self): """ Close application """ self.close() def disconnect_signals(self): """ Disconnect signal of spinboxes in ROI tables. If they are connected when updating min_max values of spinbox, the valueChanged signal is unnecessarily called. """ self.disconnect(self.spbrad, QtCore.SIGNAL("valueChanged(int)"), self.on_spbrad_valueChanged) self.disconnect(self.dspbxcoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbxcoord_valueChanged) self.disconnect(self.dspbycoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbycoord_valueChanged) self.disconnect(self.dspbzcoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbzcoord_valueChanged) def connect_signals(self): """ Reconnect signals of spinboxes in ROI tables, after min_max values have been updated """ self.connect(self.spbrad, QtCore.SIGNAL("valueChanged(int)"), self.on_spbrad_valueChanged) self.connect(self.dspbxcoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbxcoord_valueChanged) self.connect(self.dspbycoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbycoord_valueChanged) self.connect(self.dspbzcoord, QtCore.SIGNAL("valueChanged(double)"), self.on_dspbzcoord_valueChanged) @Slot() def on_actionCreate_Sphere_triggered(self): """ Create a ROI and plot sphere """ maxcoord = self.tractome.max_coordinates() xmax = maxcoord[0] ymax = maxcoord[1] zmax = maxcoord[2] self.grb_tractomeroi.setEnabled(True) self.rdbInsSphere.toggle() cantrois = 0 if hasattr(self, 'list_chkROIS'): cantrois = len(self.list_chkROIS) number = cantrois + 1 #to define the name of the ROI depending on the number of available ROIs nameroi = 'ROI' + str(number) self.prepare_interface_ROI('sphere', coords=maxcoord, nameroi=nameroi) self.tractome.create_ROI_sphere(nameroi, xmax / 2, ymax / 2, zmax / 2, 2, self.roimethod, self.roi_color.getRgbF(), self.roi_color.name()) #add info of the ROI to ROI table self.updateROItable(nameroi, xmax / 2, ymax / 2, zmax / 2, 2, self.roi_color.name()) self.tabProps_4.setCurrentIndex(1) self.glWidget.updateGL() def prepare_interface_ROI(self, roi_type, coords=None, nameroi=None): """ Set values and status of all interface elementes related to ROI. """ self.tblROI.setEnabled(True) self.tblROISlist.setEnabled(True) self.show_hide_rows(roi_type == 'mask') try: self.list_chkROIS except AttributeError: self.list_chkROIS = [] self.list_ands = [] self.list_ors = [] # add some fixed information to ROI table if roi_type == 'sphere': maxcoord = coords self.radmax = np.amax(maxcoord) # self.grbROImethod.setEnabled(True) # setting some fixed values in the table self.dspbxcoord.setRange(0, maxcoord[0]) self.dspbycoord.setRange(0, maxcoord[1]) self.dspbzcoord.setRange(0, maxcoord[2]) self.spbrad.setRange(1, self.radmax) self.connect_signals() cantrois = len(self.list_chkROIS) self.activeROI = cantrois # to know which is the ROI shown in the table, in case some information needs to be changed # define color if cantrois < len(self.colorlist): self.roi_color = self.colorlist[self.activeROI] else: poscolor = self.activeROI % len(self.colorlist) self.roi_color = self.colorlist[poscolor] # add item to tractography in tree roinameitem = QtGui.QTreeWidgetItem(self.tractnameitem) roinameitem.setText(0, nameroi) #should we add the whole file path? # roinameitem.setSelected(True) self.treeObject.expandAll() # create checkbox for applying ROI, add to list and to table for applied ROIs newchkroi = QtGui.QCheckBox() newchkroi.setText(nameroi) self.connect(newchkroi, QtCore.SIGNAL("stateChanged(int)"), self.on_chkroi_stateChanged) self.list_chkROIS.append(newchkroi) # create rdbuttons for operators and add checkbox for ROI cantchk = cantrois sizetblROIs = self.tblROISlist.geometry() if cantchk == 0: self.tblROISlist.insertRow(0) self.tblROISlist.setCellWidget(0, 0, newchkroi) else: self.tblROISlist.insertRow((2 * cantchk) - 1) # create groupbox grb_roi_operators = QtGui.QGroupBox() # create radio buttons rdband = QtGui.QRadioButton("AND") rdbor = QtGui.QRadioButton("OR") rdbor.setText('OR') # add radio button to groupbox horizontalLayout_roiop = QtGui.QHBoxLayout() horizontalLayout_roiop.addWidget(rdband) horizontalLayout_roiop.addWidget(rdbor) horizontalLayout_roiop.addStretch(1) grb_roi_operators.setLayout(horizontalLayout_roiop) self.connect(rdband, QtCore.SIGNAL("clicked(bool)"), self.on_rdb_clicked) self.connect(rdbor, QtCore.SIGNAL("clicked(bool)"), self.on_rdb_clicked) # self.tblROISlist.setCellWidget((2 * cantchk) - 1, 0, grb_roi_operators) self.list_ands.append(rdband) self.list_ors.append(rdbor) self.tblROISlist.insertRow(2 * cantchk) self.tblROISlist.setCellWidget(2 * cantchk, 0, newchkroi) self.tblROISlist.resizeRowsToContents() #resizing objects sizeandrdb = rdband.geometry() sizeorrdb = rdbor.geometry() rdband.setGeometry(sizeandrdb.left(), sizeandrdb.top(), 5, sizeandrdb.height()) rdbor.setGeometry(sizeorrdb.left(), sizeorrdb.top(), 5, sizeorrdb.height()) #resizing checkbox sizecheckbox = newchkroi.geometry() newchkroi.setGeometry(sizecheckbox.left(), sizecheckbox.top(), sizetblROIs.width(), sizecheckbox.height()) def updateROItable(self, name, coordx=None, coordy=None, coordz=None, radius=None, color=None): """ Information of ROI is inserted in table when new ROI is created or when ROI selection changes in treeview. """ #show info of ROI in the table self.tblROI.item(0, 1).setText(name) if coordx is not None: self.disconnect_signals() self.dspbxcoord.setValue(coordx) self.dspbycoord.setValue(coordy) self.dspbzcoord.setValue(coordz) self.spbrad.setValue(radius) self.connect_signals() self.btncolor.setStyleSheet(u'background-color:%s' % color) def show_hide_rows(self, hide): """ Hides or shows rows from TableROI, depending on the type of ROI is selected on the tree. """ for i in range(3, self.tblROI.rowCount()): self.tblROI.setRowHidden(i, hide) self.tblROI.resizeRowsToContents() def on_chkroi_stateChanged(self, checked): """ Computing streamlines to show according to ROIs that are checked and their operators. """ last_chkd = 0 for pos in range(0, len(self.list_chkROIS)): if self.list_chkROIS[pos].isChecked(): self.tractome.activation_ROIs(pos, True) if pos != (len(self.list_chkROIS) - 1) and ( (self.list_ands[pos].isChecked() == False) and (self.list_ors[pos].isChecked() == False)): self.list_ands[pos].setChecked(True) else: self.tractome.activation_ROIs(pos, False, operator='and') if pos != (len(self.list_chkROIS) - 1): if self.list_ands[pos].isChecked(): self.list_ands[pos].setAutoExclusive(False) self.list_ands[pos].setChecked(False) self.list_ands[pos].setAutoExclusive(True) if self.list_ors[pos].isChecked(): self.list_ors[pos].setAutoExclusive(False) self.list_ors[pos].setChecked(False) self.list_ors[pos].setAutoExclusive(True) self.tractome.compute_streamlines_ROIS() self.glWidget.updateGL() def on_rdb_clicked(self, clicked): """ Computing streamlines to show according to ROIs that are checked and their operators. """ for pos in range(0, len(self.list_ands)): if self.list_ands[pos].isChecked(): self.tractome.activation_ROIs(pos, True, operator='and') if self.list_ors[pos].isChecked(): self.tractome.activation_ROIs(pos, True, operator='or') self.tractome.compute_streamlines_ROIS() self.glWidget.updateGL() @Slot(QtGui.QTableWidgetItem) def on_tblROI_itemChanged(self, item): """ Will change name of ROI if this is edited in the table. """ treeitem = self.tractnameitem.child(self.activeROI) if item is self.tblROI.item(0, 1): prev_name_roi = str(treeitem.text(0)) index = self.treeObject.indexFromItem(treeitem, 0) if index.isValid(): self.tractome.update_ROI(prev_name_roi, newname=item.text(), pos_activeroi=self.activeROI) treeitem.setText(0, item.text()) @Slot() def on_actionRe_Cluster_triggered(self): """ Re-cluster. """ self.spbRecluster.setEnabled(True) self.hSlReCluster.setEnabled(True) self.pbRecluster.setEnabled(True) def set_clustering_values(self): """ """ max, default = self.tractome.max_num_clusters() self.spbRecluster.setValue(default) self.spbRecluster.setRange(1, max) self.hSlReCluster.setValue(default) self.hSlReCluster.setMinimum(1) self.hSlReCluster.setMaximum(min(150, max)) def initSpincamera(self, angle=0.007): """ """ if self._spinCameraTimerInit: self.spinCameraTimer.timeout.disconnect() def rotate_camera(): self.glWidget.world.camera.rotate_around_focal(angle, "yup") self.glWidget.updateGL() self.spinCameraTimer.timeout.connect(rotate_camera) self._spinCameraTimerInit = True def spinCameraToggle(self): """ """ if not self.spinCameraTimer.isActive(): self.spinCameraTimer.start() else: self.spinCameraTimer.stop() def timerInit(self, interval=30): """ """ timer = QtCore.QTimer(self) timer.setInterval(interval) return timer def add_scene(self, scene): """ """ self.glWidget.world.add_scene(scene) def set_camera(self, camera): """ """ self.glWidget.world.camera = camera def refocus_camera(self): """ """ self.glWidget.world.refocus_camera() def update_light_position(self, x, y, z): """ """ if not self.glWidget.world.light is None: self.glWidget.world.update_lightposition(x, y, z) def screenshot(self, filename): """ Store current OpenGL context as image. """ self.glWidget.updateGL() self.glWidget.grabFrameBuffer().save(filename) def keyPressEvent(self, event): """ Handle all key press events. """ # print 'key pressed', event.key() key = event.key() # self.messages=empty_messages.copy() # self.messages['key_pressed']=key # self.glWidget.world.send_all_messages(self.messages) # F1: fullscreen # F2: next frame # F3: previous frame # F4: start rotating # F12: reset camera # Esc: close window if key == QtCore.Qt.Key_F1: if self.fullscreen: self.showNormal() else: self.showFullScreen() self.fullscreen = not self.fullscreen elif key == QtCore.Qt.Key_F2: self.glWidget.world.nextTimeFrame() elif key == QtCore.Qt.Key_F3: self.glWidget.world.previousTimeFrame() elif key == QtCore.Qt.Key_F12: self.glWidget.world.refocus_camera() self.glWidget.world.camera.update() self.glWidget.updateGL() elif key == QtCore.Qt.Key_F4: if (event.modifiers() & QtCore.Qt.ShiftModifier): self.initSpincamera(angle=-0.01) self.spinCameraToggle() else: self.initSpincamera(angle=0.01) self.spinCameraToggle() elif key == QtCore.Qt.Key_Escape: self.close() else: super(MainWindow, self).keyPressEvent(event) self.glWidget.updateGL()
class MyWindow(QtGui.QMainWindow): def __init__(self, filename=None): super(MyWindow, self).__init__() # Check and create captures directory if not os.path.isdir('captures'): os.makedirs('captures') self.tasks = np.linspace(0.0, 1.0, 6) # Create a simulation if filename is None: # self.prob = problems.SimJump() # self.prob = problems.GPBow() # self.prob = problems.GPStep() # self.prob = problems.GPKick() # self.prob = problems.GPJump() self.prob = problems.GPWalk() self.model = model.Model(self.prob.dim, self.tasks, 'linear') # params = np.array([0.8647, 0.6611, -0.6017, # -0.3276, -0.3781, 0.2489]) # params = np.array([1.0447, -0.8950, 0.0627, # -0.5505, 0.3516, 0.0807]) # params = 0.6 * (np.random.rand(self.prob.dim * 2) - 0.5) # params = np.array([0.1876, -0.9591, 0.3144, -0.7733, # 0, 0, 0, 0]) # params = np.array([0.14, 0.1, -0.15, 0.05, -0.1, # 0.0, 0.2, 0.0, -0.15, -0.1]) # params = np.array([0.5862, -0.7469, 0.6050, 0.8530, 0.4105, # 0.0083, 0.3875, -0.1697, -0.1931, -0.0878]) # params = np.array([-0.7862, 0.0, -0.2, 0.65, -0.2, # 0.0, 0.0, 0.0, 0.3, 0.0]) # params = np.array([0.7727, -0.9123, 0.4292, 1.1197, -0.2495, # -0.0013, -0.0478, 0.1797, 0.01035, 0.0142125]) # params = np.array([0.75, -0.9123, 0.4292, 0.9197, -0.2495, # Kck # -0.0013, -0.0478, 0.1797, 0.01035, 0.0142125]) # params = np.array([-1.0, 0.0, 0.0, 0.0, 0.0, # Walk # 1.6, 0.7, 0.3, 0.2, -0.3]) # params = np.array([-1.1595, 0.0236, -0.6677, 0.6955, 0.1316, # -0.2170, 0.3605, -0.0384, -0.2491, -0.8954]) params = np.zeros(8) params[0] = -1.0 # # For individual approach for walking # # lhs = np.array([-0.57016213, 0.90000273, -0.682361, -0.333242, # # 0.34159808, 0.04885952, 0.35506013]) # lhs = np.array([-0.80708114, 0.69733204, 0.10948302, 0.13978436, # 0.19853263, -0.43980252, 0.0329204]) # rhs = np.array([-0.91217336, 0.07142092, 0.15365855, 0.01285273, # 0.32689401, -0.20036001, 0.57687862]) # params[:7] = lhs # params[7:] = rhs - lhs # # params[:7] = 0.5 * (lhs + rhs) self.model.mean.set_params(params) else: import json with open(filename) as fp: data = json.load(fp) print data # Parse and print self.prob = eval(data['prob']) print('Problem: %s' % self.prob) mean_type = eval(data['mean_type']) print('Mean_type: %s' % mean_type) self.model = model.Model(self.prob.dim, self.tasks, mean_type) mean_params = eval('np.' + data['mean_params']) print('params: %s' % mean_params) self.model.mean.set_params(mean_params) print('model:\n%s\n' % self.model) print('Problem name = %s' % self.prob_name()) self.initUI() self.initActions() self.initToolbar() self.initMenu() self.idleTimer = QtCore.QTimer() self.idleTimer.timeout.connect(self.idleTimerEvent) self.idleTimer.start(0) self.renderTimer = QtCore.QTimer() self.renderTimer.timeout.connect(self.renderTimerEvent) self.renderTimer.start(25) self.cam0Event() self.taskSpinEvent(0.0) self.after_reset = True def initUI(self): self.setGeometry(0, 0, 1280, 720) # self.setWindowTitle('Toolbar') self.glwidget = GLWidget(self) self.glwidget.setGeometry(0, 30, 1280, 720) self.glwidget.prob = self.prob def initActions(self): # Create actions self.resetAction = QtGui.QAction('Reset', self) self.resetAction.triggered.connect(self.resetEvent) self.playAction = QtGui.QAction('Play', self) self.playAction.setCheckable(True) self.playAction.setShortcut('Space') self.animAction = QtGui.QAction('Anim', self) self.animAction.setCheckable(True) self.captureAction = QtGui.QAction('Capture', self) self.captureAction.setCheckable(True) self.movieAction = QtGui.QAction('Movie', self) self.movieAction.triggered.connect(self.movieEvent) self.screenshotAction = QtGui.QAction('Screenshot', self) self.screenshotAction.triggered.connect(self.screenshotEvent) self.exportAction = QtGui.QAction('Export .mtn', self) self.exportAction.triggered.connect(self.exportEvent) # Camera Menu self.cam0Action = QtGui.QAction('Camera0', self) self.cam0Action.triggered.connect(self.cam0Event) self.cam1Action = QtGui.QAction('Camera1', self) self.cam1Action.triggered.connect(self.cam1Event) self.printCamAction = QtGui.QAction('Print Camera', self) self.printCamAction.triggered.connect(self.printCamEvent) def initToolbar(self): # Create a toolbar self.toolbar = self.addToolBar('Control') self.toolbar.addAction(self.resetAction) self.taskSpin = QtGui.QDoubleSpinBox(self) self.taskSpin.setRange(0.0, 1.0) self.taskSpin.setDecimals(4) self.taskSpin.setSingleStep(0.2) self.taskSpin.valueChanged[float].connect(self.taskSpinEvent) self.toolbar.addWidget(self.taskSpin) self.toolbar.addAction(self.playAction) self.toolbar.addAction(self.animAction) self.toolbar.addSeparator() self.toolbar.addAction(self.screenshotAction) self.toolbar.addAction(self.captureAction) self.toolbar.addAction(self.movieAction) self.rangeSlider = QtGui.QSlider(QtCore.Qt.Horizontal, self) self.rangeSlider.valueChanged[int].connect(self.rangeSliderEvent) self.toolbar.addWidget(self.rangeSlider) def initMenu(self): menubar = self.menuBar() fileMenu = menubar.addMenu('&File') fileMenu.addSeparator() # Camera menu cameraMenu = menubar.addMenu('&Camera') cameraMenu.addAction(self.cam0Action) cameraMenu.addAction(self.cam1Action) cameraMenu.addSeparator() cameraMenu.addAction(self.printCamAction) # Recording menu recordingMenu = menubar.addMenu('&Recording') recordingMenu.addAction(self.screenshotAction) recordingMenu.addSeparator() recordingMenu.addAction(self.captureAction) recordingMenu.addAction(self.movieAction) recordingMenu.addSeparator() recordingMenu.addAction(self.exportAction) def idleTimerEvent(self): doCapture = False # Do animation if self.animAction.isChecked(): v = self.rangeSlider.value() + 1 if v <= self.rangeSlider.maximum(): self.rangeSlider.setValue(v) else: self.animAction.setChecked(False) capture_rate = 20 # if 'Walk' in repr(self.prob): # capture_rate = 50 if 'Jump' in repr(self.prob): capture_rate = 10 doCapture = (v % capture_rate == 1) # Do play elif self.playAction.isChecked(): result = self.prob.step() if result and self.after_reset: self.after_reset = False self.playAction.setChecked(False) if self.captureAction.isChecked() and doCapture: self.glwidget.capture(self.prob_name()) def renderTimerEvent(self): self.glwidget.updateGL() self.statusBar().showMessage(str(self.prob)) self.rangeSlider.setRange(0, self.prob.world.nframes - 1) def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Escape: print 'Escape key pressed! Bye.' self.close() def taskSpinEvent(self, value): task = self.taskSpin.value() self.pt = self.model.mean.point(task) print('task: %.4f point: %s' % (task, self.pt)) self.prob.set_params(self.pt) def rangeSliderEvent(self, value): i = value if i < self.prob.world.nframes: self.prob.world.set_frame(i) def screenshotEvent(self): self.glwidget.capture() def exportEvent(self): self.prob.export_mtn() def prob_name(self): ret = repr(self.prob) ret = ret.replace('problems.', '') ret = ret.replace('()', '') task = self.taskSpin.value() if hasattr(self, 'taskSpin') else 0 ret += '%.1f' % task return ret def movieEvent(self): name = self.prob_name() cmd = 'avconv -r 100 -i ./captures/%s.%%04d.png %s.mp4' % (name, name) print('cmd = %s' % cmd) os.system(cmd) # os.system('rm ./captures/*.png') def resetEvent(self): # self.prob.set_random_params() self.after_reset = True self.prob.reset() def cam0Event(self): print 'cam0Event' if 'Bioloid' in self.prob.skel_filename: if 'Walk' in self.prob_name(): self.glwidget.tb = Trackball(phi=-25.5, theta=6.86, zoom=1, rot=[-0.11399118462862251, -0.6947769785517393, -0.1156975272831452, 0.7006461603991319], trans=[-0.32000000000000084, -0.11000000000000004, -0.710000000000003]) elif 'Kick' in self.prob_name(): self.glwidget.tb = Trackball(phi=-25.5, theta=6.86, zoom=1, rot=[-0.11399118462862251, -0.6947769785517393, -0.1156975272831452, 0.7006461603991319], trans=[-0.32000000000000084, -0.11000000000000004, -0.910000000000003]) else: # self.glwidget.tb = Trackball(phi=-25.5, theta=6.86, zoom=1, # rot=[-0.11399118462862251, # -0.6947769785517393, # -0.1156975272831452, # 0.7006461603991319], # trans=[-0.06000000000000084, # -0.17000000000000004, # -0.710000000000003]) self.glwidget.tb = Trackball(phi=-2.7, theta=-0.95, zoom=1, rot=[-0.022588755364916124, -0.6948297028012123, -0.022955860419361884, 0.7184528242749483], trans=[-0.06000000000000084, -0.17000000000000004, -0.6800000000000029]) else: self.glwidget.tb = Trackball(phi=2.266, theta=-15.478, zoom=1, rot=[-0.09399048175876601, -0.612401798950921, -0.0675106984290682, 0.7820307740607462], trans=[-0.2700000000000008, -0.900000000000000005, -3.350000000000003]) def cam1Event(self): print 'cam1Event: frontview' if 'Bioloid' in self.prob.skel_filename: if 'Walk' in self.prob_name(): self.glwidget.tb = Trackball(phi=-25.5, theta=6.86, zoom=1, rot=[-0.11399118462862251, -0.6947769785517393, -0.1156975272831452, 0.7006461603991319], trans=[-0.32000000000000084, -0.11000000000000004, -0.970000000000003]) elif 'Kick' in self.prob_name(): self.glwidget.tb = Trackball(phi=-25.5, theta=6.86, zoom=1, rot=[-0.11399118462862251, -0.6947769785517393, -0.1156975272831452, 0.7006461603991319], trans=[-0.32000000000000084, -0.11000000000000004, -0.970000000000003]) else: self.glwidget.tb = Trackball(phi=-25.5, theta=6.86, zoom=1, rot=[-0.11399118462862251, -0.6947769785517393, -0.1156975272831452, 0.7006461603991319], trans=[-0.06000000000000084, -0.17000000000000004, -0.970000000000003]) def printCamEvent(self): print 'printCamEvent' print '----' print repr(self.glwidget.tb) print '----'