应用程序在 Python2 和 Python3 中的 Windows 上运行良好,但收到错误:无法导入 android,并且按钮无响应

Posted

技术标签:

【中文标题】应用程序在 Python2 和 Python3 中的 Windows 上运行良好,但收到错误:无法导入 android,并且按钮无响应【英文标题】:App works well on Windows in Python2 & Python3, but receiving Error : failed to import android, and Button unresponsive 【发布时间】:2018-03-21 18:28:48 【问题描述】:

这是一个使用 python 2.7 编写的应用程序,使用 kivynumpy 模块。我已经按照此链接中的步骤安装了buildozer:https://github.com/kivy/buildozer,我没有做sudo pip install https://github.com/kivy/buildozer/archive/master.zip。在 android buildozer android deploy run logcat 上部署应用程序后,我在日志中看到了一些错误:

10-10 17:44:49.497 19176 19207 I python  : [ERROR  ] [Image       ] Error reading file .\logo_example1.png
10-10 17:44:49.498 19176 19207 I python  : [WARNING] [Base        ] Unknown <android> provider
10-10 17:44:49.498 19176 19207 I python  : [INFO   ] [Base        ] Start application main loop
10-10 17:44:49.503 19176 19207 I python  : [INFO   ] [GL          ] NPOT texture support is available
10-10 17:44:49.504 19176 19207 I python  : 0
10-10 17:44:49.504 19176 19207 I python  : coloring
10-10 17:44:49.505 19176 19207 I python  : [ERROR  ] [Base        ] Failed to import "android" module. Could not remove android presplash.

问题:Image 小部件未显示,并且按钮的 touch 似乎未收到任何事件/响应。可以给我反馈一下吗,谢谢。

当前部分解决: Image 小部件现在显示,我将源地址从 .\\logo_example1.png 更改为 logo_example1.png

存在的问题:Button 小部件在 android 上仍然无法响应触摸,但在 Windows 上可以正常工作。

测试开始和后退按钮的代码:

这是main.kv

#: import Main main    
<CtmButton@Button>:
    font_size:30
    size:100, 50
<BackButton@Button>:
    font_size:30
    size:100, 50
    text: "Back"
    pos: Main.Wsize[0]+100, Main.Wsize[1]+100
<mainWidget>:
    id: main_widget
<homeWidget>:
    id: home_widget
    padding : 200
    Image:
        id:logo
        source: 'logo_example1.png'
        center: 300, 450
    CtmButton:
        id: start_button
        text: "Start"
        center:300, 200
        on_release: home_widget.startbutton_function()
    ## I also have tried replacing this with on_touch_down
    ## to see whether it will solve the problem
<puzzleWidget>:
    id: puzzle_widget
    BackButton:
        id: back_button_1
        center: 100, 37.5
        on_release: puzzle_widget.backbutton_function()

这是main.py

import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.core.window import Window
from kivy.uix.image import Image
from kivy.core.image import ImageData
from kivy.clock import Clock
from kivy.graphics import Rectangle
import time
import math
import itertools
import numpy 
Window.clearcolor = (0.2, 0.25, 0.2, 0.5); col_dx = 0.005; y = list(Window.clearcolor); xstart = 0;
Window.size = (600, 700); Wsize = Window.size;
class mainWidget(Widget):
    def __init__(self):
        Widget.__init__(self);
        home = homeWidget(); self.add_widget(home);
class homeWidget(Widget):
    def __init__(self):
        Widget.__init__(self);
        self.bg_animate();
    def printingsomething(self, dt):
        print(dt);
    def bg_animate(self):
        global bg_anim
        self.bg_anim = Clock.schedule_interval(self.printingsomething,1/40);
        self.bg_anim();
    def startbutton_function(self):
        print('start pressed');
        self.bg_anim.cancel();
        mainw.clear_widgets();
        mainw.add_widget(puzzleWidget());
class puzzleWidget(Widget):
    def __init__(self):
        Widget.__init__(self); 
        self.Bar1 = Image(size = [600, 75], color = list(Window.clearcolor)); self.Bar1.color[-1] = 0.8; self.Bar1.pos = [0, 700 - self.Bar1.size[1]];
        self.Bar2 = Image(size = [600, 75], color = list(Window.clearcolor)); self.Bar2.color[-1] = 0.8; self.Bar2.pos = [0, 0];
        #### ADD WIDGET(S):
        self.add_widget(self.Bar1); self.add_widget(self.Bar2); 
        self.remove_widget(self.ids.back_button_1); self.add_widget(self.ids.back_button_1);
    def backbutton_function(self):
        print('back pressed');
        self.clear_widgets();
        mainw.clear_widgets();
        mainw.add_widget(homeWidget());
################## main window for the app #########################
class mainApp(App):    
    def build(self):
        global mainw
        mainw = mainWidget();
        return mainw
####################################################################
mainApp = mainApp()
mainApp.run();

【问题讨论】:

您可能需要在 buildozer.spec 中将android 添加到您的要求中。 @Tshirtman 请问为什么..?我认为官方步骤足够紧凑.. @Tshirtman 我试过了,按钮仍然没有收到任何响应。 【参考方案1】:

导入“android”模块失败。

此消息与图像无关。如果您不明确使用android 模块,它不会影响您的项目。为了避免在日志中出现这一行,您需要做的就是将 android 添加到 buildozer.spec 内的需求中。

读取文件时出错.\logo_example1.png

此错误表示找不到图像。我不知道.\\logo_example1.png 有什么问题,但最好只使用绝对路径而忘记问题。

import os

root_dir = os.path.dirname(os.path.abspath(__file__))
img_rel = 'logo_example1.png'
img_abs = os.path.join(root_dir, img_rel)

print(img_abs)

更新:

按下问题与此行有关 - Window.size = (600, 700)。删除它,一切都会正常。

看起来更改 Window.size 会以某种方式破坏 kivy 接触点检测。如果你想在 Windows 上更改窗口大小,use Config 或 wrap Window.size 更改为 platform check。

【讨论】:

谢谢,我已经编辑了帖子,Image 小部件现在显示。剩下的问题是Button 小部件对手机触摸无响应。 @Arief 你能提供重现问题的代码吗? 我已经清除了Window.sizetouch 在电话上仍然没有响应。但我也使用Window.clearcolor=...,并且我会在几分之一秒内不断更新它。也删除了它,仍然没有反应。但是等等,...我想可能是因为我使用Window.mouse_pos 来定位光标,这就是为什么它只适用于 Windows?抱歉,我没有在上面的测试代码中包含这个。 @Arief,我运行了与您发布的完全相同的代码并且触摸也没有响应(实际上您可以按下按钮,但在屏幕的其他位置 - 相对于实际按钮位置的右上角)。当我删除 Window.size = (600, 700) 时,我在 Android 上完美地工作了。我不知道要添加什么:) 请确保您在没有该行的情况下重建 App 并且没有添加任何其他代码。 谢谢。我又试了一次,没有Window.sizeWindow.mouse_pos。该按钮现在正在接收手机上的触摸响应,但在on_release 之后立即崩溃。错误说它无法加载Image 对象。在我将png 文件移动到与main.py 相同的文件夹后,现在它可以在手机上正常工作(仅通过filename.png 更改文件地址)。另外,我认为在buildozer.spec 中更改fullscreen 没有任何区别。

以上是关于应用程序在 Python2 和 Python3 中的 Windows 上运行良好,但收到错误:无法导入 android,并且按钮无响应的主要内容,如果未能解决你的问题,请参考以下文章

在CMD 中,如何切换python2.x 版本 和 python3.x版本?

Windows下配置Python2和Python3

让你的python程序同时兼容python2和python3

Python2和Python3中print的不同点

在 Python3/Django1.8 网络应用程序中使用 Python2 库

python2和python3编码区别