( self )
Add additional controls if JPG is selected
				Certain file formats accept additional options which can be specified as keyword
				arguments. Currently, only the 'jpeg' encoder accepts additional options, which are:

				quality - Defines the quality of the JPEG encoder as an integer ranging from 1 to 100.
							 Defaults to 85. Please note that JPEG quality is not a percentage and
							 definitions of quality vary widely.
				restart - Defines the restart interval for the JPEG encoder as a number of JPEG MCUs.
							 The actual restart interval used will be a multiple of the number of MCUs per row in the resulting image.
				thumbnail - Defines the size and quality of the thumbnail to embed in the Exif
								metadata. Specifying None disables thumbnail generation. Otherwise,
								specify a tuple of (width, height, quality). Defaults to (64, 48, 35).
				bayer - If True, the raw bayer data from the camera’s sensor is included in the
							Exif metadata.
Add additional controls if JPG is selected
				Certain file formats accept additional options which can be specified as keyword
				arguments. Currently, only the 'jpeg' encoder accepts additional options, which are:
Add additional controls if JPG is selected Certain file formats accept additional options which can be specified as keyword arguments . Currently only the jpeg encoder accepts additional options which are :
def BuildPage ( self ):
		#### TODO: 	Add Rotation. Cleanup and organize controls
		#			Add handling of Image Effect Params

		#----------- Select port for image captures ------------
		f1 = MyLabelFrame(self,'Select port for image captures',0,0,span=2)
		self.UseVidPort = MyBooleanVar(False)
		self.UseRadio = MyRadio(f1,'Use Still Port',False,self.UseVidPort,
					self.UseVideoPort,0,0,'W',tip=100)
		MyRadio(f1,'Use Video Port',True,self.UseVidPort,
					self.UseVideoPort,0,1,'W',tip=101)
		f2 = ttk.Frame(f1)			# Sub frame
		f2.grid(row=1,column=0,columnspan=4,sticky='NSEW')
		self.VideoDenoise = MyBooleanVar(True)
		b = ttk.Checkbutton(f2,text='Video denoise',variable=self.VideoDenoise,
			command=self.VideoDenoiseChecked)
		b.grid(row=1,column=0,sticky='NW',padx=5)
		ToolTip(b,msg=103)
		self.VideoStab = MyBooleanVar(False)
		b = ttk.Checkbutton(f2,text='Video stabilization',variable=self.VideoStab,
			command=self.VideoStabChecked)
		b.grid(row=1,column=1,sticky='NW')
		ToolTip(b, msg=105)
		self.ImageDenoise = MyBooleanVar(True)
		b = ttk.Checkbutton(f2,text='Image denoise',variable=self.ImageDenoise,
			command=self.ImageDenoiseChecked)
		b.grid(row=1,column=2,sticky='NW',padx=10)
		ToolTip(b, msg=104)

		#--------------- Picture/Video Capture Size ---------------
		f = MyLabelFrame(self,'Picture/Video capture size in pixels',1,0)
		#f.columnconfigure(0,weight=1)
		f1 = ttk.Frame(f)			# Sub frames to frame f
		f1.grid(row=1,column=0,sticky='NSEW')
		f1.columnconfigure(1,weight=1)
		self.UseFixedResolutions = BooleanVar()
		self.UseFixedResolutions.set(True)
		self.UseFixedResRadio = ttk.Radiobutton(f1,text='Use fixed:',
			variable=self.UseFixedResolutions,
			value=True,command=self.UseFixedResRadios,padding=(5,5,5,5))
		ToolTip(self.UseFixedResRadio,120)
		self.UseFixedResRadio.grid(row=0,column=0,sticky='NW')
		self.FixedResolutionsCombo = Combobox(f1,state='readonly',width=25)
		self.FixedResolutionsCombo.bind('<<ComboboxSelected>>',
			self.FixedResolutionChanged)
		self.FixedResolutionsCombo.grid(row=0,column=1,columnspan=3,sticky='W')
		ToolTip(self.FixedResolutionsCombo,121)
		#------------ Capture Width and Height ----------------
		# OrderedDict is used to ensure the keys stay in the same order as
		# entered. I want the combobox to display in this order
		#### TODO: 	Must check resolution and framerate and disable the Video
		# 			button if we exceed limits of the modes
		# Framerate 1-30 fps up to 1920x1080		16:9 aspect ratio
		# Framerate 1-15 fps up to 2592 x 1944		 4:3 aspect ratio
		# Framerate 0.1666 to 1 fps up to 2592 x 1944 4:3 aspect ratio
		# Framerate 1-42 fps up t0 1296 x 972 		 4:3 aspect ratio
		# Framerate 1-49 fps up to 1296 x 730		16:9 aspect ratio
		# Framerate 42.1 - 60 fps to 640 x 480		 4:3 aspect ratio
		# Framerate 60.1 - 90 fps to 640 x 480		 4:3 aspect ratio
		self.StandardResolutions = OrderedDict([ \
			('CGA', (320,200)),			('QVGA', (320,240)),
			('VGA', (640,480)),			('PAL', (768,576)),
			('480p', (720,480)),		('576p', (720,576)),
			('WVGA', (800,480)),		('SVGA', (800,600)),
			('FWVGA', (854,480)),		('WSVGA', (1024,600)),
			('XGA', (1024,768)),		('HD 720', (1280,720)),
			('WXGA_1', (1280,768)),		('WXGA_2', (1280,800)),
			('SXGA', (1280,1024)),		('SXGA+', (1400,1050)),
			('UXGA', (1600,1200)),		('WSXGA+', (1680,1050)),
			('HD 1080', (1920,1080)), 	('WUXGA', (1920,1200)),
			('2K', (2048,1080)),		('QXGA', (2048, 1536)),
			('WQXGA', (2560,1600)),		('MAX Resolution', (2592,1944)),
		   ])
		vals = []
		for key in self.StandardResolutions.keys():
			vals.append('%s: (%dx%d)' % (key, # Tabs not working?!!
							self.StandardResolutions[key][0],
							self.StandardResolutions[key][1]))
		self.FixedResolutionsCombo['values'] = vals
		self.FixedResolutionsCombo.current(10)

		f2 = ttk.Frame(f)		# subframe to frame f
		f2.grid(row=2,column=0,sticky='NSEW')
		f2.columnconfigure(2,weight=1)
		f2.columnconfigure(4,weight=1)
		b2 = ttk.Radiobutton(f2,text='Roll your own:',
			variable=self.UseFixedResolutions,
			value=False,command=self.UseFixedResRadios,padding=(5,5,5,5))
		b2.grid(row=1,column=0,sticky='NW')
		ToolTip(b2,122)

		Label(f2,text="Width:",anchor=E).grid(column=1,row=1,sticky='E',ipadx=3,ipady=3)
		Widths = []
		for i in range(1,82):
			Widths.append(32 * i) # Widths can be in 32 byte increments
		self.cb = MyComboBox ( f2, Widths, current=10,
			callback=self.ResolutionChanged, width=5, row=1, col=2,
			sticky='W', state='disabled', tip=123)

		Label(f2,text="Height:",anchor=E).grid(column=3,row=1,sticky='W',ipadx=5,ipady=3)
		Heights = []
		for i in range(1,123):
			Heights.append(16 * i)	# heights in 16 byte increments
		self.cb1 = MyComboBox ( f2, Heights, current=10,
			callback=self.ResolutionChanged, width=5, row=1, col=4,
			sticky='W', state='disabled', tip=124)

		ttk.Label(f2,text='Actual:').grid(row=2,column=1,sticky='E')
		self.WidthLabel = ttk.Label(f2,style='DataLabel.TLabel')
		self.WidthLabel.grid(row=2,column=2,sticky='W')
		ToolTip(self.WidthLabel,125)
		ttk.Label(f2,text='Actual:').grid(row=2,column=3,sticky='E')
		self.HeightLabel = ttk.Label(f2,style='DataLabel.TLabel')
		self.HeightLabel.grid(row=2,column=4,sticky='W')
		ToolTip(self.HeightLabel,126)

		Separator(f,orient=HORIZONTAL).grid(pady=5,row=3,column=0,
			columnspan=4,sticky='EW')

		#--------------- Zoom Region Before ----------------
		f4 = MyLabelFrame(f,'Zoom region of interest before taking '+
			'picture/video',4,0)
		#f4.columnconfigure(1,weight=1)
		#f4.columnconfigure(3,weight=1)
		Label(f4,text='X:').grid(row=0,column=0,sticky='E')
		self.Xzoom = ttk.Scale(f4,from_=0.0,to=0.94,orient='horizontal')
		self.Xzoom.grid(row=0,column=1,sticky='W',padx=5,pady=3)
		self.Xzoom.set(0.0)
		ToolTip(self.Xzoom,130)
		Label(f4,text='Y:').grid(row=0,column=2,sticky='E')
		self.Yzoom = ttk.Scale(f4,from_=0.0,to=0.94,orient='horizontal')
		self.Yzoom.grid(row=0,column=3,sticky='W',padx=5,pady=3)
		self.Yzoom.set(0.0)
		ToolTip(self.Yzoom,131)
		Label(f4,text='Width:').grid(row=1,column=0,sticky='E')
		self.Widthzoom = ttk.Scale(f4,from_=0.05,to=1.0,orient='horizontal')
		self.Widthzoom.grid(row=1,column=1,sticky='W',padx=5,pady=3)
		self.Widthzoom.set(1.0)
		ToolTip(self.Widthzoom,132)
		Label(f4,text='Height:').grid(row=1,column=2,sticky='E')
		self.Heightzoom = ttk.Scale(f4,from_=0.05,to=1.0,orient='horizontal')
		self.Heightzoom.grid(row=1,column=3,sticky='W',padx=5,pady=3)
		self.Heightzoom.set(1.0)
		ToolTip(self.Heightzoom,133)
		# WLW THIS IS A PROBLEM
		image = PIL.Image.open('Assets/reset.png') #.resize((16,16))
		self.resetImage = GetPhotoImage(image.resize((16,16)))
		self.ResetZoomButton = ttk.Button(f4,image=self.resetImage,
			command=self.ZoomReset)
		self.ResetZoomButton.grid(row=0,column=4,rowspan=2,sticky='W')
		ToolTip(self.ResetZoomButton,134)

		self.Xzoom.config(command=lambda newval,
			widget=self.Xzoom:self.Zoom(newval,widget))
		self.Yzoom.config(command=lambda newval,
			widget=self.Yzoom:self.Zoom(newval,widget))
		self.Widthzoom.config(command=lambda newval,
			widget=self.Widthzoom:self.Zoom(newval,widget))
		self.Heightzoom.config(command=lambda newval,
			widget=self.Heightzoom:self.Zoom(newval,widget))

		Separator(f,orient=HORIZONTAL).grid(pady=5,row=5,column=0,
			columnspan=3,sticky='EW')

		#--------------- Resize Image After ----------------
		f4 = MyLabelFrame(f,'Resize image after taking picture/video',6,0)
		#f4.columnconfigure(3,weight=1)
		#f4.columnconfigure(5,weight=1)

		b = MyBooleanVar(False)
		self.ResizeAfterNone = MyRadio(f4,'None (Default)',False,b,
			self.AllowImageResizeAfter,0,0,'W',pad=(0,5,0,5), tip=140)
		MyRadio(f4,'Resize',True,b,self.AllowImageResizeAfter,
					0,1,'W',pad=(5,5,0,5),tip=141)

		Label(f4,text="Width:",anchor=E).grid(column=2,row=0,sticky='E',ipadx=3,ipady=3)
		self.resizeWidthAfterCombo = MyComboBox ( f4, Widths, current=10,
			callback=self.ResizeAfterChanged, width=5, row=0, col=3,
			sticky='W', state='disabled', tip=142)

		Label(f4,text="Height:",anchor=E).grid(column=4,row=0,sticky='W',ipadx=5,ipady=3)
		self.resizeHeightAfterCombo = MyComboBox ( f4, Heights, current=10,
			callback=self.ResizeAfterChanged, width=5, row=0, col=5,
			sticky='W', state='disabled', tip=143)

		self.resizeAfter = None

		#--------------- Quick Adjustments ----------------
		f = MyLabelFrame(self,'Quick adjustments',2,0)
		#f.columnconfigure(2,weight=1)
		#-Brightness
		self.brightLabel, self.brightness, val = \
			self.SetupLabelCombo(f,'Brightness:',0,0,0, 100,
				self.CameraBrightnessChanged, self.camera.brightness )
		self.CameraBrightnessChanged(val)
		ToolTip(self.brightness,msg=150)
		#-Contrast
		self.contrastLabel, self.contrast, val = \
			self.SetupLabelCombo(f,'Contrast:',0,3,-100, 100,
				self.ContrastChanged, self.camera.contrast )
		self.ContrastChanged(val)
		ToolTip(self.contrast,msg=151)
		#-Saturation
		self.saturationLabel, self.saturation, val = \
			self.SetupLabelCombo(f,'Saturation:',1,0,-100, 100,
				self.SaturationChanged, self.camera.saturation, label='Sat' )
		self.SaturationChanged(val)
		ToolTip(self.saturation,msg=152)
		#-Sharpness
		self.sharpnessLabel, self.sharpness, val = \
			self.SetupLabelCombo(f,'Sharpness:',1,3,-100, 100,
				self.SharpnessChanged, self.camera.sharpness )
		self.SharpnessChanged(val)
		ToolTip(self.sharpness,msg=153)
		#-Reset
		#self.ResetGeneralButton = Button(f,image=self.resetImage,width=5,
			#command=self.ResetGeneralSliders)
		#self.ResetGeneralButton.grid(row=4,column=2,sticky='W',padx=5)
		#ToolTip(self.ResetGeneralButton,msg=154)

		#--------------- Image Effects ----------------
		f = MyLabelFrame(self,'Preprogrammed image effects',3,0)
		#f.columnconfigure(2,weight=1)

		v = MyBooleanVar(False)
		self.NoEffectsRadio = MyRadio(f,'None (Default)',False,v,
			self.EffectsChecked,0,0,'W',tip=160)
		MyRadio(f,'Select effect:',True,v,self.EffectsChecked,0,1,'W',
			tip=161)

		self.effects = Combobox(f,height=15,width=10,state='readonly')#,width=15)
		self.effects.grid(row=0,column=2,sticky='W')
		effects = list(self.camera.IMAGE_EFFECTS.keys())	# python 3 workaround
		effects.remove('none')
		effects.sort() #cmp=lambda x,y: cmp(x.lower(),y.lower())) # not python 3
		self.effects['values'] = effects
		self.effects.current(0)
		self.effects.bind('<<ComboboxSelected>>',self.EffectsChanged)
		ToolTip(self.effects, msg=162)

		self.ModParams = ttk.Button(f,text='Params...',
			command=self.ModifyEffectsParamsPressed,underline=0,padding=(5,3,5,3),width=8)
		self.ModParams.grid(row=0,column=3,sticky=EW,padx=5)
		ToolTip(self.ModParams, msg=163)
		self.EffectsChecked(False)
		'''
				Add additional controls if JPG is selected
				Certain file formats accept additional options which can be specified as keyword
				arguments. Currently, only the 'jpeg' encoder accepts additional options, which are:

				quality - Defines the quality of the JPEG encoder as an integer ranging from 1 to 100.
							 Defaults to 85. Please note that JPEG quality is not a percentage and
							 definitions of quality vary widely.
				restart - Defines the restart interval for the JPEG encoder as a number of JPEG MCUs.
							 The actual restart interval used will be a multiple of the number of MCUs per row in the resulting image.
				thumbnail - Defines the size and quality of the thumbnail to embed in the Exif
								metadata. Specifying None disables thumbnail generation. Otherwise,
								specify a tuple of (width, height, quality). Defaults to (64, 48, 35).
				bayer - If True, the raw bayer data from the camera’s sensor is included in the
							Exif metadata.
		'''
		#--------------- Flash Mode ---------------
		f = MyLabelFrame(self,'LED and Flash mode',4,0,span=4)
		#f.columnconfigure(3,weight=1)
		self.LedOn = MyBooleanVar(True)
		self.LedButton = ttk.Checkbutton(f,text='Led On (via GPIO pins)',
			variable=self.LedOn, command=self.LedOnChecked)
		self.LedButton.grid(row=0,column=0,sticky='NW',pady=5, columnspan=2)
		ToolTip(self.LedButton,msg=102)
		Label(f,text='Flash Mode:').grid(row=1,column=0,sticky='W')
		b = MyStringVar('off')
		self.FlashModeOffRadio = MyRadio(f,'Off (Default)','off',b,
			self.FlashModeButton,1,1,'W',tip=180)
		MyRadio(f,'Auto','auto',b,self.FlashModeButton,1,2,'W',tip=181)
		MyRadio(f,'Select:','set',b,self.FlashModeButton,1,3,'W',tip=182)
		# Use invoke() on radio button to force a command
		self.FlashModeCombo = Combobox(f,state='readonly',width=10)
		self.FlashModeCombo.grid(row=1,column=4,sticky='W')
		self.FlashModeCombo.bind('<<ComboboxSelected>>',self.FlashModeChanged)
		modes = list(self.camera.FLASH_MODES.keys())
		modes.remove('off')		# these two are handled by radio buttons
		modes.remove('auto')
		modes.sort() #cmp=lambda x,y: cmp(x.lower(),y.lower()))
		self.FlashModeCombo['values'] = modes
		self.FlashModeCombo.current(0)
		self.FlashModeCombo.config(state='disabled')
		ToolTip(self.FlashModeCombo,183)

		self.FixedResolutionChanged(None)
def BuildPage ( self ) : #### TODO: 	Add Rotation. Cleanup and organize controls #			Add handling of Image Effect Params #----------- Select port for image captures ------------ f1 = MyLabelFrame ( self , 'Select port for image captures' , 0 , 0 , span = 2 ) self . UseVidPort = MyBooleanVar ( False ) self . UseRadio = MyRadio ( f1 , 'Use Still Port' , False , self . UseVidPort , self . UseVideoPort , 0 , 0 , 'W' , tip = 100 ) MyRadio ( f1 , 'Use Video Port' , True , self . UseVidPort , self . UseVideoPort , 0 , 1 , 'W' , tip = 101 ) f2 = ttk . Frame ( f1 ) # Sub frame f2 . grid ( row = 1 , column = 0 , columnspan = 4 , sticky = 'NSEW' ) self . VideoDenoise = MyBooleanVar ( True ) b = ttk . Checkbutton ( f2 , text = 'Video denoise' , variable = self . VideoDenoise , command = self . VideoDenoiseChecked ) b . grid ( row = 1 , column = 0 , sticky = 'NW' , padx = 5 ) ToolTip ( b , msg = 103 ) self . VideoStab = MyBooleanVar ( False ) b = ttk . Checkbutton ( f2 , text = 'Video stabilization' , variable = self . VideoStab , command = self . VideoStabChecked ) b . grid ( row = 1 , column = 1 , sticky = 'NW' ) ToolTip ( b , msg = 105 ) self . ImageDenoise = MyBooleanVar ( True ) b = ttk . Checkbutton ( f2 , text = 'Image denoise' , variable = self . ImageDenoise , command = self . ImageDenoiseChecked ) b . grid ( row = 1 , column = 2 , sticky = 'NW' , padx = 10 ) ToolTip ( b , msg = 104 ) #--------------- Picture/Video Capture Size --------------- f = MyLabelFrame ( self , 'Picture/Video capture size in pixels' , 1 , 0 ) #f.columnconfigure(0,weight=1) f1 = ttk . Frame ( f ) # Sub frames to frame f f1 . grid ( row = 1 , column = 0 , sticky = 'NSEW' ) f1 . columnconfigure ( 1 , weight = 1 ) self . UseFixedResolutions = BooleanVar ( ) self . UseFixedResolutions . set ( True ) self . UseFixedResRadio = ttk . Radiobutton ( f1 , text = 'Use fixed:' , variable = self . UseFixedResolutions , value = True , command = self . UseFixedResRadios , padding = ( 5 , 5 , 5 , 5 ) ) ToolTip ( self . UseFixedResRadio , 120 ) self . UseFixedResRadio . grid ( row = 0 , column = 0 , sticky = 'NW' ) self . FixedResolutionsCombo = Combobox ( f1 , state = 'readonly' , width = 25 ) self . FixedResolutionsCombo . bind ( '<<ComboboxSelected>>' , self . FixedResolutionChanged ) self . FixedResolutionsCombo . grid ( row = 0 , column = 1 , columnspan = 3 , sticky = 'W' ) ToolTip ( self . FixedResolutionsCombo , 121 ) #------------ Capture Width and Height ---------------- # OrderedDict is used to ensure the keys stay in the same order as # entered. I want the combobox to display in this order #### TODO: 	Must check resolution and framerate and disable the Video # 			button if we exceed limits of the modes # Framerate 1-30 fps up to 1920x1080		16:9 aspect ratio # Framerate 1-15 fps up to 2592 x 1944		 4:3 aspect ratio # Framerate 0.1666 to 1 fps up to 2592 x 1944 4:3 aspect ratio # Framerate 1-42 fps up t0 1296 x 972 		 4:3 aspect ratio # Framerate 1-49 fps up to 1296 x 730		16:9 aspect ratio # Framerate 42.1 - 60 fps to 640 x 480		 4:3 aspect ratio # Framerate 60.1 - 90 fps to 640 x 480		 4:3 aspect ratio self . StandardResolutions = OrderedDict ( [ ( 'CGA' , ( 320 , 200 ) ) , ( 'QVGA' , ( 320 , 240 ) ) , ( 'VGA' , ( 640 , 480 ) ) , ( 'PAL' , ( 768 , 576 ) ) , ( '480p' , ( 720 , 480 ) ) , ( '576p' , ( 720 , 576 ) ) , ( 'WVGA' , ( 800 , 480 ) ) , ( 'SVGA' , ( 800 , 600 ) ) , ( 'FWVGA' , ( 854 , 480 ) ) , ( 'WSVGA' , ( 1024 , 600 ) ) , ( 'XGA' , ( 1024 , 768 ) ) , ( 'HD 720' , ( 1280 , 720 ) ) , ( 'WXGA_1' , ( 1280 , 768 ) ) , ( 'WXGA_2' , ( 1280 , 800 ) ) , ( 'SXGA' , ( 1280 , 1024 ) ) , ( 'SXGA+' , ( 1400 , 1050 ) ) , ( 'UXGA' , ( 1600 , 1200 ) ) , ( 'WSXGA+' , ( 1680 , 1050 ) ) , ( 'HD 1080' , ( 1920 , 1080 ) ) , ( 'WUXGA' , ( 1920 , 1200 ) ) , ( '2K' , ( 2048 , 1080 ) ) , ( 'QXGA' , ( 2048 , 1536 ) ) , ( 'WQXGA' , ( 2560 , 1600 ) ) , ( 'MAX Resolution' , ( 2592 , 1944 ) ) , ] ) vals = [ ] for key in self . StandardResolutions . keys ( ) : vals . append ( '%s: (%dx%d)' % ( key , # Tabs not working?!! self . StandardResolutions [ key ] [ 0 ] , self . StandardResolutions [ key ] [ 1 ] ) ) self . FixedResolutionsCombo [ 'values' ] = vals self . FixedResolutionsCombo . current ( 10 ) f2 = ttk . Frame ( f ) # subframe to frame f f2 . grid ( row = 2 , column = 0 , sticky = 'NSEW' ) f2 . columnconfigure ( 2 , weight = 1 ) f2 . columnconfigure ( 4 , weight = 1 ) b2 = ttk . Radiobutton ( f2 , text = 'Roll your own:' , variable = self . UseFixedResolutions , value = False , command = self . UseFixedResRadios , padding = ( 5 , 5 , 5 , 5 ) ) b2 . grid ( row = 1 , column = 0 , sticky = 'NW' ) ToolTip ( b2 , 122 ) Label ( f2 , text = "Width:" , anchor = E ) . grid ( column = 1 , row = 1 , sticky = 'E' , ipadx = 3 , ipady = 3 ) Widths = [ ] for i in range ( 1 , 82 ) : Widths . append ( 32 * i ) # Widths can be in 32 byte increments self . cb = MyComboBox ( f2 , Widths , current = 10 , callback = self . ResolutionChanged , width = 5 , row = 1 , col = 2 , sticky = 'W' , state = 'disabled' , tip = 123 ) Label ( f2 , text = "Height:" , anchor = E ) . grid ( column = 3 , row = 1 , sticky = 'W' , ipadx = 5 , ipady = 3 ) Heights = [ ] for i in range ( 1 , 123 ) : Heights . append ( 16 * i ) # heights in 16 byte increments self . cb1 = MyComboBox ( f2 , Heights , current = 10 , callback = self . ResolutionChanged , width = 5 , row = 1 , col = 4 , sticky = 'W' , state = 'disabled' , tip = 124 ) ttk . Label ( f2 , text = 'Actual:' ) . grid ( row = 2 , column = 1 , sticky = 'E' ) self . WidthLabel = ttk . Label ( f2 , style = 'DataLabel.TLabel' ) self . WidthLabel . grid ( row = 2 , column = 2 , sticky = 'W' ) ToolTip ( self . WidthLabel , 125 ) ttk . Label ( f2 , text = 'Actual:' ) . grid ( row = 2 , column = 3 , sticky = 'E' ) self . HeightLabel = ttk . Label ( f2 , style = 'DataLabel.TLabel' ) self . HeightLabel . grid ( row = 2 , column = 4 , sticky = 'W' ) ToolTip ( self . HeightLabel , 126 ) Separator ( f , orient = HORIZONTAL ) . grid ( pady = 5 , row = 3 , column = 0 , columnspan = 4 , sticky = 'EW' ) #--------------- Zoom Region Before ---------------- f4 = MyLabelFrame ( f , 'Zoom region of interest before taking ' + 'picture/video' , 4 , 0 ) #f4.columnconfigure(1,weight=1) #f4.columnconfigure(3,weight=1) Label ( f4 , text = 'X:' ) . grid ( row = 0 , column = 0 , sticky = 'E' ) self . Xzoom = ttk . Scale ( f4 , from_ = 0.0 , to = 0.94 , orient = 'horizontal' ) self . Xzoom . grid ( row = 0 , column = 1 , sticky = 'W' , padx = 5 , pady = 3 ) self . Xzoom . set ( 0.0 ) ToolTip ( self . Xzoom , 130 ) Label ( f4 , text = 'Y:' ) . grid ( row = 0 , column = 2 , sticky = 'E' ) self . Yzoom = ttk . Scale ( f4 , from_ = 0.0 , to = 0.94 , orient = 'horizontal' ) self . Yzoom . grid ( row = 0 , column = 3 , sticky = 'W' , padx = 5 , pady = 3 ) self . Yzoom . set ( 0.0 ) ToolTip ( self . Yzoom , 131 ) Label ( f4 , text = 'Width:' ) . grid ( row = 1 , column = 0 , sticky = 'E' ) self . Widthzoom = ttk . Scale ( f4 , from_ = 0.05 , to = 1.0 , orient = 'horizontal' ) self . Widthzoom . grid ( row = 1 , column = 1 , sticky = 'W' , padx = 5 , pady = 3 ) self . Widthzoom . set ( 1.0 ) ToolTip ( self . Widthzoom , 132 ) Label ( f4 , text = 'Height:' ) . grid ( row = 1 , column = 2 , sticky = 'E' ) self . Heightzoom = ttk . Scale ( f4 , from_ = 0.05 , to = 1.0 , orient = 'horizontal' ) self . Heightzoom . grid ( row = 1 , column = 3 , sticky = 'W' , padx = 5 , pady = 3 ) self . Heightzoom . set ( 1.0 ) ToolTip ( self . Heightzoom , 133 ) # WLW THIS IS A PROBLEM image = PIL . Image . open ( 'Assets/reset.png' ) #.resize((16,16)) self . resetImage = GetPhotoImage ( image . resize ( ( 16 , 16 ) ) ) self . ResetZoomButton = ttk . Button ( f4 , image = self . resetImage , command = self . ZoomReset ) self . ResetZoomButton . grid ( row = 0 , column = 4 , rowspan = 2 , sticky = 'W' ) ToolTip ( self . ResetZoomButton , 134 ) self . Xzoom . config ( command = lambda newval , widget = self . Xzoom : self . Zoom ( newval , widget ) ) self . Yzoom . config ( command = lambda newval , widget = self . Yzoom : self . Zoom ( newval , widget ) ) self . Widthzoom . config ( command = lambda newval , widget = self . Widthzoom : self . Zoom ( newval , widget ) ) self . Heightzoom . config ( command = lambda newval , widget = self . Heightzoom : self . Zoom ( newval , widget ) ) Separator ( f , orient = HORIZONTAL ) . grid ( pady = 5 , row = 5 , column = 0 , columnspan = 3 , sticky = 'EW' ) #--------------- Resize Image After ---------------- f4 = MyLabelFrame ( f , 'Resize image after taking picture/video' , 6 , 0 ) #f4.columnconfigure(3,weight=1) #f4.columnconfigure(5,weight=1) b = MyBooleanVar ( False ) self . ResizeAfterNone = MyRadio ( f4 , 'None (Default)' , False , b , self . AllowImageResizeAfter , 0 , 0 , 'W' , pad = ( 0 , 5 , 0 , 5 ) , tip = 140 ) MyRadio ( f4 , 'Resize' , True , b , self . AllowImageResizeAfter , 0 , 1 , 'W' , pad = ( 5 , 5 , 0 , 5 ) , tip = 141 ) Label ( f4 , text = "Width:" , anchor = E ) . grid ( column = 2 , row = 0 , sticky = 'E' , ipadx = 3 , ipady = 3 ) self . resizeWidthAfterCombo = MyComboBox ( f4 , Widths , current = 10 , callback = self . ResizeAfterChanged , width = 5 , row = 0 , col = 3 , sticky = 'W' , state = 'disabled' , tip = 142 ) Label ( f4 , text = "Height:" , anchor = E ) . grid ( column = 4 , row = 0 , sticky = 'W' , ipadx = 5 , ipady = 3 ) self . resizeHeightAfterCombo = MyComboBox ( f4 , Heights , current = 10 , callback = self . ResizeAfterChanged , width = 5 , row = 0 , col = 5 , sticky = 'W' , state = 'disabled' , tip = 143 ) self . resizeAfter = None #--------------- Quick Adjustments ---------------- f = MyLabelFrame ( self , 'Quick adjustments' , 2 , 0 ) #f.columnconfigure(2,weight=1) #-Brightness self . brightLabel , self . brightness , val = self . SetupLabelCombo ( f , 'Brightness:' , 0 , 0 , 0 , 100 , self . CameraBrightnessChanged , self . camera . brightness ) self . CameraBrightnessChanged ( val ) ToolTip ( self . brightness , msg = 150 ) #-Contrast self . contrastLabel , self . contrast , val = self . SetupLabelCombo ( f , 'Contrast:' , 0 , 3 , - 100 , 100 , self . ContrastChanged , self . camera . contrast ) self . ContrastChanged ( val ) ToolTip ( self . contrast , msg = 151 ) #-Saturation self . saturationLabel , self . saturation , val = self . SetupLabelCombo ( f , 'Saturation:' , 1 , 0 , - 100 , 100 , self . SaturationChanged , self . camera . saturation , label = 'Sat' ) self . SaturationChanged ( val ) ToolTip ( self . saturation , msg = 152 ) #-Sharpness self . sharpnessLabel , self . sharpness , val = self . SetupLabelCombo ( f , 'Sharpness:' , 1 , 3 , - 100 , 100 , self . SharpnessChanged , self . camera . sharpness ) self . SharpnessChanged ( val ) ToolTip ( self . sharpness , msg = 153 ) #-Reset #self.ResetGeneralButton = Button(f,image=self.resetImage,width=5, #command=self.ResetGeneralSliders) #self.ResetGeneralButton.grid(row=4,column=2,sticky='W',padx=5) #ToolTip(self.ResetGeneralButton,msg=154) #--------------- Image Effects ---------------- f = MyLabelFrame ( self , 'Preprogrammed image effects' , 3 , 0 ) #f.columnconfigure(2,weight=1) v = MyBooleanVar ( False ) self . NoEffectsRadio = MyRadio ( f , 'None (Default)' , False , v , self . EffectsChecked , 0 , 0 , 'W' , tip = 160 ) MyRadio ( f , 'Select effect:' , True , v , self . EffectsChecked , 0 , 1 , 'W' , tip = 161 ) self . effects = Combobox ( f , height = 15 , width = 10 , state = 'readonly' ) #,width=15) self . effects . grid ( row = 0 , column = 2 , sticky = 'W' ) effects = list ( self . camera . IMAGE_EFFECTS . keys ( ) ) # python 3 workaround effects . remove ( 'none' ) effects . sort ( ) #cmp=lambda x,y: cmp(x.lower(),y.lower())) # not python 3 self . effects [ 'values' ] = effects self . effects . current ( 0 ) self . effects . bind ( '<<ComboboxSelected>>' , self . EffectsChanged ) ToolTip ( self . effects , msg = 162 ) self . ModParams = ttk . Button ( f , text = 'Params...' , command = self . ModifyEffectsParamsPressed , underline = 0 , padding = ( 5 , 3 , 5 , 3 ) , width = 8 ) self . ModParams . grid ( row = 0 , column = 3 , sticky = EW , padx = 5 ) ToolTip ( self . ModParams , msg = 163 ) self . EffectsChecked ( False ) #--------------- Flash Mode --------------- f = MyLabelFrame ( self , 'LED and Flash mode' , 4 , 0 , span = 4 ) #f.columnconfigure(3,weight=1) self . LedOn = MyBooleanVar ( True ) self . LedButton = ttk . Checkbutton ( f , text = 'Led On (via GPIO pins)' , variable = self . LedOn , command = self . LedOnChecked ) self . LedButton . grid ( row = 0 , column = 0 , sticky = 'NW' , pady = 5 , columnspan = 2 ) ToolTip ( self . LedButton , msg = 102 ) Label ( f , text = 'Flash Mode:' ) . grid ( row = 1 , column = 0 , sticky = 'W' ) b = MyStringVar ( 'off' ) self . FlashModeOffRadio = MyRadio ( f , 'Off (Default)' , 'off' , b , self . FlashModeButton , 1 , 1 , 'W' , tip = 180 ) MyRadio ( f , 'Auto' , 'auto' , b , self . FlashModeButton , 1 , 2 , 'W' , tip = 181 ) MyRadio ( f , 'Select:' , 'set' , b , self . FlashModeButton , 1 , 3 , 'W' , tip = 182 ) # Use invoke() on radio button to force a command self . FlashModeCombo = Combobox ( f , state = 'readonly' , width = 10 ) self . FlashModeCombo . grid ( row = 1 , column = 4 , sticky = 'W' ) self . FlashModeCombo . bind ( '<<ComboboxSelected>>' , self . FlashModeChanged ) modes = list ( self . camera . FLASH_MODES . keys ( ) ) modes . remove ( 'off' ) # these two are handled by radio buttons modes . remove ( 'auto' ) modes . sort ( ) #cmp=lambda x,y: cmp(x.lower(),y.lower())) self . FlashModeCombo [ 'values' ] = modes self . FlashModeCombo . current ( 0 ) self . FlashModeCombo . config ( state = 'disabled' ) ToolTip ( self . FlashModeCombo , 183 ) self . FixedResolutionChanged ( None )