各個gui開發工具對比
Flexx: 可以使用Flexx建立桌面應用程式和web應用程式,同時可以將程式匯出到獨立的HTML檔案中,GitHub推薦
Kivy&BeeWare: 只需編寫一套程式碼便可輕鬆執行於各大移動平臺和桌面上,像Android,iOS,Linux,OS X和Windows,https://blog.csdn.net/ZNJIAYOUYA/article/details/126553693,兩者各有特別,kivy更靈活,後者相容性好
Pyforms: 旨在提高開發效率,用於開發可以在Windows GUI模式、Web模式或終端模式下執行的應用程式
PyQt: 目前最強大的庫之一,可以使用Python做任何C++能做的事
PyAutoGUI: 利用它可以實現所有GUI自動化,無需機械性操作
wxPython: wxPython具有非常優秀的跨平臺能力,可以在不修改程式的情況下在多種平臺上執行
為啥選擇beeware
1.支援跨平臺開發
2.相對Kivy更簡單,相容性更好,kivy靈活性更高,所以建議結合實際情況選擇
beeware官方教程:https://docs.beeware.org/en/latest/tutorial/tutorial-0.html
中文檔案:https://github.com/xianchengyue/Beeware--
搭建步驟
1.設定虛擬環境
1.mkdir beeware-tutorial
2.python3 -m venv beeware-venv #建立虛擬環境
3.source beeware-venv/bin/activate (windows:使用git bash工具執行) #切換至虛擬環境
4.beeware-venv\Scripts\activate.bat (windows:cmd執行)#切換至虛擬環境
2.建立第一個應用
1.安裝briefcase: pip install briefcase
2.新建專案:briefcase new ,之後的內容按需填寫即可,Pyproject.toml 檔案描述瞭如何對應用程式進行打包以便發行
3.在開發者模式下執行應用程式: cd project_dir && briefcase dev
4.專案結構說明:__init__.py:標記專案目錄是一個python包,__main__.py 將專案目錄標記為一個特殊的可執行模組,app.py:建立app視窗的邏輯
打包以便釋出
1.建立應用程式腳手架: briefcase create
2.搭建應用程式: 編譯:briefcase build
3.執行app: briefcase run
4.搭建安裝包: macos: briefcase package --no-sign;Linux&Windows:briefcase package,詳細說明:https://briefcase.readthedocs.io/en/latest/how-to/code-signing/macOS.html
更新app
1.briefcase dev: 每次執行都能看到修改後最新的效果
2.briefcase run:則不會,需要先執行:briefcase update,然後在執行briefcase run,最後使用briefcase package 命令重新打包app 以便分發
3.macOS 的使用者記住在第三章中提到的使用 briefcase package 命令時帶上 --no-sign 標誌避免設定程式碼簽名標識的複雜工作並使教程儘可能簡單
4.一步更新和執行: briefcase run -u,會自動觸發更新,重新打包:briefcase package -u
使之成為移動 app
1.IOS:
1.安裝xcode
2.briefcase create iOS #建立app
3.briefcase build iOS #編譯
4.briefcase run iOS ,執行時指定裝置名稱&選擇特定版本的iOS,-d "裝置名稱::ios 版本號",使用特定裝置的UDID名稱: -d 4768AA69-497B-4B37-BD0C-3961756C38AC
2.安卓
1.MacOs&Liunx&windows: briefcase create android ,首次執行會比較慢,會自動下載java jdk與安裝sdk #建立app
2.briefcase build android ,Gradle可能停止工作:將會列印CONFIGURING:100%,但看起來什麼事也沒做,此時它在下載更多安卓SDK元件 #編譯app
4.模擬裝置上執行app:
1.briefcase run android ,執行此命令會提示你可執行app的裝置清單,最後一個選項始終是建立一個新的安卓模擬器 #執行app
2.如果模擬器沒啟動: 執行briefcase run檢查一下終端找到錯誤資訊
3.如果你想不使用選單在裝置上執行app: briefcase run android -d @beePhone
5.實體裝置上執行app:
1.啟用開發者選項;2.啟用USB除錯;3.briefcase run android,直接執行:briefcase run android -d 裝置標識號
2.我的裝置沒有出現: 要麼你沒有啟動 USB 除錯,要麼裝置根本沒插進去
3.顯示為“未知裝置(不是未授權開發): 1.重新啟用開發者模式;2.然後重新執行 briefcase run android 命令
開始使用第三方庫
1.訪問 API:使用jsonplaceholder(https://jsonplaceholder.typicode.com)作為資料來源
2.安裝第三庫,例如:pip install httpx
3.briefcase dev #本地執行
4.briefcase update : 更新app程式碼
5.briefcase build : 編譯app
6.briefcase run : 執行app
7.啟動時提示module not found:
1.修改app全域性依賴: key:[tool.briefcase.app.appname]
1.修改pyproject.toml,修改requires,將依賴新增至requires
2.新增時可以指定版本與版本範圍,例如:httpx==0.19.0,httpx>=0.19
3.指定克隆倉庫的路徑: 如"git+https://github.com/encode/httpx"
2.修改指定平臺的依賴: key:[tool.briefcase.app.appname.macOS、windows、linux、iOS、web、android]
1.修改pyproject.toml,修改requires,將依賴新增至requires
8.Python只在移動端:
1.在桌面平臺: 任何pip能安裝的都可以被新增到你的需求中
2.在移動平臺: 只能使用純Python包及包中不能包含二進位制模組,numpy、scikit-learn、cryptography等不能在移動平臺上使用
9. briefcase update -d #更新依賴
10.briefcase build #編譯
11. briefcase run # 執行
讓app執行更流暢
1.GUI事件迴圈: 當app正在處理一個事件,不能重繪也不能處理其他事件
2.非同步程式設計: 使用 async 和 await 關鍵字實現
3.製作非同步教程
![img.png](img.png)
![img_1.png](img_1.png)
測試app
1.briefcase dev -r #自動檢查依賴安裝情況
2.briefcase dev --test #執行測試
3.test_app.py #編寫測試用例
4.briefcase run --test -r #執行時測試
5.briefcase run iOS --test、 briefcase run android --test #指定平臺執行測試用例
實戰:開始擼程式碼
專案配置檔案詳解
1.https://briefcase.readthedocs.io/en/latest/reference/index.html
Toga小部件工具詳解
1.https://toga.readthedocs.io/en/latest/tutorial/index.html
2.安裝toga依賴: pip install toga
1.編寫應用程式
1.程式碼示例:
import toga
def button_handler(widget):
print("hello")
def build(app):
box = toga.Box()
button = toga.Button("Hello world", on_press=button_handler)
button.style.padding = 50
button.style.flex = 1
box.add(button)
return box
def main():
return toga.App("First App", "org.beeware.helloworld", startup=build)
if __name__ == "__main__":
main().main_loop()
2.細節介紹
1.button_handler方法:widget引數,該函式將啟用的小部件作為第一個引數
2.build方法: app引數,為toga.app例項,用於自定義app啟動的方法
3.toga.Box: 盒子是一個物件,可用於容納多個小部件,並定義小部件周圍的填充
4.toga.Button: 定義一個按鈕,引數1:按鈕的展示名稱;2.on_press:點選按鈕後觸發的行為(函式物件)
5.button.style: 定義按鈕在視窗中的顯示方式,預設情況下,Toga 使用一種名為 的樣式演演算法Pack,有點像“CSS-lite”
1.button.style.padding = 50 #按鈕的所有邊都有 50 畫素的填充
2.padding_top = 20 padding = (20, 50, 50, 50) #在按鈕頂部定義20畫素的填充
3.button.style.flex = 1 #使按鈕佔據所有可用寬度
6.box.add(button): 將按鈕新增到框中
7.return box: 返回包含所有 UI 內容的外部盒子,此框將是應用程式主視窗的內容
故障排除
1.建議首先建立一個虛擬環境
2.Toga 有一些最低要求:
如果您使用的是 macOS,則需要使用 10.10 (Yosemite) 或更高版本。
如果您使用的是 Linux,則需要 GTK+ 3.10 或更新版本。這是從 Ubuntu 14.04 和 Fedora 20 開始釋出的版本。
如果您使用的是 Windows,則需要安裝 Windows 10 或更新版本。
3.執行指令碼: cd 專案/src && python -m 專案名稱
2.來寫一個更復雜一點的頁面:華氏度到攝氏度轉換器
程式碼示例
import toga
from toga.style.pack import COLUMN, LEFT, RIGHT, ROW, Pack
def build(app):
c_box = toga.Box()
f_box = toga.Box()
box = toga.Box()
c_input = toga.TextInput(readonly=True)
f_input = toga.TextInput()
c_label = toga.Label("Celsius", style=Pack(text_align=LEFT))
f_label = toga.Label("Fahrenheit", style=Pack(text_align=LEFT))
join_label = toga.Label("is equivalent to", style=Pack(text_align=RIGHT))
def calculate(widget):
try:
c_input.value = (float(f_input.value) - 32.0) * 5.0 / 9.0
except ValueError:
c_input.value = "???"
button = toga.Button("Calculate", on_press=calculate)
f_box.add(f_input)
f_box.add(f_label)
c_box.add(join_label)
c_box.add(c_input)
c_box.add(c_label)
box.add(f_box)
box.add(c_box)
box.add(button)
box.style.update(direction=COLUMN, padding=10)
f_box.style.update(direction=ROW, padding=5)
c_box.style.update(direction=ROW, padding=5)
c_input.style.update(flex=1)
f_input.style.update(flex=1, padding_left=160)
c_label.style.update(width=100, padding_left=10)
f_label.style.update(width=100, padding_left=10)
join_label.style.update(width=150, padding_right=10)
button.style.update(padding=15)
return box
def main():
return toga.App("Temperature Converter", "org.beeware.f_to_c", startup=build)
if __name__ == "__main__":
main().main_loop()
詳細說明
1.此示例展示了 Toga 的 Pack 風格引擎的更多功能。在這個示例應用程式中,我們設定了一個垂直堆疊的外框;在那個盒子裡,我們放了 2 個水平盒子和一個按鈕。
2.由於水平框上沒有寬度樣式,它們將嘗試將它們包含的小部件放入可用空間。
3.小TextInput 部件的樣式為flex=1,但是Label小部件的寬度是固定的;
4.結果,TextInput小部件將被拉伸以適應可用的水平空間。然後,邊距和填充項確保小部件將垂直和水平對齊。
5.toga.TextInput: 定義一個文字輸入框,readonly=True:設定為不可編輯
6.toga.Label: 定義表頭,text_align:文字對齊方式,LEFT:居左,RIGHT:居右
7.box.style: 定義按鈕在視窗中的顯示方式,預設情況下,Toga 使用一種名為 的樣式演演算法Pack,有點像“CSS-lite”
1.box.style.padding = 50 #按鈕的所有邊都有 50 畫素的填充
2.padding = (20, 50, 50, 50) #在按鈕頂部定義20畫素的填充
3.box.style.flex = 1 #使按鈕佔據所有可用寬度
4.box.style.update: 更新頁面佈局,direction:指定方向
5.box、button、input、label均可設定style
把盒子放在另一個盒子裡:涉及佈局、捲軸和其他容器內的容器
程式碼示例
import toga
from toga.style.pack import COLUMN, Pack
def button_handler(widget):
print("button handler")
for i in range(0, 10):
print("hello", i)
yield 1
print("done", i)
def action0(widget):
print("action 0")
def action1(widget):
print("action 1")
def action2(widget):
print("action 2")
def action3(widget):
print("action 3")
def action5(widget):
print("action 5")
def action6(widget):
print("action 6")
def build(app):
brutus_icon = "icons/brutus"
cricket_icon = "icons/cricket-72.png"
data = [("root%s" % i, "value %s" % i) for i in range(1, 100)]
left_container = toga.Table(headings=["Hello", "World"], data=data)
right_content = toga.Box(style=Pack(direction=COLUMN, padding_top=50))
for b in range(0, 10):
right_content.add(
toga.Button(
"Hello world %s" % b,
on_press=button_handler,
style=Pack(width=200, padding=20),
)
)
right_container = toga.ScrollContainer(horizontal=False)
right_container.content = right_content
split = toga.SplitContainer()
# The content of the split container can be specified as a simple list:
# split.content = [left_container, right_container]
# but you can also specify "weight" with each content item, which will
# set an initial size of the columns to make a "heavy" column wider than
# a narrower one. In this example, the right container will be twice
# as wide as the left one.
split.content = [(left_container, 1), (right_container, 2)]
# Create a "Things" menu group to contain some of the commands.
# No explicit ordering is provided on the group, so it will appear
# after application-level menus, but *before* the Command group.
# Items in the Things group are not explicitly ordered either, so they
# will default to alphabetical ordering within the group.
things = toga.Group("Things")
cmd0 = toga.Command(
action0,
text="Action 0",
tooltip="Perform action 0",
icon=brutus_icon,
group=things,
)
cmd1 = toga.Command(
action1,
text="Action 1",
tooltip="Perform action 1",
icon=brutus_icon,
group=things,
)
cmd2 = toga.Command(
action2,
text="Action 2",
tooltip="Perform action 2",
icon=toga.Icon.TOGA_ICON,
group=things,
)
# Commands without an explicit group end up in the "Commands" group.
# The items have an explicit ordering that overrides the default
# alphabetical ordering
cmd3 = toga.Command(
action3,
text="Action 3",
tooltip="Perform action 3",
shortcut=toga.Key.MOD_1 + "k",
icon=cricket_icon,
order=3,
)
# Define a submenu inside the Commands group.
# The submenu group has an order that places it in the parent menu.
# The items have an explicit ordering that overrides the default
# alphabetical ordering.
sub_menu = toga.Group("Sub Menu", parent=toga.Group.COMMANDS, order=2)
cmd5 = toga.Command(
action5, text="Action 5", tooltip="Perform action 5", order=2, group=sub_menu
)
cmd6 = toga.Command(
action6, text="Action 6", tooltip="Perform action 6", order=1, group=sub_menu
)
def action4(widget):
print("CALLING Action 4")
cmd3.enabled = not cmd3.enabled
cmd4 = toga.Command(
action4, text="Action 4", tooltip="Perform action 4", icon=brutus_icon, order=1
)
# The order in which commands are added to the app or the toolbar won't
# alter anything. Ordering is defined by the command definitions.
app.commands.add(cmd1, cmd0, cmd6, cmd4, cmd5, cmd3)
app.main_window.toolbar.add(cmd1, cmd3, cmd2, cmd4)
return split
詳細說明
注意: 為了呈現圖示,您需要將圖示資料夾移動到與應用程式檔案相同的目錄中。
1.toga.Table: 定義一個表格,引數詳細說明:
1.headings(表頭)=["Hello", "World","desc"], data(內容)=data
2.id:唯一識別符號;3.style:指定樣式
3.accessors:訪問器,multiple_select:支援多選框,
4.on_select:提供的回撥函式必須接受兩個引數列(obj:“表”)和行(' '行' '或' '沒有' '),on_double_click:雙點選提供的回撥函式必須接受兩個引數列(obj:“表”)和行(' '行' '或' '沒有' '),
5.missing_value:預設值,factory:已經棄用
2.toga.ScrollContainer: 定義一個捲軸,引數詳細說明:
1.horizontal:True(為水平,即橫向捲軸),False(為垂直,即縱向捲軸)
3.toga.SplitContainer: 定義一個拆分控制元件,分別展示,引數詳細說明:
1.id:指定唯一識別符號,style:指定樣式,
2.direction:是否水平展示,預設垂直展示,content:切換的內容,
例如:[(left_container, 1), (right_container, 2)]
3.factory:已經棄用
4.toga.Group:定義一個頂部選項卡(選單),引數詳細說明:
1.text:選單名稱,order:指定排序,section:是否部件,
2.parent:指定父級選項卡,label:目前已經棄用
4.系統預設可呼叫的物件:
Group.APP = Group("*", order=0)
Group.FILE = Group("File", order=1)
Group.EDIT = Group("Edit", order=10)
Group.VIEW = Group("View", order=20)
Group.COMMANDS = Group("Commands", order=30)
Group.WINDOW = Group("Window", order=90)
Group.HELP = Group("Help", order=100)
5.toga.Command: 需要呼叫命令時使用,引數詳細說明:
1.action:函式物件,text:標題,shortcut:命令描述,icon:指定展示圖示,
2.group:所屬的選項卡,section:是否部件,order:指定排序,enabled:是否啟用,factory&label:已經棄用
6.app.commands.add: 新增一組命令到commands選項卡中
7.app.main_window(程式主執行視窗).toolbar:工具欄操作,add新增
8.app.main_window.info_dialog: 正常提示彈窗,error_dialog:錯誤提示彈窗
構建一個瀏覽器
儘管可以構建複雜的 GUI 佈局,但您可以使用現代平臺上原生的豐富元件,用很少的程式碼獲得很多功能
示例程式碼
import toga
from toga.style.pack import CENTER, COLUMN, ROW, Pack
class Graze(toga.App):
def startup(self):
self.main_window = toga.MainWindow(title=self.name)
self.webview = toga.WebView(
on_webview_load=self.on_webview_loaded, style=Pack(flex=1)
)
self.url_input = toga.TextInput(
value="https://beeware.org/", style=Pack(flex=1)
)
box = toga.Box(
children=[
toga.Box(
children=[
self.url_input,
toga.Button(
"Go",
on_press=self.load_page,
style=Pack(width=50, padding_left=5),
),
],
style=Pack(
direction=ROW,
alignment=CENTER,
padding=5,
),
),
self.webview,
],
style=Pack(direction=COLUMN),
)
self.main_window.content = box
self.webview.url = self.url_input.value
# Show the main window
self.main_window.show()
def load_page(self, widget):
self.webview.url = self.url_input.value
def on_webview_loaded(self, widget):
self.url_input.value = self.webview.url
def main():
return Graze("Graze", "org.beeware.graze")
if __name__ == "__main__":
main().main_loop()
在此示例中,您可以看到一個應用程式被開發為一個類,而不是一個構建方法。
您還可以看到以宣告方式定義的框 - 如果您不需要保留對特定小部件的引用,您可以內聯定義一個小部件,並將其作為引數傳遞給框,它將成為那個盒子。
詳細說明
1.toga.WebView: 指定一個web頁面
打造獨家app
1.新增圖示
2.下一步