• python Gui编程工具详解:beeware


    各个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.跨平台开发能力强,web&app(pc:windows linux mac,移动端:android ios)都可,范围非常广
    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.异步编程: 使用 asyncawait 关键字实现
    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.下一步
    
  • 相关阅读:
    网络协议--BOOTP:引导程序协议
    Linux选择题笔记
    助力汽修企业突破转型瓶颈,S2B2B商城价格管理模块实现采购交易数字化升级
    记录一次循环引用的问题
    C51--单片机中断
    033:跨域,vue端和 Nignx反向代理的配置详细解析
    HTML5期末考核大作业,电影网站——橙色国外电影 web期末作业设计网页
    模拟大数相加
    TensorFlow实战教程(二十四)-基于BiLSTM-CRF的医学命名实体识别研究(上)数据预处理
    SSE图像算法优化系列三十一:RGB2HSL/RGB2HSV及HSL2RGB/HSV2RGB的指令集优化-上。
  • 原文地址:https://www.cnblogs.com/qtclm/p/17152723.html