Kivy框架打包APK后定位与尺寸异常问题求助
问题描述
我学习Kivy框架有段时间了,之前编译简单Android APK都正常。花3个月做了个给培训孩子用的大型应用,包含数十个.py脚本、图片和配置导入,在PyCharm里调试完全正常,比如设置窗口尺寸:
from kivy.config import Config Config.set("graphics", "resizable", "0") Config.set("graphics", "width", "360") Config.set("graphics", "height", "800")
但用buildozer编译后在Android Studio调试时出现严重问题:字体明显变小,所有元素定位都不对,FloatLayout里的布局和PyCharm里完全不符,连通过canvas绘制线条都无法正常显示。
试过在Android Studio里连接Python调试但没成功,现在考虑把尺寸和定位绑定到Window.width、Window.height,但这要重写大量代码,而且解决不了给特定按钮绘制线条的问题。
附其中一个程序的代码:
from kivy.app import App from kivy.config import Config Config.set("graphics", "resizable", "0") Config.set("graphics", "width", "360") Config.set("graphics", "height", "800") from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition, WipeTransition, NoTransition from kivy.uix.boxlayout import BoxLayout from kivy.uix.label import Label from kivy.uix.button import Button from kivy.graphics import Color, Line, Rectangle, BoxShadow from kivy.uix.widget import Widget class StatsApp(App): total =0 def build(self): main_layout = ScreenManager(transition=NoTransition()) screen_main_menu = Screen(name="quiz") bl = BoxLayout(orientation="vertical") main_menu = BoxLayout(size_hint_y=0.29) w1 = Widget() bt_menu = Button(text="--Главное меню--", font_size=27, size_hint_x=3, background_color=[1, 0.55, 0, 1], background_normal="") w2 = Widget() with w2.canvas: Color(1, 1, 0, .5) # Line(points=(0, 0, 443,997), width=10) Rectangle(source="bol2.jpg", pos=(358, 907), size=(450 - 359, 1000 - 907)) Rectangle(source="bol2.jpg", pos=(0, 907), size=(450 - 358, 1000 - 907)) for w in (w1, bt_menu, w2): main_menu.add_widget(w) # _____________________________________________ bl.add_widget(main_menu) res = ('никто',"ноль", 'чайник', 'дерево',"ребёнок", 'пацан', 'знаток', 'мастер', 'звезда', 'гений', 'легенда') ind = StatsApp.total lb_1 = Label(text=f"Итоговый результат", size_hint_y=0.6, font_size=45, halign="center", valign="center", color=[1, 0, 0, 1]) lb_2 = Label(text=f"{ind*10} %", size_hint_y=0.9, font_size=125, halign="center", valign="center", color=[1, 0, 0, 1]) lb_text = Label(text=f"Ваш уровень в теории футбола:", halign="center", valign="center" , font_size=50, color=[1, 0, 0, 1],size_hint_y=0.3) lb_res=Label(text=f"{res[ind]}", halign="center", valign="center" , font_size=80, color=[1, 0, 0, 1]) lb_text.text_size = 380, 550 lb_1.text_size = 380, 550 for lb in lb_1,lb_2,lb_text,lb_res: bl.add_widget(lb) def go_main_menu(instance: Button): from nosta_2014 import main as ml from nosta_2014 import quiz screen2 = Screen(name="main_menu") tl = ml.Nosta2014App.build("") screen2.add_widget(tl) main_layout.add_widget(screen2) main_layout.current = "main_menu" quiz.QuizApp.total = 0 bt_menu.bind(on_press=go_main_menu) screen_main_menu.add_widget(bl) main_layout.add_widget(screen_main_menu) with bl.canvas.before: Color(1, 1, 0, 1) Rectangle(pos=(0, 0), size=(447, 1000)) return main_layout if __name__ == "__main__": StatsApp().run()
解决方案
1. 修复DPI适配问题
Android设备的屏幕密度和桌面端差异大,直接用绝对数值会导致布局错位。在buildozer.spec中添加适配配置:
android.api = 33 android.ndk = 25b android.sdk = 24 android.use_aapt2 = True android.density = auto
同时代码中改用**密度无关像素(dp)**替代绝对数值,比如:
from kivy.metrics import dp, sp # 字体用sp(适配系统字体缩放),尺寸用dp bt_menu = Button(text="--Главное меню--", font_size=sp(27), ...) lb_1 = Label(text=f"Итоговый результат", font_size=sp(45), ...)
2. 动态绑定Canvas绘制坐标
不要硬写Canvas的pos和size,绑定父控件的尺寸变化事件,实时更新绘制内容:
from kivy.metrics import dp w2 = Widget() def update_canvas(widget, *args): widget.canvas.clear() with widget.canvas: Color(1, 1, 0, .5) # 基于父控件尺寸计算位置 right_pos = (widget.parent.width - dp(92), widget.parent.height - dp(93)) Rectangle(source="bol2.jpg", pos=right_pos, size=(dp(91), dp(93))) Rectangle(source="bol2.jpg", pos=(0, widget.parent.height - dp(93)), size=(dp(92), dp(93))) # 绑定父控件尺寸、位置变化事件 main_menu.bind(size=lambda _, __: update_canvas(w2), pos=lambda _, __: update_canvas(w2)) # 初始化调用一次 update_canvas(w2)
3. 移除固定窗口尺寸配置
删掉代码中固定窗口大小的代码,让Kivy自适应设备屏幕:
# 移除这三行 # Config.set("graphics", "resizable", "0") # Config.set("graphics", "width", "360") # Config.set("graphics", "height", "800")
依赖布局的size_hint属性自动适配,避免硬写尺寸。
4. Android调试替代方案
如果Android Studio连接Python调试失败,用以下命令查看实时日志:
buildozer android deploy run logcat
代码中添加的print()输出会在logcat中显示,方便定位问题。
内容的提问来源于stack exchange,提问作者popovic86
相关产品推荐
相关产品推荐

