self.close()
else:
# Terminates the execution of the thread.
- # TODO: find out if we can do it with requestInterruption()
- self.thread.terminate()
+ self.thread.cancel()
self.progress.setLabelText('Canceled!')
self.progress.setCancelButtonText('Close')
import inspect
from traceback import format_exc
-from qtsalome import QApplication, pyqtSignal, QThread, Qt
+from qtsalome import QApplication, pyqtSignal, QThread, Qt, QTimer
from .geomrepairadv_logger import logger
# Set a variable for result
self.result = None
+ # Create a timer to terminate the thread if we can't exit gracefully
+ self.terminate_timer = QTimer()
+ self.terminate_timer.timeout.connect(self.terminate)
+ self.terminate_timer.setSingleShot(True)
+
def run(self):
"""
# Reset the progress when finished
self.progress_update.emit(100)
- self.work_completed.emit()
+
+ if not self.is_canceled():
+ self.work_completed.emit()
except Exception:
logger.error(format_exc())
QApplication.restoreOverrideCursor()
- def terminate(self):
+ def is_canceled(self):
"""
- Overrides default terminate() to add some clean up.
+ Returns true if the job was canceled.
+ """
+
+ return not self.progress_emitter.is_running
+
+
+ def cancel(self):
+ """
+ Cancels the job.
"""
- super().terminate()
+ # Set emitter to know that we canceled the job and
+ # can return from the running function gracefully.
+ self.progress_emitter.stop()
# Termination doesn't call a final block inside run()
QApplication.restoreOverrideCursor()
+ # Set a timer for a case when the running function
+ # doesn't use emitter or does so heavy job that it would take
+ # a lot of time for waiting and we need to terminate it.
+ self.terminate_timer.start(1000)
+
+
+ def terminate(self):
+ """
+ Overrides default terminate() to add some clean up.
+ """
+
+ # Check if the job is still running and need to be terminated
+ if self.isRunning():
+ logger.warning('Thread will be terminated!')
+ super().terminate()
+
def get_result(self):
"""
self.progress_percent = total_lines / 100.0
logger.debug('self.progress_percent: %f', self.progress_percent)
+ # Flag to check if we need to return from a function running in the thread
+ self.is_running = True
+
+
+ def stop(self):
+ """
+ Call this methid from the Worker for early return
+ from a function executed in the separated thread.
+ """
+
+ self.is_running = False
+
def emit(self):
"""
Call this methid in a target function to update a progress value
based on a currently executed line number.
+ Returns False if the job was stopped. Should be used in the algo scripts
+ for early return from the running function and finish the thread.
"""
line = inspect.getframeinfo(inspect.stack()[1][0]).lineno
logger.debug('progress_value: %d', progress_value)
self.progress_update.emit(int(progress_value))
+
+ return self.is_running
layout.setContentsMargins(0, 0, 0, 0)
# Min/max values widgets
- decimals = 2
+ decimals = 7
max_value = sys.float_info.max
- self._min_widget = DlgRef_1Spin_QTD('Tol Min', 0, decimals, max_value)
- self._max_widget = DlgRef_1Spin_QTD('Tol Max', 1000, decimals, max_value)
+ self._min_widget = DlgRef_1Spin_QTD('Tol Min', 0.001, decimals, max_value)
+ self._max_widget = DlgRef_1Spin_QTD('Tol Max', 0.015, decimals, max_value)
self._min_widget.SpinBox_DX.valueChanged.connect(self.on_limit_changed)
self._max_widget.SpinBox_DX.valueChanged.connect(self.on_limit_changed)
from qtsalome import QFileDialog, QApplication, pyqtSignal
import GEOM
-
salome.salome_init()
geompy = geomBuilder.New()
sleep(1)
if ('source_solid' not in args_dict or
- 'selected_ids' not in args_dict or
'result_name' not in args_dict or
- 'selection_level' not in args_dict or
'Tol_min' not in args_dict or
'Tol_max' not in args_dict or
'Debug' not in args_dict):
return False
source_solid = args_dict['source_solid']
- selected_ids = args_dict['selected_ids']
result_name = args_dict['result_name']
- selection_level = args_dict['selection_level']
- Tol_min = args_dict['Tol_min']
- Tol_max = args_dict['Tol_max']
+ minTol = args_dict['Tol_min']
+ maxTol = args_dict['Tol_max']
Debug = args_dict['Debug']
# Replace the lines below with an actual algorithm
logging.info('Received arguments:')
logging.info('\tsource_solid: %s', source_solid)
- logging.info('\tselected_ids: %s', selected_ids)
logging.info('\tresult_name: %s', result_name)
- logging.info('\tselection_level: %s', selection_level)
- logging.info('\Tol_min: %s', Tol_min)
- logging.info('\Tol_max: %s', Tol_max)
+ logging.info('\Tol_min: %s', minTol)
+ logging.info('\Tol_max: %s', maxTol)
logging.info('\Debug: %s', Debug)
progress_emitter.emit()
- sleep(1)
-
- # Make a group
- # geomBuilder uses their own types - geomBuilder.ShapeType
- geom_builder_types = { GEOM.EDGE : 'EDGE', GEOM.FACE : 'FACE', GEOM.SOLID : 'SOLID' }
- type_str = geom_builder_types[selection_level]
- shape_type = geompy.ShapeType[type_str]
- group = geompy.CreateGroup(source_solid, shape_type, theName = result_name)
-
- logging.info('Step1.')
- progress_emitter.emit()
- sleep(1)
- # Add sub-shapes into the group
- for subshape_id in selected_ids:
- geompy.AddObject(group, subshape_id)
-
- logging.info('Step2.')
- progress_emitter.emit()
+ for i in range(5000):
+ vertex = geompy.MakeVertex(0,0,0)
+ logging.info('\I: %s', i)
+ if not progress_emitter.emit():
+ return False
- return group
+ return vertex
def test():