QPython 中文文档 下载 App

QPython FullScreenWrapper2——用 Python 构建 Android GUI

为什么需要 UI 框架

前面介绍的 Toast、Dialog、Sensor 自动化都是无界面或轻界面的交互方式。如果你想做一个带正式界面的 Android 应用——有按钮、输入框、列表、图片等——QSL4A 提供了 FullScreenWrapper2 框架。

FullScreenWrapper2(简称 FSW2)是一个纯 Python 的 UI 框架:

FSW2 的基本用法

导入和创建 Activity

import android.fullscreenwrapper2 as fsw2

class MyApp(fsw2.Layout):
    def __init__(self):
        super().__init__()
        # 在这里定义界面元素

    def load_layout(self):
        # 定义并加载 UI 布局
        # 返回一个包含 UI 元素的列表
        pass

# 启动 Activity
fsw2.start_activity(MyApp)

添加 UI 元素

import android.fullscreenwrapper2 as fsw2

class GreetingApp(fsw2.Layout):
    def __init__(self):
        super().__init__()
        self.user_name = ""

    def load_layout(self):
        # 创建元素
        title = fsw2.TextElement("title", "你好,欢迎使用!", topmargin=50)
        input_field = fsw2.TextboxElement("name_input", "请输入你的名字", topmargin=120)
        submit_btn = fsw2.ButtonElement("submit", "提交", topmargin=200)
        
        # 按钮点击事件
        submit_btn.set_on_click_listener(self.on_submit)
        
        # 返回布局元素列表
        self.layoutElements = [title, input_field, submit_btn]

    def on_submit(self):
        # 获取输入框内容
        self.user_name = self.layoutElements["name_input"].text
        # 更新标题文字
        self.layoutElements["title"].text = f"你好,{self.user_name}!"
        self.update_view()

# 启动
fsw2.start_activity(GreetingApp)

支持的 UI 元素

FullScreenWrapper2 提供的常用元素:

元素说明
TextElement静态文字标签
TextboxElement输入框(可编辑)
ButtonElement按钮
ImageElement图片(从文件或资源加载)
ListElement列表视图
SpinnerElement下拉选择器
CheckboxElement复选框
ToggleElement开关按钮
SeekbarElement滑块(如音量、亮度调节)
WebviewElement内嵌 WebView
HorizontalScrollElement / VerticalScrollElement可滚动容器

布局方式

FSW2 使用 相对定位(Relative Layout):

title = fsw2.TextElement("title", "标题文字",
                         topmargin=20,
                         height=60)
button = fsw2.ButtonElement("btn", "点击",
                            topmargin=150,
                            height=50,
                            width=200)

事件处理

点击事件

def my_click_handler(self):
    droid.makeToast("按钮被点击了!")

button = fsw2.ButtonElement("btn", "点我")
button.set_on_click_listener(my_click_handler)

文本变化事件

def text_changed(self):
    new_text = self.layoutElements["input"].text
    # 实时响应输入变化

textbox = fsw2.TextboxElement("input", "")
textbox.add_text_changed_listener(text_changed)

列表选择事件

def item_selected(index):
    selected_item = items[index]
    droid.makeToast(f"选中了: {selected_item}")

items = ["苹果", "香蕉", "橘子"]
list_view = fsw2.ListElement("fruit_list", items)
list_view.set_on_item_click_listener(item_selected)

实际应用示例:传感器数据面板

把 QSL4A 传感器数据实时展示在 FSW2 界面上:

import android.fullscreenwrapper2 as fsw2
from androidhelper import Android
import time

class SensorDashboard(fsw2.Layout):
    def __init__(self):
        super().__init__()
        self.droid = Android()
        self.droid.startSensingTimed(1, 500)
        self.running = True

    def load_layout(self):
        self.title = fsw2.TextElement("title", "加速度传感器", topmargin=30, height=50)
        self.x_label = fsw2.TextElement("x", "X: 0", topmargin=100, height=40)
        self.y_label = fsw2.TextElement("y", "Y: 0", topmargin=150, height=40)
        self.z_label = fsw2.TextElement("z", "Z: 9.8", topmargin=200, height=40)
        self.stop_btn = fsw2.ButtonElement("stop", "停止", topmargin=280, height=50)
        self.stop_btn.set_on_click_listener(self.stop)
        
        self.layoutElements = [self.title, self.x_label, self.y_label, self.z_label, self.stop_btn]
        
        # 启动定时更新
        self.update_loop()

    def update_loop(self):
        import threading
        def update():
            while self.running:
                events = self.droid.sensorsGetEventBuffered().result
                if events:
                    latest = events[-1]
                    self.x_label.text = f"X: {latest.get('x', 0):.2f}"
                    self.y_label.text = f"Y: {latest.get('y', 0):.2f}"
                    self.z_label.text = f"Z: {latest.get('z', 0):.2f}"
                    try:
                        self.update_view()
                    except:
                        pass
                time.sleep(0.5)
        
        thread = threading.Thread(target=update)
        thread.daemon = True
        thread.start()

    def stop(self):
        self.running = False
        self.droid.stopSensing()
        self.close()

fsw2.start_activity(SensorDashboard)

这个示例展示了 FSW2 的核心用法——定义元素、设置事件、用 update_view() 更新界面。

和原生 Android UI 的区别

特性Android XML 布局 + Java/KotlinFSW2 + Python
开发语言Java / KotlinPython
布局方式XML 或 ComposePython 代码(相对定位)
事件处理Java / Kotlin 回调Python 函数
运行环境原生 AppQPython + QSL4A RPC
适合场景发布到应用商店的正式 App内部工具、原型、快速开发

FSW2 做出来的界面和原生 Android 界面外观一致(因为底层用的就是 Android View),但性能比原生稍差(多了一层 RPC)。对于工具类应用和原型来说完全够用。

小结

FullScreenWrapper2 让「用 Python 写 Android GUI」变成现实——你不需要学 Java、不需要装 Android Studio,用 Python 就能构建带按钮、输入框、列表、图片等元素的原生界面。事件处理和界面更新都是纯 Python 代码,结合 QSL4A 的硬件能力,可以做出很有意思的手机工具。

继续看悬浮窗和二维码扫描,这两个是硬件自动化的重要配套。