def get_config_metadata(self, field_name, field_type): """ Returns dictionary of auxiliary information needed to render borders :param field_name:{str} field_name :param field_type: {str} field type :return: {dict} """ metadata_dict = {} metadata_dict['BorderColor'] = qcolor_to_rgba(Configuration.getSetting('BorderColor')) metadata_dict['ClusterBorderColor'] = qcolor_to_rgba(Configuration.getSetting('ClusterBorderColor')) metadata_dict['BoundingBoxColor'] = qcolor_to_rgba(Configuration.getSetting('BoundingBoxColor')) metadata_dict['AxesColor'] = qcolor_to_rgba(Configuration.getSetting('AxesColor')) metadata_dict['ContourColor'] = qcolor_to_rgba(Configuration.getSetting('ContourColor')) metadata_dict['WindowColor'] = qcolor_to_rgba(Configuration.getSetting('WindowColor')) # todo - fix color of fpp links metadata_dict['FPPLinksColor'] = qcolor_to_rgba(Configuration.getSetting('FPPLinksColor')) metadata_dict['ShowHorizontalAxesLabels'] = Configuration.getSetting('ShowHorizontalAxesLabels') metadata_dict['ShowVerticalAxesLabels'] = Configuration.getSetting('ShowVerticalAxesLabels') # type-color map type_color_map_dict = OrderedDict() config_type_color_map = Configuration.getSetting("TypeColorMap") for type_id, qt_color in list(config_type_color_map.items()): type_color_map_dict[type_id] = qcolor_to_rgba(qt_color) metadata_dict['TypeColorMap'] = type_color_map_dict return metadata_dict
def generate_cell_type_lookup_table(scene_metadata=None, actual_screenshot=False): """ generates cell type color lookup table. Depending whether we got metadata for actual screenshot or not we will use cell type color lookup table based on settings or we will use colors defined int he screenshot description file :param scene_metadata: scene metadata dict :param actual_screenshot: flag that tells if we got metadata for actual screenshot :return: """ if actual_screenshot: if scene_metadata is None: color_map = Configuration.getSetting("TypeColorMap") else: color_map = scene_metadata["TypeColorMap"] else: color_map = Configuration.getSetting("TypeColorMap") cell_type_color_lookup_table = vtk.vtkLookupTable() # You need to explicitly call Build() when constructing the LUT by hand cell_type_color_lookup_table.Build() cell_type_color_lookup_table.SetNumberOfTableValues(len(color_map)) cell_type_color_lookup_table.SetNumberOfColors(len(color_map)) for type_id, color_obj in list(color_map.items()): type_id = int(type_id) rgba = to_vtk_rgb(color_obj=color_obj) rgba.append(1.0) cell_type_color_lookup_table.SetTableValue(type_id, *rgba) return cell_type_color_lookup_table
def initParams(self): ''' this fcn stores current settings for all the keys of Configuration.Configuration.defaultConfigs as a self.paramCC3D dictionary ''' for key in Configuration.getSettingNameList(): self.paramCC3D[key] = Configuration.getSetting(key)
def set3DInvisibleTypes(self): ''' Initializes a dictionary self.invisibleCellTypes of invisible cell types - reads settings "Types3DInvisible" :return:None ''' self.colorMap = Configuration.getSetting("TypeColorMap") typesInvisibleStrTmp = str(Configuration.getSetting("Types3DInvisible")) # print "GOT ",typesInvisibleStrTmp if typesInvisibleStrTmp != self.typesInvisibleStr: self.typesInvisibleStr = str(Configuration.getSetting("Types3DInvisible")) typesInvisible = self.typesInvisibleStr.replace(" ", "") typesInvisible = typesInvisible.split(",") def cell_type_check(cell_type): try: cell_type_int = int(cell_type) if cell_type_int >= 0: return True else: return False except: False typesInvisible = [int(cell_type) for cell_type in typesInvisible if cell_type_check(cell_type)] # print "typesInvisibleVec=",typesInvisibleVec # turning list into a dictionary self.invisibleCellTypes.clear() for type in typesInvisible: self.invisibleCellTypes[int(type)] = 0
def currentTabChanged(self): Configuration.setSetting("TabIndex", self.tabWidget.currentIndex()) if self.tabWidget.currentIndex() == 2: if self.lastSelectedField >= 0: self.fieldComboBox.setCurrentIndex(self.lastSelectedField)
def store_gui_vis_config(self, scrData): """ Stores visualization settings such as cell borders, on/or cell on/off etc... :param scrData: {instance of ScreenshotDescriptionData} :return: None """ tvw = self.tabViewWidget() if tvw: tvw.update_active_window_vis_flags(self.screenshotGraphicsWidget) scrData.cell_borders_on = tvw.border_act.isChecked() scrData.cells_on = tvw.cells_act.isChecked() scrData.cluster_borders_on = tvw.cluster_border_act.isChecked() scrData.cell_glyphs_on = tvw.cell_glyphs_act.isChecked() scrData.fpp_links_on = tvw.fpp_links_act.isChecked() scrData.lattice_axes_on = Configuration.getSetting( 'ShowHorizontalAxesLabels') or Configuration.getSetting( 'ShowVerticalAxesLabels') scrData.lattice_axes_labels_on = Configuration.getSetting("ShowAxes") scrData.bounding_box_on = Configuration.getSetting("BoundingBoxOn") invisible_types = Configuration.getSetting("Types3DInvisible") invisible_types = invisible_types.strip() if invisible_types: scrData.invisible_types = list( [int(x) for x in invisible_types.split(',')]) else: scrData.invisible_types = []
def get_min_max_metadata(self, scene_metadata, field_name): """ Returns dictionary with the following entries: 1. MinRangeFixed 2. MaxRangeFixed 3. MinRange 3. MaxRange :param scene_metadata:{dict} metadata dictionary :param field_name: {str} field name :return: {dict} """ out_dict = {} if set(['MinRangeFixed', "MaxRangeFixed", 'MinRange', 'MaxRange']).issubset(set(scene_metadata.keys())): min_range_fixed = scene_metadata['MinRangeFixed'] max_range_fixed = scene_metadata['MaxRangeFixed'] min_range = scene_metadata['MinRange'] max_range = scene_metadata['MaxRange'] else: min_range_fixed = Configuration.getSetting("MinRangeFixed", field_name) max_range_fixed = Configuration.getSetting("MaxRangeFixed", field_name) min_range = Configuration.getSetting("MinRange", field_name) max_range = Configuration.getSetting("MaxRange", field_name) out_dict['MinRangeFixed'] = min_range_fixed out_dict['MaxRangeFixed'] = max_range_fixed out_dict['MinRange'] = min_range out_dict['MaxRange'] = max_range return out_dict
def add_3d_screenshot(self, _plotName, _plotType, _camera, metadata=None): # called from GraphicsFrameWidget if len(self.screenshotDataDict) > self.maxNumberOfScreenshots: print("MAX NUMBER OF SCREENSHOTS HAS BEEN REACHED") scrData = ScreenshotData() scrData.spaceDimension = "3D" scrData.plotData = (_plotName, _plotType) x_size = Configuration.getSetting("Screenshot_X") y_size = Configuration.getSetting("Screenshot_Y") (scrName, scrCoreName) = self.produce_screenshot_name(scrData) okToAddScreenshot = True for name in self.screenshotDataDict: scrDataFromDict = self.screenshotDataDict[name] if scrDataFromDict.screenshotCoreName == scrCoreName and scrDataFromDict.spaceDimension == "3D": if scrDataFromDict.compareCameras(_camera): print("CAMERAS ARE THE SAME") okToAddScreenshot = False break else: print("CAMERAS ARE DIFFERENT") if (not scrName in self.screenshotDataDict) and okToAddScreenshot: scrData.screenshotName = scrName scrData.screenshotCoreName = scrCoreName scrData.screenshotGraphicsWidget = self.screenshotGraphicsWidget scrData.win_width = x_size scrData.win_height = y_size if metadata is not None: scrData.metadata = metadata tvw = self.tabViewWidget() if tvw: tvw.update_active_window_vis_flags(self.screenshotGraphicsWidget) self.store_gui_vis_config(scrData=scrData) scrData.extractCameraInfo(_camera) # on linux there is a problem with X-server/Qt/QVTK implementation and calling resize right after additional QVTK # is created causes segfault so possible "solution" is to do resize right before taking screenshot. # It causes flicker but does not cause segfault # User should NOT close or minimize this "empty" window (on Linux anyway). if sys.platform == 'Linux' or sys.platform == 'linux' or sys.platform == 'linux2': self.screenshotDataDict[scrData.screenshotName] = scrData self.screenshotCounter3D += 1 else: self.screenshotDataDict[scrData.screenshotName] = scrData self.screenshotCounter3D += 1 else: print("Screenshot ", scrCoreName, " with current camera settings already exists. " \ "You need to rotate camera i.e. rotate picture " \ "using mouse to take additional screenshot") # serializing all screenshots self.serialize_screenshot_data()
def closeEvent(self, event=None): Configuration.setSetting('ScreenGeometry', self.get_current_screen_geometry_settings()) # this saves size and position of window when player is opened and closed without running simulation self.save_ui_geometry() self.viewmanager.closeEventSimpleTabView(event)
def toggleModelEditor(self, flag): """ Private slot to handle the toggle of the Model Editor window. """ self.modelAct.setChecked(flag) Configuration.setSetting('DisplayModelEditor', flag) self.__toggleWindowFlag(self.modelEditorDock, flag)
def __initActions(self): """ Private method to define the user interface actions. """ self.actions = [] self.toolbarFileAct = QAction("&File", self) self.toolbarFileAct.setCheckable(True) self.toolbarFileAct.setChecked(True) self.actions.append(self.toolbarFileAct) self.toolbarViewAct = QAction("&View", self) self.toolbarViewAct.setCheckable(True) self.toolbarViewAct.setChecked(True) self.actions.append(self.toolbarViewAct) self.toolbarSimAct = QAction("&Simulation", self) self.toolbarSimAct.setCheckable(True) self.toolbarSimAct.setChecked(True) self.actions.append(self.toolbarSimAct) self.toolbarSimAct.setShortcut(Qt.CTRL + Qt.Key_M) self.modelAct = QAction("&Model Editor", self) self.modelAct.setCheckable(True) if Configuration.getSetting('DisplayModelEditor'): self.modelAct.setChecked(True) self.modelAct.triggered.connect(self.toggleModelEditor) self.actions.append(self.modelAct) self.pluginsAct = QAction("&Plugins", self) self.pluginsAct.setCheckable(True) self.pluginsAct.setChecked(True) self.pluginsAct.triggered.connect(self.__toggleCPlugins) self.actions.append(self.pluginsAct) self.latticeDataAct = QAction("&Lattice Data", self) self.latticeDataAct.setCheckable(True) if Configuration.getSetting('DisplayLatticeData'): self.latticeDataAct.setChecked(True) self.latticeDataAct.triggered.connect(self.toggleLatticeData) self.actions.append(self.latticeDataAct) self.consoleAct = QAction("&Console", self) self.consoleAct.setCheckable(True) self.toggleConsole(Configuration.getSetting('DisplayConsole')) if Configuration.getSetting('DisplayConsole'): self.consoleAct.setChecked(True) self.consoleAct.triggered.connect(self.toggleConsole) self.actions.append(self.consoleAct)
def toggleLatticeData(self, flag): """ Private slot to handle the toggle of the Plugins window. """ self.latticeDataAct.setChecked(flag) Configuration.setSetting('DisplayLatticeData', flag) self.__toggleWindowFlag(self.latticeDataDock, flag)
def updateColorButton(self, btn, name): ''' updates button (btn) and changes corresponding color setting (name).Shows Choose color dialog ''' color = self.selectColor(btn, Configuration.getSetting(name)) # which of the following is necessary at this point? Configuration.setSetting(name, color) self.paramCC3D[name] = color
def changeButtonColor(self, _btn, _color, _settingName): ''' assigns color (_color) to button (_btn) and changes corresponding color setting (_settingName). Does not shows Choose color dialog ''' if _color.isValid(): size = _btn.iconSize() pm = QPixmap(size.width(), size.height()) pm.fill(_color) _btn.setIcon(QIcon(pm)) Configuration.setSetting(_settingName, _color)
def toggle_cell_type_color_map_dock(self, flag): """ :param flag: :return: """ print('toggle_cell_type_color_map_dock') self.cell_type_color_map_act.setChecked(flag) self.__toggleWindowFlag(self.cell_type_color_map_dock, flag) Configuration.setSetting('DisplayCellTypeColorMap', flag)
def add_2d_screenshot(self, _plotName, _plotType, _projection, _projectionPosition, _camera, metadata=None): if len(self.screenshotDataDict) > self.maxNumberOfScreenshots: print("MAX NUMBER OF SCREENSHOTS HAS BEEN REACHED") scrData = ScreenshotData() scrData.spaceDimension = "2D" scrData.plotData = (_plotName, _plotType) x_size = Configuration.getSetting("Screenshot_X") y_size = Configuration.getSetting("Screenshot_Y") scrData.projection = _projection scrData.projectionPosition = int(_projectionPosition) # import pdb; pdb.set_trace() (scrName, scrCoreName) = self.produce_screenshot_name(scrData) print(" add2DScreenshot(): THIS IS NEW SCRSHOT NAME", scrName) # e.g. Cell_Field_CellField_2D_XY_150 if not scrName in self.screenshotDataDict: scrData.screenshotName = scrName scrData.screenshotCoreName = scrCoreName scrData.screenshotGraphicsWidget = self.screenshotGraphicsWidget # = GraphicsFrameWidget (rf. __init__) scrData.win_width = x_size scrData.win_height = y_size if metadata is not None: scrData.metadata = metadata tvw = self.tabViewWidget() if tvw: tvw.update_active_window_vis_flags(self.screenshotGraphicsWidget) self.store_gui_vis_config(scrData=scrData) scrData.extractCameraInfo(_camera) # so "camera" icon (save images) remembers camera view # on linux there is a problem with X-server/Qt/QVTK implementation and calling resize right after additional QVTK # is created causes segfault so possible "solution" is to do resize right before taking screenshot. # It causes flicker but does not cause segfault. # User should NOT close or minimize this "empty" window (on Linux anyway). if sys.platform == 'Linux' or sys.platform == 'linux' or sys.platform == 'linux2': # pass self.screenshotDataDict[scrData.screenshotName] = scrData else: self.screenshotDataDict[scrData.screenshotName] = scrData else: print("Screenshot ", scrName, " already exists") # serializing all screenshots self.serialize_screenshot_data()
def on_outputLocationButton_clicked(self): currentOutputDir = Configuration.getSetting('OutputLocation') dirName = QFileDialog.getExistingDirectory( self, "Specify CC3D Output Directory", currentOutputDir, QFileDialog.ShowDirsOnly) dirName = str(dirName) dirName.rstrip() print("dirName=", dirName) if dirName == "": return dirName = os.path.abspath(dirName) self.outputLocationLineEdit.setText(dirName) Configuration.setSetting('OutputLocation', dirName)
def toggleConsole(self, flag): """ Private slot to handle the toggle of the Log Viewer window. if self.layout == "DockWindows": self.__toggleWindow(self.logViewerDock) else: self.__toggleWindow(self.logViewer) """ self.consoleAct.setChecked(flag) Configuration.setSetting('DisplayConsole', flag) # TODO self.__toggleWindowFlag(self.consoleDock, flag)
def get_vector_field_metadata(self, field_name, field_type): """ Returns dictionary of auxiliary information needed to render a give scene :param field_name:{str} field_name :param field_type: {str} field type :return: {dict} """ metadata_dict = self.get_con_field_metadata(field_name=field_name, field_type=field_type) metadata_dict['ArrowLength'] = Configuration.getSetting('ArrowLength', field_name) metadata_dict['FixedArrowColorOn'] = Configuration.getSetting('FixedArrowColorOn', field_name) metadata_dict['ArrowColor'] = qcolor_to_rgba(Configuration.getSetting('ArrowColor', field_name)) metadata_dict['ScaleArrowsOn'] = Configuration.getSetting('ScaleArrowsOn', field_name) return metadata_dict
def restore_plots_layout(self): ''' This function restores plot layout - it is called from CompuCellSetup.py inside mainLoopNewPlayer function :return: None ''' windows_layout_dict = Configuration.getSetting('WindowsLayout') if not windows_layout_dict: return for winId, win in self.vm.win_inventory.getWindowsItems(PLOT_WINDOW_LABEL): plot_frame_widget = win.widget() plot_interface = plot_frame_widget.plotInterface() # plot_frame_widget.plotInterface is a weakref if not plot_interface: # if weakref to plot_interface is None we ignore such window continue if str(plot_interface.title) in list(windows_layout_dict.keys()): window_data_dict = windows_layout_dict[str(plot_interface.title)] gwd = GraphicsWindowData() gwd.fromDict(window_data_dict) if gwd.winType != 'plot': return win.resize(gwd.winSize) win.move(gwd.winPosition) win.setWindowTitle(plot_interface.title)
def check_version(self, check_interval=-1, display_no_update_info=False): """ This function checks if new CC3D version is available :return:None """ # here we decide whether the information about no new updates is displayed or not. For automatic update checks # this information should not be displayed. For manual update checks we need to inform the user # that there are no updates self.display_no_update_info = display_no_update_info # determine if check is necessary - for now we check every week in order not to bother users with too many checks last_version_check_date = Configuration.getSetting( 'LastVersionCheckDate') today = datetime.date.today() today_date_str = today.strftime('%Y%m%d') old_date = datetime.date(int(last_version_check_date[:4]), int(last_version_check_date[4:6]), int(last_version_check_date[6:])) t_delta = today - old_date if t_delta.days < check_interval: # check for CC3D recently return else: print('WILL DO THE CHECK') version_fetcher = WebFetcher(_parent=self) version_fetcher.gotWebContentSignal.connect(self.process_version_check) version_fetcher.fetch("http://www.compucell3d.org/current_version")
def Render(self): color = Configuration.getSetting("WindowColor") self.ren.SetBackground( float(color.red()) / 255, float(color.green()) / 255, float(color.blue()) / 255) self.qvtkWidget.Render()
def setScreenUpdateFrequency(self): import cc3d.player5.Configuration as Configuration try: self.screenUpdateFrequency = Configuration.getSetting( "ScreenUpdateFrequency") except: print('SIMTHREAD: Could not access configuration.')
def restoreSingleWindow(self, plotWindowInterface): ''' Restores size and position of a single, just-added plot window :param plotWindowInterface: an insance of PlotWindowInterface - can be fetchet from PlotFrameWidget using PlotFrameWidgetInstance.plotInterface :return: None ''' windows_layout_dict = Configuration.getSetting('WindowsLayout') # print 'windowsLayoutDict=', windowsLayoutDict if not windows_layout_dict: return if str(plotWindowInterface.title) in list(windows_layout_dict.keys()): window_data_dict = windows_layout_dict[str(plotWindowInterface.title)] gwd = GraphicsWindowData() gwd.fromDict(window_data_dict) if gwd.winType != 'plot': return plot_window = self.vm.lastActiveRealWindow plot_window.resize(gwd.winSize) plot_window.move(gwd.winPosition) plot_window.setWindowTitle(plotWindowInterface.title)
def __init__(self, parent=None, originatingWidget=None): QtWidgets.QFrame.__init__(self, parent) self.is_screenshot_widget = False self.qvtkWidget = QVTKRenderWindowInteractor(self) # a QWidget self.setAttribute(QtCore.Qt.WA_DeleteOnClose) # MDIFIX self.parentWidget = ref(originatingWidget) self.plane = None self.planePos = None self.lineEdit = QtWidgets.QLineEdit() self.init_cross_section_actions() self.cstb = self.initCrossSectionToolbar() layout = QtWidgets.QBoxLayout(QtWidgets.QBoxLayout.TopToBottom) layout.addWidget(self.cstb) layout.addWidget(self.qvtkWidget) self.setLayout(layout) self.setMinimumSize(100, 100) # needs to be defined to resize smaller than 400x400 self.resize(600, 600) self.qvtkWidget.Initialize() self.qvtkWidget.Start() # todo 5 - adding generic drawer self.gd = GenericDrawer() self.gd.set_interactive_camera_flag(True) self.gd.set_pixelized_cartesian_scene(Configuration.getSetting("PixelizedCartesianFields")) # placeholder for current screenshot data self.current_screenshot_data = None # placeholder for currently used basic simulation data self.current_bsd = None self.camera2D = self.gd.get_active_camera() self.camera3D = self.gd.get_renderer().MakeCamera() self.renWin = self.qvtkWidget.GetRenderWindow() self.renWin.AddRenderer(self.gd.get_renderer()) self.metadata_fetcher_dict = { 'CellField': self.get_cell_field_metadata, 'ConField': self.get_con_field_metadata, 'ScalarField': self.get_con_field_metadata, 'ScalarFieldCellLevel': self.get_con_field_metadata, 'VectorField': self.get_vector_field_metadata, 'VectorFieldCellLevel': self.get_vector_field_metadata, }
def __createViewManager(self): self.zitems = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2.0, 3.0, 4.0, 8.0] self.viewmanager = SimpleTabView( self) # ViewManager.factory(self, self) self.viewmanager.set_recent_simulation_file( str(Configuration.getSetting("RecentFile"))) self.viewmanager.setZoomItems(self.zitems) # self.viewmanager.setOrientation(Qt.Vertical) self.setCentralWidget(self.viewmanager)
def populateLookupTable( self): # rwh: why is this method in both View & Model? self.drawModel.populateLookupTable( ) # have to update colors in model objects colorMap = Configuration.getSetting("TypeColorMap") for key in list(colorMap.keys()): r = colorMap[key].red() g = colorMap[key].green() b = colorMap[key].blue() self.lut.SetTableValue(key, self.toVTKColor(r), self.toVTKColor(g), self.toVTKColor(b), 1.0)
def get_con_field_metadata(self, field_name, field_type): """ Returns dictionary of auxiliary information needed to render a give scene :param field_name:{str} field_name :param field_type: {str} field type :return: {dict} """ # metadata_dict = {} metadata_dict = self.get_config_metadata(field_name=field_name, field_type=field_type) con_field_name = field_name metadata_dict['MinRangeFixed'] = Configuration.getSetting("MinRangeFixed", con_field_name) metadata_dict['MaxRangeFixed'] = Configuration.getSetting("MaxRangeFixed", con_field_name) metadata_dict['MinRange'] = Configuration.getSetting("MinRange", con_field_name) metadata_dict['MaxRange'] = Configuration.getSetting("MaxRange", con_field_name) metadata_dict['ContoursOn'] = Configuration.getSetting("ContoursOn", con_field_name) metadata_dict['NumberOfContourLines'] = Configuration.getSetting("NumberOfContourLines", field_name) metadata_dict['ScalarIsoValues'] = cs_string_to_typed_list( Configuration.getSetting("ScalarIsoValues", field_name)) metadata_dict['LegendEnable'] = Configuration.getSetting("LegendEnable", field_name) metadata_dict['DisplayMinMaxInfo'] = Configuration.getSetting("DisplayMinMaxInfo") return metadata_dict
def populateLookupTable(self): # print MODULENAME,' populateLookupTable()' colorMap = Configuration.getSetting("TypeColorMap") # print MODULENAME,' populateLookupTable(): len(colorMap)=',len(colorMap) self.celltypeLUT.SetNumberOfTableValues(len(colorMap)) self.celltypeLUT.SetNumberOfColors(len(colorMap)) # lutGlyph.SetTableValue(5, 1,0,0, 1.0) # SetTableValue (vtkIdType indx, double r, double g, double b, double a=1.0) # lutGlyph.SetTableValue(8, 0,1,1, 1.0) # SetTableValue (vtkIdType indx, double r, double g, double b, double a=1.0) for key in list(colorMap.keys()): r = colorMap[key].red() g = colorMap[key].green() b = colorMap[key].blue() self.celltypeLUT.SetTableValue(key, self.toVTKColor(r), self.toVTKColor(g), self.toVTKColor(b), 1.0) # print " type=",key," red=",r," green=",g," blue=",b # print " type=",key," (VTK) red=",self.toVTKColor(r)," green=",self.toVTKColor(g)," blue=",self.toVTKColor(b) # self.qvtkWidget.repaint() self.celltypeLUT.Build() self.celltypeLUTMax = self.celltypeLUT.GetNumberOfTableValues() - 1 # cell types = [0,max] self.celltypeLUT.SetTableRange(0, self.celltypeLUTMax)
def check_version(self, check_interval=-1, display_no_update_info=False): """ This function checks if new CC3D version is available :return:None """ # checking if cc3d is running in nanohub. if it is do not check for updates (it'll be blocked by their firewall) if 'NANOHUB_SIM' in environ: return # here we decide whether the information about no new updates is displayed or not. For automatic update checks # this information should not be displayed. For manual update checks we need to inform the user # that there are no updates self.display_no_update_info = display_no_update_info # determine if check is necessary - for now we check every week in order # not to bother users with too many checks last_version_check_date = Configuration.getSetting( 'LastVersionCheckDate') today = datetime.date.today() old_date = datetime.date(int(last_version_check_date[:4]), int(last_version_check_date[4:6]), int(last_version_check_date[6:])) t_delta = today - old_date if t_delta.days < check_interval: # check for CC3D recently return else: print('WILL DO THE CHECK') if requests_web_fetcher_available: self.version_fetcher = WebFetcherRequests(_parent=self) else: self.version_fetcher = WebFetcher(_parent=self) self.version_fetcher.gotWebContentSignal.connect( self.process_version_check) self.version_fetcher.fetch(self.cc3d_updates_url)