class MaskRadiiPreviewDialog(MaskPreviewDialog): def _createPreview(self, frame): """ Should be implemented by subclasses to create the items preview. """ from pyworkflow.gui.matplotlib_image import MaskPreview if self.innerRadius is None: self.innerRadius = 0 if self.outerRadius is None or self.outerRadius == -1 or self.outerRadius > self.dim_par/2: self.outerRadius = int(self.dim_par/2) self.preview = MaskPreview(frame, self.dim, label=self.previewLabel, outerRadius=int(self.outerRadius)*self.ratio, innerRadius=self.innerRadius*self.ratio) self.preview.grid(row=0, column=0) def _createControls(self, frame): self.radiusSliderOut = LabelSlider(frame, 'Outer radius', from_=0, to=int(self.dim_par/2), value=self.outerRadius, step=1, callback=lambda a, b, c:self.updateRadius(self.radiusSliderOut, self.radiusSliderIn)) self.radiusSliderOut.grid(row=0, column=0, padx=5, pady=5) self.radiusSliderIn = LabelSlider(frame, 'Inner radius', from_=0, to=int(self.dim_par/2), value=self.innerRadius, step=1, callback=lambda a, b, c:self.updateRadius(self.radiusSliderOut, self.radiusSliderIn)) self.radiusSliderIn.grid(row=1, column=0, padx=5, pady=5) def updateRadius(self, radiusSliderOut, radiusSliderIn): self.preview.updateMask(outerRadius=radiusSliderOut.get() * self.ratio, innerRadius=radiusSliderIn.get() * self.ratio) def getRadius(self, radiusSlider): return int(radiusSlider.get())
def addFreqSlider(self, label, value, col): slider = LabelSlider(self.freqFrame, label, from_=0, to=0.5, value=value, callback=lambda a, b, c: self.updateFreqRing()) slider.grid(row=0, column=col, padx=5, pady=5) return slider
def addFreqSlider(self, label, value, col): slider = LabelSlider(self.freqFrame, label, from_=0, to=0.5, value=value, callback=None) slider.grid(row=0, column=col, padx=5, pady=5) return slider
def addFreqSlider(self, label, value, col): fromValue = self.sliFrom toValue = self.sliTo if self.unit == UNIT_ANGSTROM: fromValue = self.sliTo toValue = self.sliFrom slider = LabelSlider(self.freqFrame, label, from_=fromValue, to=toValue, step=self.step , value=value, callback=lambda a, b, c:self.updateFilteredImage()) slider.grid(row=0, column=col, padx=5, pady=5) return slider
class MaskPreviewDialog(ImagePreviewDialog): def _beforePreview(self): self.dim = 256 self.samplingRate = 1 self.unit = getattr(self, 'unit', UNIT_PIXEL) if self.unit != UNIT_PIXEL: self.samplingRate = self.firstItem.getSamplingRate() self.dim_par = self.firstItem.getDim()[0] * self.samplingRate self.ratio = self.dim / float(self.dim_par) self.previewLabel = 'Central slice' def _createPreview(self, frame): """ Should be implemented by subclasses to create the items preview. """ from pyworkflow.gui.matplotlib_image import MaskPreview if self.maskRadius == -1: self.iniRadius = self.dim_par / 2 else: self.iniRadius = self.maskRadius self.preview = MaskPreview(frame, self.dim, label=self.previewLabel, outerRadius=self.iniRadius * self.ratio) self.preview.grid(row=0, column=0) def _createControls(self, frame): self.addRadiusBox(frame) def addRadiusBox(self, parent): self.radiusSlider = LabelSlider( parent, 'Outer radius (%s)' % self.unit, from_=0, to=int(self.dim_par / 2), value=self.iniRadius, step=self.samplingRate, callback=lambda a, b, c: self.updateRadius()) self.radiusSlider.grid(row=0, column=0, padx=5, pady=5) def updateRadius(self): self.preview.updateMask(self.radiusSlider.get() * self.ratio) def getRadius(self): return int(self.radiusSlider.get())
class MaskRadiiPreviewDialog(MaskPreviewDialog): def _createPreview(self, frame): """ Should be implemented by subclasses to create the items preview. """ from pyworkflow.gui.matplotlib_image import MaskPreview if self.innerRadius is None: self.innerRadius = 0 if self.outerRadius is None or self.outerRadius == -1 or self.outerRadius > self.dim_par / 2: self.outerRadius = int(self.dim_par / 2) self.preview = MaskPreview(frame, self.dim, label=self.previewLabel, outerRadius=int(self.outerRadius) * self.ratio, innerRadius=self.innerRadius * self.ratio) self.preview.grid(row=0, column=0) def _createControls(self, frame): self.radiusSliderOut = LabelSlider( frame, 'Outer radius', from_=0, to=int(self.dim_par / 2), value=self.outerRadius, step=1, callback=lambda a, b, c: self.updateRadius(self.radiusSliderOut, self.radiusSliderIn)) self.radiusSliderOut.grid(row=0, column=0, padx=5, pady=5) self.radiusSliderIn = LabelSlider( frame, 'Inner radius', from_=0, to=int(self.dim_par / 2), value=self.innerRadius, step=1, callback=lambda a, b, c: self.updateRadius(self.radiusSliderOut, self.radiusSliderIn)) self.radiusSliderIn.grid(row=1, column=0, padx=5, pady=5) def updateRadius(self, radiusSliderOut, radiusSliderIn): self.preview.updateMask(outerRadius=radiusSliderOut.get() * self.ratio, innerRadius=radiusSliderIn.get() * self.ratio) def getRadius(self, radiusSlider): return int(radiusSlider.get())
class MaskPreviewDialog(ImagePreviewDialog): def _beforePreview(self): self.dim = 256 self.samplingRate = 1 self.unit = getattr(self, 'unit', UNIT_PIXEL) if self.unit != UNIT_PIXEL: self.samplingRate = self.firstItem.getSamplingRate() self.dim_par = self.firstItem.getDim()[0] * self.samplingRate self.ratio = self.dim / float(self.dim_par) self.previewLabel = 'Central slice' def _createPreview(self, frame): """ Should be implemented by subclasses to create the items preview. """ from pyworkflow.gui.matplotlib_image import MaskPreview if self.maskRadius == -1: self.iniRadius = self.dim_par/2 else: self.iniRadius = self.maskRadius self.preview = MaskPreview(frame, self.dim, label=self.previewLabel, outerRadius=self.iniRadius*self.ratio) self.preview.grid(row=0, column=0) def _createControls(self, frame): self.addRadiusBox(frame) def addRadiusBox(self, parent): self.radiusSlider = LabelSlider(parent, 'Outer radius (%s)' % self.unit, from_=0, to=int(self.dim_par/2), value=self.iniRadius, step=self.samplingRate, callback=lambda a, b, c:self.updateRadius()) self.radiusSlider.grid(row=0, column=0, padx=5, pady=5) def updateRadius(self): self.preview.updateMask(self.radiusSlider.get() * self.ratio) def getRadius(self): return int(self.radiusSlider.get())
class PreWhiteningDialog(dialog.Dialog): def __init__(self, form, workingDir, **kwargs): """ Params: parent: parent windows of the dialog. provider: the TreeProvider to populate items tree. """ self.form = form self.workingDir = workingDir buttons = [('Select', dialog.RESULT_YES), ('Cancel', dialog.RESULT_CANCEL)] dialog.Dialog.__init__(self, form.root, "Pre-whitening", buttons=buttons, default='Select', **kwargs) def _runBeforePreWhitening(self): prot = self.form.protocol # Convert input volumes ih = ImageHandler() if prot.useSplitVolume: ih.convert(prot.volumeHalf1.get(), join(self.workingDir, 'volume1.map')) ih.convert(prot.volumeHalf2.get(), join(self.workingDir, 'volume2.map')) else: ih.convert(prot.inputVolume.get(), join(self.workingDir, 'volume1.map')) self.results = prot.runResmap(self.workingDir, wizardMode=True) def _runPreWhitening(self, newElbowAngstrom, newRampWeight): # Add resmap libraries to the path results = self.results self.figure.clear() myCreatePrewhiteningFigure(results, self.figure, newElbowAngstrom, newRampWeight) def body(self, bodyFrame): figFrame = FigureFrame(bodyFrame, figsize=(18, 9)) figFrame.grid(row=0, column=0, columnspan=5) #self._runBeforePreWhitening(self.prot) dialog.FlashMessage(self.form.root, "Running Pre-Whitening tool...", func=self._runBeforePreWhitening) results = self.results self.figure = figFrame.getFigure() #plt.figure(figsize=(18, 9)) self._runPreWhitening(results['newElbowAngstrom'], results['newRampWeight']) #bodyFrame.config() bodyFrame.columnconfigure(0, weight=1) bodyFrame.rowconfigure(0, weight=1) controlsFrame = tk.Frame(bodyFrame) controlsFrame.grid(row=1, column=0) self.elbowSlider = LabelSlider(controlsFrame, "Angstroms", from_=2.1*results['vxSize'], to=100, value=results['newElbowAngstrom']) self.elbowSlider.grid(row=1, column=0, padx=5, pady=5) self.rampSlider = LabelSlider(controlsFrame, "Ramp weight", from_=0.0, to=1., value=results['newRampWeight']) self.rampSlider.grid(row=1, column=1, padx=5, pady=5) self.updateBtn = HotButton(controlsFrame, " Update ", command=self._onUpdate, tooltip="Update plots with new pre-whitening parameters.") self.updateBtn.grid(row=1, column=2, padx=10, pady=5) def getElbowValue(self): return self.elbowSlider.get() def getRampValue(self): return self.rampSlider.get() def _onUpdate(self, e=None): self._runPreWhitening(self.getElbowValue(), self.getRampValue())
class PreWhiteningDialog(dialog.Dialog): def __init__(self, form, workingDir, **kwargs): """ Params: parent: parent windows of the dialog. provider: the TreeProvider to populate items tree. """ self.form = form self.workingDir = workingDir buttons = [('Select', dialog.RESULT_YES), ('Cancel', dialog.RESULT_CANCEL)] dialog.Dialog.__init__(self, form.root, "Pre-whitening", buttons=buttons, default='Select', **kwargs) def _runBeforePreWhitening(self): prot = self.form.protocol # Convert input volumes ih = ImageHandler() if prot.useSplitVolume: ih.convert(prot.volumeHalf1.get(), join(self.workingDir, 'volume1.map')) ih.convert(prot.volumeHalf2.get(), join(self.workingDir, 'volume2.map')) else: ih.convert(prot.inputVolume.get(), join(self.workingDir, 'volume1.map')) self.results = prot.runResmap(self.workingDir, wizardMode=True) def _runPreWhitening(self, newElbowAngstrom, newRampWeight): # Add resmap libraries to the path results = self.results self.figure.clear() myCreatePrewhiteningFigure(results, self.figure, newElbowAngstrom, newRampWeight) def body(self, bodyFrame): figFrame = FigureFrame(bodyFrame, figsize=(18, 9)) figFrame.grid(row=0, column=0, columnspan=5) #self._runBeforePreWhitening(self.prot) dialog.FlashMessage(self.form.root, "Running Pre-Whitening tool...", func=self._runBeforePreWhitening) results = self.results self.figure = figFrame.getFigure() #plt.figure(figsize=(18, 9)) self._runPreWhitening(results['newElbowAngstrom'], results['newRampWeight']) #bodyFrame.config() bodyFrame.columnconfigure(0, weight=1) bodyFrame.rowconfigure(0, weight=1) controlsFrame = tk.Frame(bodyFrame) controlsFrame.grid(row=1, column=0) self.elbowSlider = LabelSlider(controlsFrame, "Angstroms", from_=2.1 * results['vxSize'], to=100, value=results['newElbowAngstrom']) self.elbowSlider.grid(row=1, column=0, padx=5, pady=5) self.rampSlider = LabelSlider(controlsFrame, "Ramp weight", from_=0.0, to=1., value=results['newRampWeight']) self.rampSlider.grid(row=1, column=1, padx=5, pady=5) self.updateBtn = HotButton( controlsFrame, " Update ", command=self._onUpdate, tooltip="Update plots with new pre-whitening parameters.") self.updateBtn.grid(row=1, column=2, padx=10, pady=5) def getElbowValue(self): return self.elbowSlider.get() def getRampValue(self): return self.rampSlider.get() def _onUpdate(self, e=None): self._runPreWhitening(self.getElbowValue(), self.getRampValue())
def addFreqSlider(self, label, value, col): slider = LabelSlider(self.freqFrame, label, from_=0, to=0.5, value=value, callback=lambda a, b, c:self.updateFreqRing()) slider.grid(row=0, column=col, padx=5, pady=5) return slider
class MaskPreviewDialog(ImagePreviewDialog): def _beforePreview(self): self.dim = 256 self.unit = getattr(self, 'unit', emcts.UNIT_PIXEL) self.samplingRate = self.firstItem.getSamplingRate() self.dim_par = self.firstItem.getDim()[0] self.ratio = self.dim / float(self.dim_par) self.previewLabel = 'Central slice' def _createPreview(self, frame): """ Should be implemented by subclasses to create the items preview. """ # Insert the corresponding explanation text self.expText.updateExpText(emcts.CIRCLE_MASK_WIZ_MSG) from pyworkflow.gui.matplotlib_image import MaskPreview if self.maskRadius == -1: self.iniRadius = self.dim_par / 2 else: self.iniRadius = self.maskRadius if self.unit == emcts.UNIT_ANGSTROM: self.iniRadius = self.iniRadius / self.samplingRate listeners = { "<Button-4>": self.makeBigger, "<Button-5>": self.makeSmaller } self.preview = MaskPreview(frame, self.dim, label=self.previewLabel, listenersDict=listeners) self.preview.grid(row=1, column=0) def makeBigger(self, event): new_val = self.iniRadius + 1 if new_val <= self.dim_par / 2: # Don't make the mask bigger unless the is equal or lower than the max self.iniRadius = self.iniRadius + 1 self.manageMaskVals() def makeSmaller(self, event): new_val = self.iniRadius - 1 if new_val >= 1: # Don't make the mask smaller unless the radius is equal or greater than 1 self.iniRadius = self.iniRadius - 1 self.manageMaskVals() def manageMaskVals(self): # Set the ring slider in case it comes from the mouse wheel self.setRadius(self.radiusSlider, self.iniRadius) # Show values self.showValues(self.hfVar, self.radiusSlider) # Update mask self.preview.updateMask(self.iniRadius * self.ratio) def _createControls(self, frame): self.addRadiusBox(frame) self.hfVar = tk.StringVar() self.hfLabel = tk.Label(frame, textvariable=self.hfVar, width=20) self.hfLabel.grid(row=0, column=1, sticky='NSE', padx=5, pady=5) self.manageMaskVals() def addRadiusBox(self, parent): self.radiusSlider = LabelSlider( parent, 'Mask radius', from_=1, to=int(self.dim_par / 2), value=self.iniRadius, step=1, length=150, showvalue=0, callback=lambda a, b, c: self.updateSliderRadius()) self.radiusSlider.grid(row=0, column=0, sticky='NEWS') def updateSliderRadius(self): new_val = self.getRadius(self.radiusSlider) # Carry out the action only if the slider is clicked & dragged (prevent from minimal variations when the mouse # is on the slider but not clicking on it) if abs(new_val - self.iniRadius) >= 1: self.iniRadius = new_val self.manageMaskVals() def showValues(self, var2set, radiusSlider): """ Show the values selected for the inner and outer radius. If the units are angstroms (sampling_rate = 1, it will show only one value to avoid redundancies """ pixVal = self.getRadius(radiusSlider) if self.samplingRate == 1: var2set.set('{:6.1f} {}'.format(pixVal, emcts.UNIT_PIXEL)) else: var2set.set('{:5.0f} pix | {:6.1f} {}'.format( pixVal, self.getRadiusAngstroms(radiusSlider), emcts.UNIT_ANGSTROM_SYMBOL)) @staticmethod def getRadius(radiusSlider): return radiusSlider.get() @staticmethod def setRadius(radiusSlider, val): radiusSlider.slider.set(val) def getRadiusAngstroms(self, radiusSlider): return convertPixToLength(self.samplingRate, radiusSlider.get())
class CtfDialog(DownsampleDialog): def _createRightPreview(self, rightFrame): self.isInnerRad = True listeners = { "<Button-4>": self.makeBigger, "<Button-5>": self.makeSmaller, "<Up>": self.upKeyPress, "<Down>": self.downKeyPress } from pyworkflow.gui.matplotlib_image import PsdPreview return PsdPreview(rightFrame, self.dim, self.lf, self.hf, label=self.rightPreviewLabel, listenersDict=listeners) def downKeyPress(self, event): self.isInnerRad = False self.highlightOuterSlider() def upKeyPress(self, event): self.isInnerRad = True self.highlightInnerSlider() def highlightOuterSlider(self): self.hfSlider.highlightLabel() self.lfSlider.removeHighlightFromLabel() def highlightInnerSlider(self): self.lfSlider.highlightLabel() self.hfSlider.removeHighlightFromLabel() def makeBigger(self, event): self.isMakingBigger = True if self.isInnerRad: self.lf = self.lf + self.step else: new_val = self.hf + self.step if new_val <= 0.5: # Don't make the mask bigger unless the is equal or lower than the max self.hf = new_val self.manageMaskVals() def makeSmaller(self, event): self.isMakingBigger = False if self.isInnerRad: new_val = self.lf - self.step if new_val >= 0: self.lf = new_val else: self.hf = self.hf - self.step self.manageMaskVals() def manageMaskVals(self): if self.isMakingBigger: if self.isInnerRad and self.lf >= self.hf: # Inner ring can't be bigger than outer ring # Subtract one step to go back to the nearest lower value self.lf = self.hf - self.step else: if not self.isInnerRad and self.hf <= self.lf: # Outer ring can't be smaller than inner # ring # Add one step to go back to the nearest higher value self.hf = self.lf + self.step # Set the ring sliders in case it comes from the mouse wheel self.setFreq(self.lfSlider, self.lf) self.setFreq(self.hfSlider, self.hf) # Show values self.showValues(self.hfVar, self.hfSlider) self.showValues(self.lfVar, self.lfSlider) # Update mask self.rightPreview.updateFreq(self.lf, self.hf) def _showInAngstroms(self): return getattr(self, 'showInAngstroms', False) def _createControls(self, frame): frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=1) frame.columnconfigure(2, weight=1) self.step = 0.01 self.freqFrame = ttk.LabelFrame(frame, text="Frequencies") self.freqFrame.columnconfigure(0, weight=3) self.freqFrame.grid(row=0, column=2, sticky='news') self.lfSlider = LabelSlider( self.freqFrame, 'Low freq', value=self.lf, from_=0.01, to=0.5, length=178, labelWidth=13, step=self.step, showvalue=0, callback=lambda a, b, c: self.updateSliderInnerRadius(), ) self.lfSlider.grid(row=0, column=0, padx=5, pady=5, sticky='news') self.lfSlider.highlightLabel() self.hfSlider = LabelSlider( self.freqFrame, 'High freq', value=self.lf, from_=0.01, to=0.5, length=178, labelWidth=13, step=self.step, showvalue=0, callback=lambda a, b, c: self.updateSliderOuterRadius(), ) self.hfSlider.grid(row=1, column=0, padx=5, pady=5, sticky='news') # Pack and configure low freq slider self.lfVar = tk.StringVar() self.lfLabel = tk.Label(self.freqFrame, textvariable=self.lfVar, width=26) self.lfLabel.grid(row=0, column=1, sticky='nse', padx=5, pady=5) # Pack and configure high freq slider self.hfVar = tk.StringVar() self.hfLabel = tk.Label(self.freqFrame, textvariable=self.hfVar, width=26) self.hfLabel.grid(row=1, column=1, sticky='nse', padx=5, pady=5) # Update both mask and sliders with the initial values self.manageMaskVals() # def getDownsample(self): # return 1.0 # Micrograph previously downsample, not taken into account here def updateFreqRing(self): self.rightPreview.updateFreq(self.getLowFreq(), self.getHighFreq()) self.showValues(self.lfVar, self.lfSlider) self.showValues(self.hfVar, self.hfSlider) def updateSliderOuterRadius(self): new_val = self.getFreq(self.hfSlider) # Carry out the action only if the slider is clicked & dragged (prevent from minimal variations when the mouse # is on the slider but not clicking on it) if abs(new_val - self.hf) >= self.step: self.highlightOuterSlider() self.isInnerRad = False self.isMakingBigger = False # Check if the user is making the ring bigger if new_val > self.hf: self.isMakingBigger = True self.hf = new_val self.manageMaskVals() def updateSliderInnerRadius(self): new_val = self.getFreq(self.lfSlider) # Highlight only if the slider is clicked & dragged (prevent from minimal variations when the mouse is on the # slider but not clicking on it) if abs(new_val - self.lf) >= self.step: self.highlightInnerSlider() self.isInnerRad = True self.isMakingBigger = False # Check if the user is making the ring bigger if new_val > self.lf: self.isMakingBigger = True self.lf = new_val self.manageMaskVals() def showValues(self, var2set, labSlider): """ Show the values selected for the inner and outer radius. If the units are angstroms (sampling_rate = 1, it will show only one value to avoid redundancies """ sr = self.firstItem.getSamplingRate() freqVal = max(self.getFreq(labSlider), 0.0001) # avoid division by zero if sr == 1: var2set.set('{:2.2f} {}'.format(labSlider.slider.get(), emcts.UNIT_PIXEL)) else: var2set.set('{:2.2f} rad/{} | {:5.1f} {}'.format( labSlider.slider.get(), emcts.UNIT_ANGSTROM_SYMBOL, self.getDownsample() * sr / freqVal, emcts.UNIT_ANGSTROM_SYMBOL)) def getLowFreq(self): return self.lfSlider.get() def getHighFreq(self): return self.hfSlider.get() @staticmethod def getFreq(freqSlider): return freqSlider.get() @staticmethod def setFreq(freqSlider, val): freqSlider.slider.set(val)
class MaskRadiiPreviewDialog(MaskPreviewDialog): def _createPreview(self, frame): """ Should be implemented by subclasses to create the items preview. """ # Insert the corresponding explanation text self.expText.updateExpText(emcts.RING_MASK_WIZ_MSG) from pyworkflow.gui.matplotlib_image import MaskPreview if self.innerRadius is None: self.innerRadius = 1 if self.outerRadius is None or self.outerRadius == -1 or self.outerRadius > self.dim_par / 2: self.outerRadius = int(self.dim_par / 2) if self.unit == emcts.UNIT_ANGSTROM: self.innerRadius = self.innerRadius / self.samplingRate self.outerRadius = self.innerRadius / self.samplingRate listeners = { "<Button-4>": self.makeBigger, "<Button-5>": self.makeSmaller, "<Up>": self.upKeyPress, "<Down>": self.downKeyPress } self.preview = MaskPreview(frame, self.dim, label=self.previewLabel, listenersDict=listeners) self.preview.grid(row=1, column=0) def upKeyPress(self, event): self.isInnerRad = False self.highlightOuterSlider() def downKeyPress(self, event): self.isInnerRad = True self.highlightInnerSlider() def highlightOuterSlider(self): self.radiusSliderOut.highlightLabel() self.radiusSliderIn.removeHighlightFromLabel() def highlightInnerSlider(self): self.radiusSliderIn.highlightLabel() self.radiusSliderOut.removeHighlightFromLabel() def makeBigger(self, event): self.isMakingBigger = True if self.isInnerRad: self.innerRadius = self.innerRadius + self.step else: new_val = self.outerRadius + self.step if new_val <= int( self.dim_par / 2 ): # Don't make the mask bigger unless the is equal or lower than the max self.outerRadius = new_val self.manageMaskVals() def makeSmaller(self, event): self.isMakingBigger = False if self.isInnerRad: new_val = self.innerRadius - self.step if new_val >= 0: self.innerRadius = new_val else: self.outerRadius = self.outerRadius - self.step self.manageMaskVals() def manageMaskVals(self): if self.isMakingBigger: if self.isInnerRad and self.innerRadius >= self.outerRadius: # Inner ring can't be bigger than outer ring # Subtract one step to go back to the nearest lower value self.innerRadius = self.outerRadius - self.step else: if not self.isInnerRad and self.outerRadius <= self.innerRadius: # Outer ring can't be smaller than inner # ring # Add one step to go back to the nearest higher value self.outerRadius = self.innerRadius + self.step # Set the ring sliders in case it comes from the mouse wheel self.setRadius(self.radiusSliderIn, self.innerRadius) self.setRadius(self.radiusSliderOut, self.outerRadius) # Show values self.showValues(self.orVar, self.radiusSliderOut) self.showValues(self.irVar, self.radiusSliderIn) # Update mask self.preview.updateMask(self.outerRadius * self.ratio, self.innerRadius * self.ratio) def _createControls(self, frame): self.step = 1 to = int(self.dim_par / 2) self.radiusSliderOut = LabelSlider( frame, 'Outer radius', from_=1, to=to, value=self.outerRadius, step=self.step, callback=lambda a, b, c: self.updateSliderOuterRadius(), length=150, showvalue=0) self.radiusSliderOut.highlightLabel() self.orVar = tk.StringVar() self.orLabel = tk.Label(frame, textvariable=self.orVar, width=20) self.radiusSliderIn = LabelSlider( frame, 'Inner radius', from_=1, to=to, value=self.innerRadius, step=self.step, callback=lambda a, b, c: self.updateSliderInnerRadius(), length=150, showvalue=0) self.irVar = tk.StringVar() self.irLabel = tk.Label(frame, textvariable=self.irVar, width=20) # Pack and configure outer radius slider self.radiusSliderOut.grid(row=0, column=0, sticky='NEWS') self.radiusSliderOut.columnconfigure(0, weight=1) self.orLabel.grid(row=0, column=1, sticky='NSE', padx=5, pady=5) self.orLabel.columnconfigure(0, weight=1) # Pack and configure inner radius slider self.radiusSliderIn.grid(row=1, column=0, sticky='NEWS') self.radiusSliderIn.columnconfigure(0, weight=1) self.irLabel.grid(row=1, column=1, sticky='NSE', padx=5, pady=5) self.irLabel.columnconfigure(0, weight=1) # Update both mask and sliders with the initial values self.manageMaskVals() def updateSliderOuterRadius(self): new_val = self.getRadius(self.radiusSliderOut) # Carry out the action only if the slider is clicked & dragged (prevent from minimal variations when the mouse # is on the slider but not clicking on it) if abs(new_val - self.outerRadius) >= self.step: self.highlightOuterSlider() self.isInnerRad = False self.isMakingBigger = False # Check if the user is making the ring bigger if new_val > self.outerRadius: self.isMakingBigger = True self.outerRadius = new_val self.manageMaskVals() def updateSliderInnerRadius(self): new_val = self.getRadius(self.radiusSliderIn) # Highlight only if the slider is clicked & dragged (prevent from minimal variations when the mouse is on the # slider but not clicking on it) if abs(new_val - self.innerRadius) >= self.step: self.highlightInnerSlider() self.isInnerRad = True self.isMakingBigger = False # Check if the user is making the ring bigger if new_val > self.innerRadius: self.isMakingBigger = True self.innerRadius = new_val self.manageMaskVals()