Vai al contenuto

Utilizzo della fotocamera

Quasi tutti i dispositivi informatici moderni dispongono di una fotocamera di qualche tipo. In questa esercitazione, scriveremo una nuova applicazione in grado di richiedere l'accesso alla fotocamera, di scattare una fotografia e di visualizzarla nella nuova applicazione che utilizza la fotocamera del dispositivo.

Questo tutorial non funziona su tutte le piattaforme!

Purtroppo, al momento, questa esercitazione funziona solo su macOS e Android.

Sebbene gli iPhone siano tutti dotati di fotocamera, il Simulatore iOS non dispone di una fotocamera funzionante. Anche i dispositivi Windows e Linux hanno una fotocamera, ma attualmente Toga non è in grado di accedere alla fotocamera su queste piattaforme.

Il codice presentato qui viene eseguito su Windows o Linux, ma genera un errore quando si tenta di scattare una fotografia.

Il codice funziona se viene eseguito su un dispositivo iOS reale, ma non riesce a scattare una fotografia se viene distribuito sul simulatore iOS.

Avviare un nuovo progetto

Per questa esercitazione non ci baseremo sull'applicazione del tutorial principale, ma inizieremo un nuovo progetto. È possibile utilizzare lo stesso ambiente virtuale usato nel primo progetto, ma è necessario eseguire nuovamente la procedura guidata briefcase new.

Tornate alla directory che contiene la cartella del progetto helloworld e avviate un nuovo progetto chiamato "Hello Camera":

(beeware-venv) $ cd ..
(beeware-venv) $ briefcase new
...
[hellocamera] Generated new application 'Hello Camera'

To run your application, type:

    $ cd hellocamera
    $ briefcase dev

(beeware-venv) $ cd hellocamera

Aggiungere il codice per scattare una foto

La procedura guidata ha generato un nuovo progetto Toga vuoto. Ora possiamo aggiungere il codice per scattare e visualizzare una fotografia. Modificare il file app.py della nuova applicazione in modo che abbia il seguente contenuto:

import toga
from toga.style.pack import COLUMN, ROW


class HelloCamera(toga.App):
    def startup(self):
        main_box = toga.Box()

        self.photo = toga.ImageView(height=300, margin=5)
        camera_button = toga.Button(
            "Take photo",
            on_press=self.take_photo,
            margin=5,
        )

        main_box.add(self.photo)
        main_box.add(camera_button)

        self.main_window = toga.MainWindow(title=self.formal_name)
        self.main_window.content = main_box
        self.main_window.show()

    async def take_photo(self, widget, **kwargs):
        try:
            if not self.camera.has_permission:
                await self.camera.request_permission()

            image = await self.camera.take_photo()
            if image:
                self.photo.image = image
        except NotImplementedError:
            await self.main_window.dialog(
                toga.InfoDialog(
                    "Oh no!",
                    "The Camera API is not implemented on this platform",
                )
            )
        except PermissionError:
            await self.main_window.dialog(
                toga.InfoDialog(
                    "Oh no!",
                    "You have not granted permission to take photos",
                )
            )


def main():
    return HelloCamera()

Questo codice presenta due modifiche rispetto all'applicazione predefinita generata da Briefcase. Queste aggiunte sono evidenziate sopra:

  1. Il primo blocco di codice evidenziato (nel metodo startup()) aggiunge i due widget necessari per controllare la fotocamera: una ImageView per visualizzare una foto e un Button per attivare la fotocamera.
  2. Il secondo blocco di codice evidenziato (il metodo take_photo()) definisce il gestore dell'evento quando viene premuto il pulsante. Questo gestore conferma innanzitutto se l'applicazione ha il permesso di scattare una foto; se il permesso non esiste, viene richiesto. Quindi, viene scattata la foto. La richiesta di autorizzazione e la richiesta di scattare una foto sono entrambe richieste asincrone, quindi richiedono l'uso di await; mentre l'applicazione attende che l'utente confermi l'autorizzazione o scatti la foto, il ciclo di eventi dell'applicazione può continuare in background.

Se la fotocamera scatta una foto con successo, restituisce un oggetto Image che può essere assegnato come contenuto della ImageView. Se la richiesta di foto è stata annullata dall'utente, la chiamata self.camera.take_photo() restituirà None e il risultato potrà essere ignorato. Se l'utente non concede il permesso di usare la fotocamera, o se la fotocamera non è implementata sulla piattaforma corrente, verrà sollevato un errore e verrà mostrata una finestra di dialogo all'utente.

Aggiunta di autorizzazioni al dispositivo

Una parte del codice che abbiamo appena aggiunto chiede il permesso di utilizzare la fotocamera. Si tratta di una caratteristica comune alle moderne piattaforme di app: non è possibile accedere alle funzioni hardware senza chiedere esplicitamente il permesso all'utente.

Tuttavia, questa richiesta avviene in due parti. La prima è nel codice che abbiamo appena visto; ma prima che l'applicazione possa chiedere i permessi, deve dichiarare i permessi che sta per chiedere.

I permessi richiesti da ogni piattaforma sono leggermente diversi, ma Briefcase ha una rappresentazione multipiattaforma per molti permessi hardware comuni. Nella sezione di configurazione [tool.briefcase.app.hellocamera] del file pyproject.toml della propria applicazione, aggiungere quanto segue (appena sopra la dichiarazione sources):

permission.camera = "App will take mugshots."

Dichiara che l'applicazione deve accedere alla fotocamera e fornisce una breve descrizione del motivo per cui la fotocamera è necessaria. Questa descrizione è necessaria su alcune piattaforme (in particolare macOS e iOS) e verrà mostrata all'utente come informazione aggiuntiva quando viene presentata la finestra di dialogo dei permessi.

Ora possiamo generare ed eseguire l'applicazione:

(beeware-venv) $ briefcase create
(beeware-venv) $ briefcase build
(beeware-venv) $ briefcase run
(beeware-venv) $ briefcase create android
(beeware-venv) $ briefcase build android
(beeware-venv) $ briefcase run android

Quando l'applicazione viene eseguita, viene visualizzato un pulsante. Premendo il pulsante, verrà visualizzata la finestra di dialogo della fotocamera predefinita della piattaforma. Scattare una foto; la finestra di dialogo della fotocamera scomparirà e la foto verrà visualizzata nell'app, proprio sopra il pulsante. È quindi possibile scattare un'altra foto, che sostituirà la prima.

Aggiunta di ulteriori autorizzazioni

I permessi sono dichiarati nei file generati durante la chiamata originale a briefcase create. Sfortunatamente, Briefcase non può aggiornare questi file dopo che sono stati generati inizialmente; quindi, se si vuole aggiungere un nuovo permesso alla propria applicazione o modificare quelli esistenti, è necessario ricreare l'applicazione. È possibile farlo eseguendo nuovamente briefcase create; questo avvertirà che l'applicazione esistente sarà sovrascritta e quindi rigenererà l'applicazione con i nuovi permessi.