@@ -53,6 +53,19 @@ class Preview(Enum):
5353 DRM = DrmPreview
5454 QT = QtPreview
5555 QTGL = QtGlPreview
56+ NO = None
57+
58+ @staticmethod
59+ def auto ():
60+ # Crude attempt at "autodetection" but which will mostly (?) work. We will
61+ # probably find situations that need fixing, VNC perhaps.
62+ display = os .getenv ('DISPLAY' )
63+ if display is None :
64+ return Preview .DRM
65+ elif display .startswith (':' ):
66+ return Preview .QTGL
67+ else :
68+ return Preview .QT
5669
5770
5871class GlobalCameraInfo (TypedDict ):
@@ -578,34 +591,26 @@ def start_preview(self, preview=None, **kwargs) -> None:
578591 """
579592 Start the given preview which drives the camera processing.
580593
581- The preview may be either:
582- None or False - in which case a NullPreview is made,
583- True - which we hope in future to use to autodetect
584- a Preview enum value - in which case a preview of that type is made,
585- or an actual preview object.
586-
587- When using the enum form, extra keyword arguments can be supplied that
588- will be forwarded to the preview class constructor.
594+ preview - a Preview enum or an actual preview object.
595+ Pass Preview.auto() to autodetect. Defaults to NullPreview.
596+ Additional keyword arguments may be supplied which will be
597+ forwarded to the preview class constructor.
589598 """
590- if self ._event_loop_running :
591- raise RuntimeError ("An event loop is already running" )
599+ if isinstance (preview , bool ):
600+ _log .error ("Passing bool to preview parameter is deprecated" )
601+ preview = Preview .auto () if preview else None
592602
593- if preview is True :
594- # Crude attempt at "autodetection" but which will mostly (?) work. We will
595- # probably find situations that need fixing, VNC perhaps.
596- display = os .getenv ('DISPLAY' )
597- if display is None :
598- preview = Preview .DRM .value (** kwargs )
599- elif display .startswith (':' ):
600- preview = Preview .QTGL .value (** kwargs )
601- else :
602- preview = Preview .QT .value (** kwargs )
603- elif preview is False or preview is None :
604- preview = Preview .NULL .value (** kwargs )
603+ if preview is None :
604+ preview = NullPreview (** kwargs )
605605 elif isinstance (preview , Preview ):
606+ if preview is Preview .NO :
607+ return
606608 preview = preview .value (** kwargs )
607609 # Assume it's already a preview object.
608610
611+ if self ._event_loop_running :
612+ raise RuntimeError ("An event loop is already running" )
613+
609614 # The preview windows call the attach_preview method.
610615 self ._preview_stopped .clear ()
611616 preview .start (self )
@@ -1183,32 +1188,27 @@ def start_(self):
11831188 _log .info ("Camera started" )
11841189 self .started = True
11851190
1186- def start (self , config = None , show_preview = False ) -> None :
1191+ def start (self , config = None , show_preview = False , preview = None ) -> None :
11871192 """
11881193 Start the camera system running.
11891194
11901195 Camera controls may be sent to the camera before it starts running.
11911196
1192- The following parameters may be supplied:
1197+ config - Camera configuration to be set. Defaults to 'preview' configuration.
1198+ Note: if the camera is already configured, this has no effect.
11931199
1194- config - if not None this is used to configure the camera. This is just a
1195- convenience so that you don't have to call configure explicitly.
1196-
1197- show_preview - whether to show a preview window. You can pass in the preview
1198- type or True to attempt to autodetect. If left as False you'll get no
1199- visible preview window but the "NULL preview" will still be run. The
1200- value None would mean no event loop runs at all and you would have to
1201- implement your own.
1200+ preview - A Preview enum or an actual preview object.
1201+ Pass Preview.auto() to autodetect. Defaults to NullPreview.
1202+ Note: if an event loop is already running, this parameter has no effect.
12021203 """
1203- if not self . camera_config and config is None :
1204- config = " preview"
1205- if config is not None :
1206- self . configure ( config )
1204+ if preview is None and show_preview is not False :
1205+ _log . error ( "show_preview is deprecated, use preview instead" )
1206+ preview = Preview . NO if show_preview is None else show_preview
1207+
12071208 if not self .camera_config :
1208- raise RuntimeError ("Camera has not been configured" )
1209- # By default we will create an event loop if there isn't one running already.
1210- if show_preview is not None and not self ._event_loop_running :
1211- self .start_preview (show_preview )
1209+ self .configure (config )
1210+ if not self ._event_loop_running :
1211+ self .start_preview (preview )
12121212 self .start_ ()
12131213
12141214 def cancel_all_and_flush (self ) -> None :
@@ -2394,7 +2394,7 @@ def set_overlay(self, overlay) -> None:
23942394 def start_and_capture_files (self , name = "image{:03d}.jpg" ,
23952395 initial_delay = 1 , preview_mode = "preview" ,
23962396 capture_mode = "still" , num_files = 1 , delay = 1 ,
2397- show_preview = True , exif_data = None ) -> None :
2397+ show_preview = True , exif_data = None , preview = None ) -> None :
23982398 """This function makes capturing multiple images more convenient.
23992399
24002400 Should only be used in command line line applications (not from a Qt application, for example).
@@ -2417,34 +2417,35 @@ def start_and_capture_files(self, name="image{:03d}.jpg",
24172417
24182418 delay - the time delay for every capture after the first (default 1s).
24192419
2420- show_preview - whether to show a preview window (default: yes). The preview window only
2421- displays an image by default during the preview phase, so if captures are back-to-back
2422- with delay zero, then there may be no images shown. This parameter only has any
2423- effect if a preview is not already running. If it is, it would have to be stopped first
2424- (with the stop_preview method).
2420+ preview - which preview to start (current-default: auto-detect; in-future: NullPreview).
2421+ The preview window only displays an image by default during the preview phase,
2422+ so if captures are back-to-back with delay zero, then there may be no images shown.
2423+ Note: if a preview is already running, this parameter has no effect.
24252424
24262425 exif_data - dictionary containing user defined exif data (based on `piexif`). This will
24272426 overwrite existing exif information generated by picamera2.
24282427 """
2428+ _log .warning ("FutureWarning: Parameter preview will default to NullPreview in a future release" )
2429+
24292430 if self .started :
24302431 self .stop ()
24312432 if delay :
24322433 # Show a preview between captures, so we will switch mode and back for each capture.
24332434 self .configure (preview_mode )
2434- self .start (show_preview = show_preview )
2435+ self .start (show_preview = show_preview , preview = preview )
24352436 for i in range (num_files ):
24362437 time .sleep (initial_delay if i == 0 else delay )
24372438 self .switch_mode_and_capture_file (capture_mode , name .format (i ), exif_data = exif_data )
24382439 else :
24392440 # No preview between captures, it's more efficient just to stay in capture mode.
24402441 if initial_delay :
24412442 self .configure (preview_mode )
2442- self .start (show_preview = show_preview )
2443+ self .start (show_preview = show_preview , preview = preview )
24432444 time .sleep (initial_delay )
24442445 self .switch_mode (capture_mode )
24452446 else :
24462447 self .configure (capture_mode )
2447- self .start (show_preview = show_preview )
2448+ self .start (show_preview = show_preview , preview = preview )
24482449 for i in range (num_files ):
24492450 self .capture_file (name .format (i ), exif_data = exif_data )
24502451 if i == num_files - 1 :
@@ -2453,7 +2454,7 @@ def start_and_capture_files(self, name="image{:03d}.jpg",
24532454 self .stop ()
24542455
24552456 def start_and_capture_file (self , name = "image.jpg" , delay = 1 , preview_mode = "preview" ,
2456- capture_mode = "still" , show_preview = True , exif_data = None ) -> None :
2457+ capture_mode = "still" , show_preview = True , exif_data = None , preview = None ) -> None :
24572458 """This function makes capturing a single image more convenient.
24582459
24592460 Should only be used in command line line applications (not from a Qt application, for example).
@@ -2471,21 +2472,22 @@ def start_and_capture_file(self, name="image.jpg", delay=1, preview_mode="previe
24712472 capture_mode - the camera mode to use to capture the still images (defaulting to the
24722473 Picamera2 object's still_configuration field).
24732474
2474- show_preview - whether to show a preview window (default: yes). The preview window only
2475- displays an image by default during the preview phase. This parameter only has any
2476- effect if a preview is not already running. If it is, it would have to be stopped first
2477- (with the stop_preview method).
2475+ preview - which preview to start (current-default: auto-detect; in-future: NullPreview).
2476+ The preview window only displays an image by default during the preview phase.
2477+ Note: if a preview is already running, this parameter has no effect.
24782478
24792479 exif_data - dictionary containing user defined exif data (based on `piexif`). This will
24802480 overwrite existing exif information generated by picamera2.
24812481 """
2482+ _log .warning ("FutureWarning: Parameter preview will default to NullPreview in a future release" )
2483+
24822484 self .start_and_capture_files (name = name , initial_delay = delay , preview_mode = preview_mode ,
24832485 capture_mode = capture_mode , num_files = 1 ,
2484- show_preview = show_preview ,
2486+ show_preview = show_preview , preview = preview ,
24852487 exif_data = exif_data )
24862488
24872489 def start_and_record_video (self , output , encoder = None , config = None , quality = Quality .MEDIUM ,
2488- show_preview = False , duration = 0 , audio = False ) -> None :
2490+ show_preview = False , duration = 0 , audio = False , preview = None ) -> None :
24892491 """This function makes video recording more convenient.
24902492
24912493 Should only be used in command line applications (not from a Qt application, for example).
@@ -2507,9 +2509,8 @@ def start_and_record_video(self, output, encoder=None, config=None, quality=Qual
25072509 quality - an indication of the video quality to use. This will be ignored if the encoder
25082510 object was created with all its quality parameters (such as bitrate) filled in.
25092511
2510- show_preview - whether to show a preview window (default: no). This parameter only has an
2511- effect if a preview is not already running, in which case that preview would need
2512- stopping first (using stop_preview) for any change to take effect.
2512+ preview - which preview to start (default: NullPreview).
2513+ Note: if a preview is already running, this parameter has no effect.
25132514
25142515 duration - the duration of the video. The function will wait this amount of time before
25152516 stopping the recording and returning. The default behaviour is to return immediately
@@ -2538,7 +2539,7 @@ def start_and_record_video(self, output, encoder=None, config=None, quality=Qual
25382539 if encoder is None :
25392540 encoder = H264Encoder ()
25402541 self .start_encoder (encoder = encoder , output = output , quality = quality )
2541- self .start (show_preview = show_preview )
2542+ self .start (show_preview = show_preview , preview = preview )
25422543 if duration :
25432544 time .sleep (duration )
25442545 self .stop_recording ()
0 commit comments