使用相機¶
幾乎每部現代電腦裝置都有某種相機。在本教程中,我們將編寫新的應用程式,能夠要求存取此相機、拍攝照片,然後在使用裝置相機的新應用程式中顯示該照片。
本教學不會在所有平台上運作!
不幸的是,目前本教學只適用於 macOS 和 Android。
雖然 iPhone 都有相機,但 iOS Simulator 並沒有可用的相機。Windows 和 Linux 裝置也有攝影機,但 Toga 目前無法在這些平台上存取攝影機。
這裡提出的程式碼可以在 Windows 或 Linux 上 * 執行;但當您嘗試拍照時,它會產生錯誤。
如果在實際的 iOS 裝置上執行,程式碼將會正常運作,但如果部署到 iOS 模擬器上,則會無法拍照。
開始新專案¶
在本教程中,我們不打算在核心教程中的應用程式上進行建置 - 我們要開始一個全新的專案。您可以使用與第一個專案相同的虛擬環境;但我們需要重新執行
briefcase new 精靈。
變回包含專案資料夾 helloworld 的目錄,並開始一個名為「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
新增代碼以拍攝照片¶
精靈已產生一個新的空 Toga 專案。現在我們可以加入拍攝和顯示照片的程式碼。編輯新應用程式的 app.py,使其具有以下內容:
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()
與 Briefcase 所產生的預設應用程式相比,此程式碼有兩項變更。這些新增內容將在上文強調:
- 第一個突出顯示的程式碼區塊(在
startup()方法中)新增了控制攝影機所需的兩個 widget:顯示相片的ImageView,以及觸發攝影機的Button。 - 第二個反白顯示的程式碼區塊(
take_photo()方法)定義了按鈕被按下時的事件處理程式。此處理器會首先確認應用程式是否有拍照的權限;如果沒有權限,則會請求權限。然後拍攝照片。請求權限和拍攝照片的請求都是異步請求,因此需要使用await;當應用程式在等待使用者確認權限或拍攝照片時,應用程式的事件循環可以在背景中繼續。
如果相機成功拍攝了照片,它會返回一個 Image 物件,這個物件可以指定為 ImageView
的內容。如果拍照請求被使用者取消,self.camera.take_photo() 呼叫將返回
None,結果可以被忽略。如果使用者沒有允許使用照相機,或是照相機沒有在目前的平台上實作,將會產生錯誤,並顯示對話框給使用者。
新增裝置權限¶
我們剛剛加入的這段程式碼,有一部分是要求取得使用攝影機的權限。這是現代應用程式平台的常見功能 - 不先明確詢問用戶的許可,就無法存取硬體功能。
不過,這個要求分為兩部分。第一部分在我們剛剛看到的程式碼中;但在應用程式要求權限之前,它需要先宣告它要要求的權限。
每個平台所需的權限略有不同,但 Briefcase 對許多常見的硬體權限都有跨平台的表示。在您應用程式的 pyproject.toml 檔案的
[tool.briefcase.app.hellocamera]配置區段中,新增下列內容 (就在 sources 宣告的上方):
permission.camera = "App will take mugshots."
這宣告您的應用程式需要存取攝影機,並提供簡短的說明,說明為何需要使用攝影機。在某些平台 (最顯著的是 macOS 和 iOS) 上需要此說明,並會在顯示權限對話框時,以附加資訊的形式顯示給使用者。
現在我們可以產生並執行應用程式:
(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
當應用程式執行時,您會看到一個按鈕。按下按鈕,平台的預設相機對話框將會顯示。拍張照片;相機對話框會消失,照片會顯示在應用程式中,就在按鈕上方。然後您可以再拍一張照片;這張照片會取代第一張照片。
新增更多權限¶
權限是在原始呼叫 briefcase create 時產生的檔案中宣告的。不幸的是,Briefcase
無法在初始產生這些檔案後更新它們;所以如果您想要在應用程式中加入新的權限,或是修改現有的權限,您需要重新建立應用程式。您可以重新執行 briefcase
create 來做到這一點;這會警告您現有的應用程式將會被覆寫,然後用新的權限重新產生應用程式。