Я новичок в этом, и мне действительно нужна помощь.Я успешно установил все необходимое для преобразования кода Kivy в приложение для Android.Все работает, но в моем коде я использовал модуль PyMySQL, которого нет в рецептах Python-для-Android.Некоторое время я безуспешно искал решение в Интернете.Я обнаружил, что не получающие модули должны устанавливаться автоматически с помощью pip.Но этого не происходит.Я установил модуль PyMySQL с помощью pip, но buildozer не распознает его.Когда я ввожу команду «pip list», PyMySQL находится в списке установленных модулей.В дополнение к вышесказанному, при выполнении команды «buildozer android debug» модуль не подключается к приложению, он просто пропускает его.Одним из решений этой проблемы является составление рецепта для этого модуля.Моя проблема в том, что я новичок, и я не знаю, как это сделать.Пожалуйста помоги.По возможности шаг за шагом.Я хотел бы добавить, что код работает на Windows и Linux.Что означало бы, что в коде нет проблем.Заранее спасибо.
import pymysql
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
Window.clearcolor = (0.86, 0.84, 0.76, 1)
podaci = []
def provera1(d1, d2, v1, v2, b1, b2):
""" Check that the numbers are entered and not the text. """
if d1:
try:
int(d1)
except ValueError:
return False
if d2:
try:
int(d2)
except ValueError:
return False
if v1:
try:
int(v1)
except ValueError:
return False
if v2:
try:
int(v2)
except ValueError:
return False
if b1:
try:
int(b1)
except ValueError:
return False
if b2:
try:
int(b2)
except ValueError:
return False
return True
def kamen_db():
global podaci
materijali = []
for i in podaci:
kod = str(i[0])
mat = str(i[1])
duz = str(i[2])
vis = str(i[3])
deb = str(i[4])
poz = str(i[5])
materijal = "Kod: "+kod+"\nMaterijal: "+mat+"\nDimenzije: "+duz+"x"+vis+"x"+deb+"\nPozicija: "+poz
materijali.append(materijal)
podaci = materijali
return podaci
def connect_base():
try:
# Opening DB connection
db = pymysql.connect("localhost", "testuser", "test123", "granit_novak")
db.close()
a = True
return a
except pymysql.err.OperationalError:
a = False
return a
def pokusaj_konekcije(p_kod, p_materijal, p_duz1, p_duz2, p_vis1, p_vis2, p_deb1, p_deb2, p_pozicija):
try:
# Opening DB connection
db = pymysql.connect("localhost", "testuser", "test123", "granit_novak")
# creating cursor()
cursor = db.cursor()
# KOD
if p_kod:
upit_kod = "'" + p_kod + "'"
else:
upit_kod = 'kod'
# MATERIJAL
if p_materijal:
upit_materijal = "'" + p_materijal + "'"
else:
upit_materijal = 'kamen.materijali'
# DUZINA
v_duz1 = p_duz1 or p_duz2
v_duz2 = p_duz2 or p_duz1
if v_duz1 and v_duz2:
upit_duz = ' BETWEEN ' + str(v_duz1) + ' AND ' + str(v_duz2)
else:
upit_duz = '= duzina'
# VISINA
v_vis1 = p_vis1 or p_vis2
v_vis2 = p_vis2 or p_vis1
if v_vis1 and v_vis2:
upit_vis = ' BETWEEN ' + str(v_vis1) + ' AND ' + str(v_vis2)
else:
upit_vis = '= visina'
# DEBLJINA
v_deb1 = p_deb1 or p_deb2
v_deb2 = p_deb2 or p_deb1
if v_deb1 and v_deb2:
upit_deb = ' BETWEEN ' + str(v_deb1) + ' AND ' + str(v_deb2)
else:
upit_deb = '= debljina'
# POZICIJA
if p_pozicija:
upit_pozicija = "'" + p_pozicija + "'"
else:
upit_pozicija = 'lokacija.pozicije'
komanda = 'SELECT kod, materijali, duzina, visina, debljina, pozicije\
FROM glavna INNER JOIN kamen INNER JOIN lokacija ON glavna.materijal = kamen.rb AND\
glavna.pozicija = lokacija.rb'
upit_where = ' WHERE kod = ' + upit_kod + ' AND kamen.materijali = ' + upit_materijal + '\
AND duzina ' + upit_duz + ' AND visina ' + upit_vis + '\
AND debljina ' + upit_deb + ' AND pozicije = ' + upit_pozicija + ''
komanda = komanda + upit_where
cursor.execute(komanda)
pretraga = cursor.fetchall()
db.close()
return pretraga
except pymysql.err.OperationalError:
ScreenOne.konekcija_popup()
class ScreenOne(Screen):
""" First screen. """
def konekcija(self, kod_entry, mat_entry, duz_od, duz_do, vis_od, vis_do, deb_od, deb_do, poz_entry):
izbor = provera1(duz_od, duz_do, vis_od, vis_do, deb_od, deb_do)
if izbor is True:
a = connect_base()
if a is True:
global podaci
podaci = pokusaj_konekcije(kod_entry, mat_entry, duz_od, duz_do,
vis_od, vis_do, deb_od, deb_do, poz_entry)
kamen_db()
self.change_screen()
return podaci
else:
self.konekcija_popup()
else:
self.unos_popup()
def change_screen(self):
if self.manager.current == 'Pretraga':
self.manager.current = 'Tabela'
Window.clearcolor = (0.38, 0.57, 0.69, 1)
else:
self.manager.current = 'Pretraga'
@staticmethod
def konekcija_popup():
popup = Popup(title='Baza',
content=Label(text='Konekcija sa bazom\nnije uspostavljena.\n\nPokušajte ponovo.'),
size_hint=(.7, .5))
popup.open()
@staticmethod
def unos_popup():
popup = Popup(title='Unos',
content=Label(text='Uneseni podaci nisu\nu ispravnom formatu.\n\nProverite da li ste uneli\n'
'tekst umesto cifara u\npolja sa dimenzijama.'),
size_hint=(.7, .5))
popup.open()
class ScreenTwo(Screen, BoxLayout):
""" Second screen. """
global podaci
def populate(self):
self.rv.data = [{'value': str(x)} for x in podaci]
def clear(self):
self.rv.data = []
@staticmethod
def prikaz():
if podaci:
print(podaci)
kamen_db()
else:
print("Nema nista.")
def change_screen(self):
if self.manager.current == 'Tabela':
self.manager.current = 'Pretraga'
Window.clearcolor = (0.86, 0.84, 0.76, 1)
else:
self.manager.current = 'Tabela'
class Manager(ScreenManager):
screen_one = ObjectProperty(None)
screen_two = ObjectProperty(None)
class GranitNovakApp(App):
def build(self):
return Manager()
if __name__ == '__main__':
GranitNovakApp().run()
KV файл:
<CustLabel@Label>
color: 0, 0, 0, 1
<MatLabel@CustLabel>:
text_size: self.size
padding: (10, 0)
halign: "left"
valign: "middle"
<Manager>:
id: screen_manager
screen_one: screen_one
screen_two: screen_two
ScreenOne:
id: screen_one
name: "Pretraga"
manager: screen_manager
ScreenTwo:
id: screen_two
name: "Tabela"
manager: screen_manager
<ScreenOne>:
GridLayout:
id: search
rows: 11
spacing: 10
padding: 10
BoxLayout:
CustLabel:
text: "GRANIT NOVAK"
bold: True
italic: True
font_size: 54
BoxLayout:
CustLabel:
text: "Kod: "
size_hint: .33, 1
TextInput:
id: kod_entry
size_hint: .66, 1
multiline: False
BoxLayout:
CustLabel:
text: "Materijal: "
size_hint: .33, 1
TextInput:
id: mat_entry
size_hint: .66, 1
multiline: False
BoxLayout:
CustLabel:
text: "Pozicija: "
size_hint: .33, 1
TextInput:
id: poz_entry
size_hint: .66, 1
multiline: False
BoxLayout:
CustLabel:
text: " "
CustLabel:
text: "od"
CustLabel:
text: "do"
BoxLayout:
CustLabel:
text: "Duzina:"
TextInput:
id: duz_od
multiline: False
TextInput:
id: duz_do
multiline: False
BoxLayout:
Label:
text: " "
CustLabel:
text: "od"
CustLabel:
text: "do"
BoxLayout:
CustLabel:
text: "Visina:"
TextInput:
id: vis_od
multiline: False
TextInput:
id: vis_do
multiline: False
BoxLayout:
Label:
text: " "
CustLabel:
text: "od"
CustLabel:
text: "do"
BoxLayout:
CustLabel:
text: "Debljina:"
TextInput:
id: deb_od
multiline: False
TextInput:
id: deb_do
multiline: False
BoxLayout:
Button:
text: "POTVRDI"
on_release:
root.konekcija(kod_entry.text, mat_entry.text, duz_od.text, duz_do.text,
vis_od.text, vis_do.text, deb_od.text, deb_do.text, poz_entry.text)
root.manager.transition.direction = "left"
root.manager.transition.duration = .2
<Row@BoxLayout>:
canvas.before:
Color:
rgba: 0.86, 0.84, 0.76, 1
Rectangle:
size: self.size
pos: self.pos
value: ''
MatLabel:
text: root.value
<ScreenTwo>:
rv: rv
orientation: 'vertical'
GridLayout:
id: display
rows: 3
spacing: 5
padding: 5
BoxLayout:
size_hint_y: .1
bgcolor: 0.86, 0.84, 0.76, 1
canvas:
Color:
rgba: self.bgcolor
Rectangle:
pos: self.pos
size: self.size
CustLabel:
text: "Rezultati pretrage:"
font_size: 40
RecycleView:
id: rv
scroll_type: ['bars', 'content']
scroll_wheel_distance: dp(114)
bar_width: dp(10)
viewclass: 'Row'
RecycleBoxLayout:
default_size: None, dp(100)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
spacing: dp(2)
GridLayout:
id: dug
cols: 2
size_hint_y: .1
spacing: 5
padding: 2
BoxLayout:
size_hint_y: .1
Button:
text: "Prikaz"
focus: True
on_release:
root.populate()
BoxLayout:
size_hint_y: .1
Button:
text: "NAZAD"
on_release:
root.clear()
root.change_screen()
root.manager.transition.direction = "right"
root.manager.transition.duration = .2