我一直在为我的工作场所开发我的第一个应用程序,并使其达到需要其他人测试的地步。但是,无论是通过buildozer还是使用Kivy启动器进行编译,我都看不出哪里出了问题,只是在启动时立即崩溃了。
由于我知道Kivy启动器的支持有限,我已经尝试将代码回切到仅没有MySQL的登录页面。 我设法使用buildozer来创建Kivy示例的apk和另一段演示代码。
main.py:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
import time
import pymysql.cursors
global mycursor
global end1
global ad
global ogl
global enum
global snum
ogl = []
connection = pymysql.connect(host="localhost", user="user", password="pw", db="user", charset='utf8mb4', cursorclass=pymysql.cursors.Cursor)
mycursor = connection.cursor()
class SigninWindow(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def validate_user(self):
user = self.ids.username_field
pwd = self.ids.pwd_field
info = self.ids.info
uname = user.text
passw = pwd.text
sqluname = "hold"
sqlpassw = "hold"
if uname == '' or passw == '':
info.text = '[color=#808080]You need a username or password![/color]'
else:
mycursor = connection.cursor()
sql = ("SELECT * FROM users WHERE user_name = %s")
val = (uname)
mycursor.execute(sql, val)
myresult = mycursor.fetchall()
for x in myresult:
sqluname = x[3]
sqlpassw = x[4]
if uname == sqluname and passw == sqlpassw:
info.text = '[color=#808080]Success![/color]'
self.manager.current = 'Menu'
self.ids.username_field.text = ""
self.ids.pwd_field.text = ""
self.ids.info.text = ""
else:
info.text = '[color=#808080]Invalid username or password[/color]'
self.ids.username_field.text = ""
self.ids.pwd_field.text = ""
class MenuWindow(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def CSGO(self):
self.manager.current = 'CutSheet'
def DIGO(self):
self.manager.current = 'DrumInput'
def SIGO(self):
self.manager.current = 'Signin'
class CutSheetWindow(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def home(self):
self.manager.current = 'Menu'
self.ids.drum_container.clear_widgets()
self.ids.ic_field.text = ""
self.ids.ic_hold.text = 'Incoming Number'
self.ids.pc_hold.text = 'Product Code'
self.ids.l_hold.text = 'Length'
self.ids.sm_hold.text = 'Start Mark'
self.ids.em_hold.text = 'End Mark'
def lbupdate(self):
global snum
global enum
ic = self.ids.ic_field.text
sql = ("SELECT * FROM ic_drum WHERE ic_number = %s")
val = (ic,)
mycursor.execute(sql, val)
myresult = mycursor.fetchall()
drum_container = self.ids.drum_container
drum_container.clear_widgets()
for x in myresult:
ic = x[0]
self.ids.ic_hold.text = str(ic)
pc = x[1]
self.ids.pc_hold.text = str(pc)
l = x[2]
self.ids.l_hold.text = str(l)
sm = x[3]
quant = sm
self.ids.sm_hold.text = str(sm)
em = x[4]
self.ids.em_hold.text = str(em)
up = x[6]
sql = ("SELECT length FROM `Products` WHERE `BT Item Code` = %s ")
val = (str(pc) ,)
mycursor.execute(sql, val)
cutb = mycursor.fetchone()
cuta = cutb[0]
cut = cuta
snum = []
enum = []
if up == 1:
while quant < em-cut:
details = GridLayout(cols=3,size_hint_y=None,height=30,pos_hint={'top': 1})
drum_container.add_widget(details)
details.add_widget(Label(text=str(quant),size_hint_x=.2,color=(0,0,0,1)))
quant = quant + cut
snum.append(quant)
details.add_widget(Label(text=str(quant),size_hint_x=.2,color=(0,0,0,1)))
quant = quant + 1
enum.append(quant)
og = (TextInput(hint_text='Outgoing Number', multiline=False,size_hint_x=.2,height=20))
details.add_widget(og)
og.fbind('on_text_validate', self.on_event,self.green)
quant = l-quant
else:
while quant > sm-l+cut:
details = GridLayout(cols=4,size_hint_y=None,height=30,pos_hint={'top': 1})
drum_container.add_widget(details)
details.add_widget(Label(text=str(quant),size_hint_x=.2,color=(0,0,0,1)))
snum.append(quant)
quant = quant - cut
details.add_widget(Label(text=str(quant),size_hint_x=.2,color=(0,0,0,1)))
enum.append(quant)
quant = quant - 1
og = (TextInput(hint_text='Outgoing Number', multiline=False,size_hint_x=.2,height=20))
details.add_widget(og)
og.fbind('on_text_validate', self.on_event)
self.ids.test.text = 'Send'
sql = ("UPDATE ic_drum SET waste = '%s' WHERE ic_number = '%s'")
val = (quant,ic,)
mycursor.execute(sql, val)
connection.commit()
def on_event(self,og):
global ogl
ogl.append(int(og.text))
og.foreground_color=(0,1,0,1)
def ogsend(self):
ic = self.ids.ic_field.text
sql = ("SELECT product_code FROM `ic_drum` WHERE `ic_number` = %s ")
val = (float(ic) ,)
mycursor.execute(sql, val)
pc = mycursor.fetchone()
pc = pc[0]
if len(snum) == len(ogl):
for i in range(len(snum)):
s = snum[i]
e = enum[i]
o = ogl[i]
sql = ("INSERT INTO `outgoing`(`ic_number`, `product_code`, `start`, `end`, `outgoing`) VALUES (%s,%s,%s,%s,%s)")
val = (ic,pc,s,e,o)
mycursor.execute(sql, val)
connection.commit()
else:
content = Button(text='Missing outgoing numbers')
popup = Popup(title='Error', content=content,auto_dismiss=True)
content.bind(on_press=popup.dismiss)
popup.open()
class DrumInputWindow(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def home(self):
self.manager.current = 'Menu'
# For Switch
def switch_on(self, instance, value):
global end1
global ad
if len(self.ids.length_field.text) == 0:
content = Button(text='Enter Values First!')
popup = Popup(title='Error', content=content,auto_dismiss=True)
content.bind(on_press=popup.dismiss)
popup.open()
else:
l = self.ids.length_field.text
sm = self.ids.start_field.text
hl = float(l)
hs = float(sm)
if value is True:
hld = str(hl+hs)
end1 = hld
ad = 1
else:
hld = str(hl-hs)
end1 = hld
ad = 0
def drum_hold(self):
ic = self.ids.ic_field.text
pc = self.ids.pc_field.text
l = self.ids.length_field.text
sm = self.ids.start_field.text
em = end1
drum_container = self.ids.drum_container
if len(ic) == 4:
details = BoxLayout(size_hint_y=None,height=30,pos_hint={'top': 1})
drum_container.add_widget(details)
incoming = Label(text=ic,size_hint_x=.2,color=(1,0,0,1))
pcode = Label(text=pc,size_hint_x=.2,color=(1,0,0,1))
length = Label(text=l,size_hint_x=.2,color=(1,0,0,1))
smark = Label(text=sm,size_hint_x=.2,color=(1,0,0,1))
emark = Label(text=em,size_hint_x=.2,color=(1,0,0,1))
hold = Label(text='Sent',size_hint_x=.2,color=(1,0,0,1))
details.add_widget(incoming)
details.add_widget(pcode)
details.add_widget(length)
details.add_widget(smark)
details.add_widget(emark)
details.add_widget(hold)
prod = '%.6s' % str(pc)
sql = ("INSERT INTO `ic_drum` (`ic_number`, `product_code`, `quantity`, `start`, `end`,`waste`) VALUES (%s,%s,%s,%s,%s,%s)")
val = (float(ic),prod,float(l),float(sm),float(em),ad)
mycursor.execute(sql, val)
connection.commit()
else:
content = Button(text='IC number needs to be 4 digits')
popup = Popup(title='Error', content=content,auto_dismiss=True)
content.bind(on_press=popup.dismiss)
popup.open()
class WindowManager(ScreenManager):
pass
kv = Builder.load_file("my.kv")
class SkynetApp(App):
def build(self):
return kv
if __name__ == "__main__":
SkynetApp().run()
my.kv:
#:kivy 1.1.6
WindowManager:
SigninWindow:
MenuWindow:
DrumInputWindow:
CutSheetWindow:
<FlatButton@ButtonBehavior+Label>:
font_size: 16
<SigninWindow>:
id: main_win
name: 'Signin'
space_x: self.size[0]/3
BoxLayout:
orientation: "vertical"
spacing: 10
canvas.before:
Color:
rgba: (1,1,1,1)
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
size_hint_y: None
height: 100
canvas.before:
Color:
rgba: (1,0,0,1)
Rectangle:
size: self.size
pos: self.pos
Image:
source: "logo.jpg"
size_hint_x: .4
Label:
text: "Login"
bold: True
font_size: 16
size_hint_x: .5
FlatButton:
text: "x"
size_hint_x: .1
BoxLayout:
orientation: "vertical"
padding: main_win.space_x, 10
spacing: 20
BoxLayout:
orientation: "vertical"
spacing: 10
size_hint_y: None
height: 100
Label:
id: info
text: ''
markup: True
TextInput:
id: username_field
hint_text: "Username"
multiline: False
focus: True
on_text_validate: pwd_field.focus = True
TextInput:
id: pwd_field
hint_text: "Password"
multiline: False
password: True
on_text_validate: root.validate_user()
Button:
text: "Sign In"
size_hint_y: None
height: 40
background_color: (1,0,0,1)
background_normal: ''
on_release: root.validate_user()
Label:
id: sp2
<MenuWindow>:
id: Menu
name: "Menu"
BoxLayout:
orientation: "vertical"
space_x: self.size[0]/3
spacing: 10
canvas.before:
Color:
rgba: (1,1,1,1)
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
size_hint_y: None
height: 100
spacing: 10
canvas.before:
Color:
rgba: (1,0,0,1)
Rectangle:
size: self.size
pos: self.pos
Image:
source: "logo.jpg"
size_hint_x: .4
Label:
text: "Menu"
bold: True
font_size: 16
size_hint_x: .5
FlatButton:
text: "x"
size_hint_x: .1
GridLayout:
cols:1
canvas.before:
Color:
rgba: 1,1,1,1
Rectangle:
pos: self.pos
size: self.size
orientation: 'vertical'
spacing: 10
Button:
text: "Cut Sheet"
size_hint_y: None
height: 40
size_hint_x: .6
background_color: (1,0,0,1)
background_normal: ''
on_release: root.CSGO()
Button:
text: "Drum Input"
size_hint_y: None
height: 40
size_hint_x: .6
background_color: (1,0,0,1)
background_normal: ''
on_release: root.DIGO()
Button:
text: "Sign Out"
size_hint_y: None
height: 40
size_hint_x: .6
background_color: (1,0,0,1)
background_normal: ''
on_release: root.SIGO()
Label:
id: sp2
<DrumInputWindow>:
id: DrumInput
name: "DrumInput"
BoxLayout:
orientation: "vertical"
size: 400,400
canvas.before:
Color:
rgba: (1,1,1,1)
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
size_hint_y: None
height: 100
spacing: 10
canvas.before:
Color:
rgba: (1,0,0,1)
Rectangle:
size: self.size
pos: self.pos
Image:
source: "logo.jpg"
size_hint_x: .4
Label:
text: "Drum Input"
bold: True
font_size: 16
size_hint_x: .5
FlatButton:
text: "x"
size_hint_x: .1
on_release:root.home()
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: 40
BoxLayout:
padding: 10
spacing: 10
canvas.before:
Color:
rgba: (0,0,0,1)
Rectangle:
size: self.size
pos: self.pos
FlatButton:
text: "Incoming Number"
FlatButton:
text: "Product Code"
FlatButton:
text: "Length"
FlatButton:
text: "Start Mark"
FlatButton:
text: "Up/Down"
FlatButton:
text: "Holder"
color: (0,0,0,1)
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: 60
BoxLayout:
padding: 10
spacing: 10
TextInput:
id: ic_field
size_hint_x: .1
hint_text: "Incoming No"
multiline: False
focus: True
on_text_validate: pc_field.focus = True
TextInput:
id: pc_field
size_hint_x: .1
hint_text: "Product Code"
multiline: False
on_text_validate: length_field.focus = True
TextInput:
id: length_field
size_hint_x: .1
hint_text: "Length"
multiline: False
on_text_validate: start_field.focus = True
TextInput:
id: start_field
size_hint_x: .1
hint_text: "Start Marking"
multiline: False
Switch:
size_hint_x: .1
id: switch
on_active: root.switch_on(self, self.active)
Button:
text: "Submit"
size_hint_x: .1
background_color: (1,0,0,1)
background_normal: ''
on_release: root.drum_hold()
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: 40
BoxLayout:
padding: 10
spacing: 10
canvas.before:
Color:
rgba: (0,0,0,1)
Rectangle:
size: self.size
pos: self.pos
FlatButton:
text: "Incoming Number"
FlatButton:
text: "Product Code"
FlatButton:
text: "Length"
FlatButton:
text: "Start Mark"
FlatButton:
text: "End Mark"
FlatButton:
text: "Status"
GridLayout:
cols: 1
rows: 2
ScrollView:
size_hint: (1, .9)
bar_width: 100
bar_color: 1, 0, 0, 1 # red
bar_inactive_color: 0, 0, 1, 1 # blue
effect_cls: "ScrollEffect"
scroll_type: ['bars']
GridLayout:
cols: 1
id:drum_container
size_hint_y: None
height: 40
<CutSheetWindow>:
id: CutSheet
name: 'CutSheet'
BoxLayout:
orientation: "vertical"
size: self.size
canvas.before:
Color:
rgba: (1,1,1,1)
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
size_hint_y: None
height: 100
spacing: 10
canvas.before:
Color:
rgba: (1,0,0,1)
Rectangle:
size: self.size
pos: self.pos
Image:
source: "logo.jpg"
size_hint_x: .4
#align: left
Label:
text: "Cut Sheet"
bold: True
font_size: 16
size_hint_x: .5
FlatButton:
text: "x"
size_hint_x: .1
on_release: root.home()
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: 60
BoxLayout:
padding: 10
spacing: 10
canvas.before:
Color:
rgba: (0,0,0,1)
Rectangle:
size: self.size
pos: self.pos
FlatButton:
id: test
size_hint_x: .2
text: "Incoming Number"
on_release: root.ogsend()
TextInput:
id: ic_field
size_hint_x: .2
hint_text: "Incoming No"
multiline: False
focus: True
Button:
value: False
text: "Submit"
size_hint_x: .1
background_color: (1,0,0,1)
background_normal: ''
on_release: root.lbupdate()
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: 25
BoxLayout:
padding: 10
spacing: 10
canvas.before:
Color:
rgba: (0,0,0,1)
Rectangle:
size: self.size
pos: self.pos
FlatButton:
text: "Incoming Number"
FlatButton:
text: "Product Code"
FlatButton:
text: "Length"
FlatButton:
text: "Start Mark"
FlatButton:
text: "End Mark"
BoxLayout:
orientation: 'vertical'
size_hint_y: None
height: 25
font_size: 10
BoxLayout:
padding: 10
spacing: 10
canvas.before:
Color:
rgba: (0,0,0,1)
Rectangle:
size: self.size
pos: self.pos
FlatButton:
text: "Incoming Number"
id: ic_hold
FlatButton:
text: "Product Code"
id: pc_hold
FlatButton:
text: "Length"
id: l_hold
FlatButton:
text: "Start Mark"
id: sm_hold
FlatButton:
text: "End Mark"
id: em_hold
GridLayout:
cols: 1
rows: 1
ScrollView:
bind: True
size_hint: (1, .9)
bar_width: 100
bar_color: 1, 0, 0, 1 # red
bar_inactive_color: 0, 0, 1, 1 # blue
effect_cls: "ScrollEffect"
scroll_type: ['bars']
GridLayout:
orientation: 'vertical'
cols: 4
id:drum_container
size_hint_y: None
height: 40
我没有收到任何错误消息,只是崩溃了。该代码可以在Windows和Linux(Lubuntu 18.04)上完美运行,但是在Android上无法执行任何操作。