Skip to content

Instantly share code, notes, and snippets.

@CoutinhoElias
Last active April 12, 2021 17:19
Show Gist options
  • Save CoutinhoElias/2691a495742b76d0ca5394ca79a2dc08 to your computer and use it in GitHub Desktop.
Save CoutinhoElias/2691a495742b76d0ca5394ca79a2dc08 to your computer and use it in GitHub Desktop.
[CRITICAL] [Clock] Warning, too much iteration done before the next frame. Check your code, or increase the Clock.max_iteration attribute
'''MY main.py'''
import json
import unicodedata
import string
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.properties import ObjectProperty, StringProperty
from kivy.network.urlrequest import UrlRequest
from kivy.uix.screenmanager import Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import AsyncImage
from kivymd.uix.list import TwoLineIconListItem, ThreeLineIconListItem
from kivymd.uix.list import TwoLineAvatarListItem, ThreeLineAvatarListItem
from kivymd.uix.list import ImageLeftWidget
from kivymd.uix.datatables import MDDataTable
from kivymd.uix.textfield import MDTextField
from kivymd.uix.card import MDCard
from kivy.metrics import dp
from kivymd.app import MDApp
from models import Produto
from datetime import datetime
#import firebase_admin
#from firebase_admin import credentials
#from firebase_admin import db
import pyrebase
# Classes AsyncImageLeftWidget, ItemImage criada para associar ImageLeftWidget e AsyncImage.
class AsyncImageLeftWidget(ImageLeftWidget, AsyncImage):
pass
class ItemImage(TwoLineAvatarListItem):
source = StringProperty()
class CovidImage(ThreeLineAvatarListItem):
source = StringProperty()
class SenhaCard(MDCard):
def fechar(self):
self.parent.remove_widget(self)
class TelaLogin(Screen):
def login(self):
# Chaves para acessar o banco de dados.
'''
Attention
The configuration data has been changed, it is false.
'''
firebaseConfig = {
"apiKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"authDomain": "inventarioshop-8318f.firebaseapp.com",
"databaseURL": "https://inventarioshop-8318f-default-rtdb.firebaseio.com",
"projectId": "inventarioshop-8318f",
"storageBucket": "inventarioshop-8318f.appspot.com",
"messagingSenderId": "321654987159",
"appId": "1:123456789123:web:zzzzzzzzzzzzzzzzzzzzz",
"measurementId": "G-S5F5G98H4J"
}
# Inicializando o banco de dados.
firebase = pyrebase.initialize_app(firebaseConfig)
auth =firebase.auth()
email = '[email protected]'
password = 'Salmo8318'
try:
auth.sign_in_with_email_and_password(email, password)
self.manager.current = 'main'
except:
print('Usuário ou senha inválidos!')
self.manager.current = 'tela_singin'
def abrir_card(self):
print('Abrindo o card...')
self.add_widget(SenhaCard())
class MainScreen(Screen):
pass
class ProductsDataTableScreen(Screen):
def on_kv_post(self, base_widget):
p = Produto.select(Produto.cdchamada,
Produto.nmproduto,
Produto.stativo,
Produto.cdipi,
Produto.cest)
# .where(Produto.cdchamada.in_(['000003', '000005','000012']))
rd = []
for row in p.dicts()[:50]:
if row['stativo'] == 'S':
rd.append((row['cdchamada'],
("checkbox-marked-circle", [39 / 256, 174 / 256, 96 / 256, 1], "Online"),
row['nmproduto'],
row['cdipi'], row['cest']))
else:
rd.append((row['cdchamada'],
("alert-circle", [1, 0, 0, 1], "Offline"),
row['nmproduto'],
row['cdipi'], row['cest']))
# self.data_fields = MDTextField(
# hint_text="Helper text on focus",
# helper_text="This will disappear when you click off",
# helper_text_mode="on_focus",
# size_hint_x=0.5
# )
#
# self.ids.header.add_widget(self.data_fields)
self.data_tables = MDDataTable(
# MDDataTable allows the use of size_hint (Largura, Altura)
size_hint=(0.8, 0.7),
use_pagination=True,
pagination_menu_pos='auto',
check=True,
column_data=[
("Código", dp(30)),
("Status", dp(30)),
("Descrição", dp(60), self.sort_on_signal),
("NCM", dp(30), self.sort_on_schedule),
("CEST", dp(30), self.sort_on_team),
],
row_data= rd,
sorted_on="Schedule",
sorted_order="ASC",
elevation=2
)
self.data_tables.bind(on_row_press=self.on_row_press)
self.data_tables.bind(on_check_press=self.on_check_press)
print(self.data_tables)
self.ids.body.add_widget(self.data_tables)
def on_row_press(self, instance_table, instance_row):
'''Called when a table row is clicked.'''
print(instance_table, instance_row)
def on_check_press(self, instance_table, current_row):
'''Called when the check box in the table row is checked.'''
print(instance_table, current_row)
def sort_on_signal(self, data):
return sorted(data, key=lambda l: l[2])
def sort_on_schedule(self, data):
return sorted(data, key=lambda l: sum([int(l[-2].split(":")[0])*60, int(l[-2].split(":")[1])]))
def sort_on_team(self, data):
return sorted(data, key=lambda l: l[-1])
class MenuProductsScreen(Screen):
def on_kv_post(self, base_widget):
pass
#self.ids.rbt_export_products.disabled = False
def remove_quotation_character(self, text: str):
for c in string.punctuation:
text = text.replace(c,"")
return text
def remove_non_ascii_normalized(self, string: str) -> str:
normalized = unicodedata.normalize('NFD', string)
return normalized.encode('ascii', 'ignore').decode('utf8').upper()
def normaliza_texto(self):
produtos = Produto.select()[:20]
for x in produtos:
#print(x.nmproduto)
x.nmproduto = self.remove_non_ascii_normalized(x.nmproduto)
x.save()
#self.ids.rbt_normalizes_products.disabled = True
#self.ids.rbt_remove_char_products.disabled = False
def normaliza_pontuacao(self):
produtos = Produto.select()[:20]
for x in produtos:
#print(x.nmproduto)
x.nmproduto = self.remove_quotation_character(x.nmproduto)
x.save()
#self.ids.rbt_normalizes_products.disabled = True
#self.ids.rbt_remove_char_products.disabled = True
#self.ids.rbt_export_products.disabled = False
def salva_produtos_json(self):
# Chaves para acessar o banco de dados.
firebaseConfig = {
"apiKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"authDomain": "inventarioshop-8318f.firebaseapp.com",
"databaseURL": "https://inventarioshop-8318f-default-rtdb.firebaseio.com",
"projectId": "inventarioshop-8318f",
"storageBucket": "inventarioshop-8318f.appspot.com",
"messagingSenderId": "321654987159",
"appId": "1:123456789123:web:zzzzzzzzzzzzzzzzzzzzz",
"measurementId": "G-S5F5G98H4J"
}
# Inicializando o banco de dados.
firebase = pyrebase.initialize_app(firebaseConfig)
db = firebase.database()
#auth =firebase.auth()
q = Produto.select(Produto.cdchamada,
Produto.nmproduto,
Produto.stativo).order_by(Produto.cdchamada).where(Produto.cdchamada.in_(['000003', '000005','000012']))
produto = {}
# Adicionando os dicts do peewee em uma tabela do Firebase.
for row in q.dicts():
# Adiciona um campo Quantidade com valor Zero
row.update({'Quantidade': 0})
produto[row['cdchamada']] = row
produtos = {"Produtos": produto}
db.child('Produtos').update(produto)
print(json.dumps(produto, indent=4))
print('***** JSON EXPORTADO *****')
class ProductsScreen(Screen):
# Esta função deve ser inicializada antes da on_enter pois assim evita o erro
# AttributeError: 'super' object has no attribute '__getattr__'
def on_kv_post(self, base_widget):
q = Produto.select(Produto.cdchamada, Produto.nmproduto)
for row in q.dicts()[:20]:
# Cria o Widget conforme sua escolha.
'''Forma personalizada'''
items = ItemImage(text=str(row['cdchamada']),
secondary_text=row['nmproduto'],
source="./images/coragem_feliz.png")
'''Forma tradicional
# Cria a imagem que será usada no TwoLineIconListItem.
# image = ImageLeftWidget(source="./images/chamada_preto_branco.png")
# Cria o Widget conforme sua escolha.
# items = TwoLineIconListItem(text=str(l),
# secondary_text='Produto {}'.format(str(l)))
# Adiciona a imagem ao Widget acima.
#items.add_widget(image)
'''
# Adiciona o Widget à lista.
self.ids.produtos_da_lista.add_widget(items)
class ListScreen(Screen):
info_loaded = False
''' Será utilizada para chamar ou não a conexão com o WShop '''
def on_enter(self):
if not self.info_loaded:
self.request()
'''Essa função será usada somente no final do projeto, por enquanto ignoraremos'''
def request(self, *args):
def on_success(rec, response):
#print(json.dumps(response, indent=4))
for i in response['data']:
items = CovidImage(text=i['state'],
secondary_text='Casos de COVID-19: ' + str(i['cases']),
tertiary_text='Casos suspeitos: ' + str(i['suspects']),
source='https://overiq.com/media/uploads/2018/2/6/python-5098a18d-52ac-4e6f-8008-77af1a5c1800.png')
self.ids.itens_da_lista.add_widget(
items
)
self.info_loaded = True
def on_failure(rec, response):
print('Falhou:' + str(response))
def on_error(rec, response):
print('Deu Erro:' + str(response))
UrlRequest('https://covid19-brazil-api.now.sh/api/report/v1',
on_success=on_success,
on_failure=on_failure,
on_error=on_error)
def update_list(self):
self.info_loaded = False
self.ids.itens_da_lista.clear_widgets()
self.request()
class ContentNavigationDrawer(BoxLayout):
screen_manager = ObjectProperty()
nav_drawer = ObjectProperty()
class DeskShop(MDApp):
def build(self):
#self.theme_cls.primary_palette = "Purple"
self.theme_cls.theme_style = "Dark" # "Light"
return Builder.load_file('main.kv')
# Window.maximize()
DeskShop().run()
''' My main.kv'''
# Inicio do KV_LANG
<ContentNavigationDrawer>:
orientation: "vertical"
FloatLayout:
size_hint_y: None
height: "200dp"
BoxLayout:
id: box_image
x: root.x
pos_hint: {"top": 1}
FloatLayout:
# Imagem de fundo
FitImage:
pos_hint: {'center_x': .5, 'center_y': .5}
source: "./images/menu.png"
# Imagem do usuário
FitImage:
pos_hint: {'center_x': .5, 'center_y': .5}
source: "data/logo/kivy-icon-256.png"
size_hint: None, None
width: dp(150)
height: dp(150)
radius: [99, 99, 99, 99]
MDLabel:
text: "Coletor de dados WShop"
size_hint_y: None
height: self.texture_size[1]
# Define a posição do Label
x: root.x + 10
y: root.height - box_image.height + dp(10)
ScrollView:
MDList:
OneLineIconListItem:
text: "Trata e Exporta Dados"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = 'menu_products_screen'
root.screen_manager.transition.direction = 'left'
IconLeftWidget:
icon: 'store'
OneLineIconListItem:
text: "Lista de produtos"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = 'products_screen'
root.screen_manager.transition.direction = 'left'
IconLeftWidget:
icon: 'store'
OneLineIconListItem:
text: "Produtos DataTable"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = 'products_datadablescreen'
root.screen_manager.transition.direction = 'right'
IconLeftWidget:
icon: 'account-cash'
OneLineIconListItem:
text: "Lista de casos de COVID-19"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = 'lista_covid_screen'
root.screen_manager.transition.direction = 'right'
IconLeftWidget:
icon: 'alert'
OneLineIconListItem:
text: "Exportar Cadastros"
on_press:
root.nav_drawer.set_state("close")
root.screen_manager.current = "scr 4"
root.screen_manager.transition.direction = 'right'
IconLeftWidget:
icon: 'database-export'
# Criamos ItemImage com (TwoLineAvatarListItem) para que possamos usar em qualquer lista com qualquer imagen.
<ItemImage>:
AsyncImageLeftWidget:
source: root.source
canvas:
# Criamos CovidImage com (ThreeLineAvatarListItem) para que possamos usar em qualquer lista com qualquer imagen.
<CovidImage>:
AsyncImageLeftWidget:
source: root.source
canvas:
# Transforma Screen em <MainScreen@Screen>:
# Remove TelaLogin: do ScreenManager
<MainScreen>:
MDToolbar:
id: toolbar
pos_hint: {"top": 1}
elevation: 10
title: "Operações Desktop com WShop."
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
MDNavigationLayout:
x: toolbar.height
ScreenManager:
id: screen_manager
# Adiciona somente as screens que irão aparecer com a barra de feramentas
MenuProductsScreen
ProductsDataTableScreen
ProductsScreen
Screen:
name: "scr 4"
MDLabel:
text: "Exportar Cadastros"
halign: "center"
ListScreen
MDNavigationDrawer:
id: nav_drawer
ContentNavigationDrawer:
screen_manager: screen_manager
nav_drawer: nav_drawer
<SenhaCard>:
orientation: "vertical"
#padding: "8dp"
#size_hint: None, None
#size: "380dp", "380dp"
#pos_hint: {"center_x": .5, "center_y": .5}
MDBoxLayout:
size_hint_y: .2
padding: [15, 0, 0, 0]
md_bg_color: app.theme_cls.primary_color
MDLabel:
text: 'Cadastrar Usuário.'
theme_text_color: 'Custom'
text_color: 1, 1, 1, 1
MDIconButton:
theme_text_color: 'Custom'
text_color: 1, 1, 1, 1
icon: 'close'
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: root.fechar()
MDFloatLayout:
MDTextField:
id: 'email'
hint_text: 'E-Mail'
size_hint_x: .9
pos_hint: {'center_x': .5, 'center_y': .8}
MDTextField:
hint_text: 'Senha'
size_hint_x: .9
pos_hint: {'center_x': .5, 'center_y': .5}
MDTextField:
hint_text: 'Confirme a Senha'
size_hint_x: .9
pos_hint: {'center_x': .5, 'center_y': .3}
MDRaisedButton:
text: 'Login'
size_hint_x: .9
pos_hint: {'center_x': .5, 'center_y': .1}
<TelaSingIn@Screen>:
name: 'tela_singin'
id: 'body_tela_singin'
MDIconButton:
icon: "arrow-left-bold"
pos_hint: {"center_x": .1, "center_y": .9}
on_release: app.root.current = 'tela_login'
FloatLayout:
MDIconButton:
icon: "arrow-left-bold"
pos_hint: {"center_x": .1, "center_y": .9}
# Imagem do usuário
FitImage:
pos_hint: {'center_x': .5, 'center_y': .75}
source: "./images/coragem_de_saco_cheio.png"
size_hint: None, None
width: dp(180)
height: dp(180)
radius: [99, 99, 99, 99]
MDTextField:
id: 'text_email'
hint_text: 'E-Mail'
size_hint_x: .6
pos_hint: {'center_x': .5, 'center_y': .5}
MDTextField:
hint_text: 'Senha'
size_hint_x: .6
pos_hint: {'center_x': .5, 'center_y': .4}
MDTextField:
hint_text: 'Confirme a Senha'
size_hint_x: .6
pos_hint: {'center_x': .5, 'center_y': .3}
MDRaisedButton:
text: 'Cadastrar'
size_hint_x: .6
pos_hint: {'center_x': .5, 'center_y': .1}
<TelaLogin>:
name: 'tela_login'
MDBoxLayout:
orientation: "vertical"
#padding: "8dp"
#size_hint: None, None
#size: "380dp", "280dp"
#pos_hint: {"center_x": .5, "center_y": .5}
id: 'body_tela_login'
MDIconButton:
pos_hint: {'center_x': .5, 'center_y': .9}
icon: 'language-python'
user_font_size: '75sp'
MDTextField:
id: email_input
hint_text: 'E-Mail'
size_hint_x: .9
pos_hint: {'center_x': .5, 'center_y': .7}
MDTextField:
id: senha_input
hint_text: 'Senha'
size_hint_x: .9
pos_hint: {'center_x': .5, 'center_y': .6}
MDRaisedButton:
text: 'Login'
size_hint_x: .9
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: root.login()
MDLabel:
pos_hint: {'center_y': .2}
text: 'Não tem usuário ainda?'
halign: 'center'
MDTextButton:
pos_hint: {'center_x': .5, 'center_y': .1}
text: 'clique aqui!'
on_release: root.abrir_card()
# Screen 00 - MODELO, sendo chamada em MDNavigationLayout > ScreenManager (Meus Screens)
# Observe que dentro de MDNavigationLayout > ScreenManager tem o nome da minha classe e um outro
# screen desenhado lá mesmo. Isso me permite desenhar as telas fora do MDNavigationLayout > ScreenManager e
# chamar somente o nome da classe. É possível desenhar dentro de MDNavigationLayout > ScreenManager mas isso
# torna o código confuso.
# Observação: Para cada Screen personalizada você deve ir no arquivo .py e criar sua respectiva classe.
# No caso desse exemplo abaixo criei a classe:
# class ListScreen(Screen):
# Pode ser passado pass para não ter erro na classe.
<ListScreen>:
name: 'lista_covid_screen'
MDBoxLayout:
padding: [0, 110, 0, 0]
#orientation: 'vertical'
ScrollView:
MDList:
id: itens_da_lista
MDFloatingActionButton:
id: float_act_btn
icon: 'reload'
#opposite_colors: True
elevation_normal: 8
pos_hint: {'center_x': 0.9, 'center_y': 0.1}
on_release: root.update_list()
<MenuProductsScreen>:
name: 'menu_products_screen'
MDFloatLayout:
MDRaisedButton:
id: rbt_normalizes_products
text: 'Normaliza Descrição'
size_hint_x: .9
pos_hint: {'center_x': .5, 'center_y': .8}
on_release: root.normaliza_texto()
MDRaisedButton:
id: rbt_remove_char_products
text: 'Remove Caracteres'
size_hint_x: .9
pos_hint: {'center_x': .5, 'center_y': .7}
#disabled: True
on_release: root.normaliza_pontuacao()
MDRaisedButton:
id: rbt_export_products
text: 'Exporta Dados'
size_hint_x: .9
pos_hint: {'center_x': .5, 'center_y': .6}
#disabled: True
on_release: root.salva_produtos_json()
#on_release: root.exporta_produtos_json()
<ProductsScreen>:
name: 'products_screen'
MDBoxLayout:
padding: [0, 64, 0, 0]
#orientation: 'vertical'
ScrollView:
MDList:
id: produtos_da_lista
<ProductsDataTableScreen>:
name: 'products_datadablescreen'
MDBoxLayout:
id: body
# Cria um ScreenManager independente chamando duas screens (TelaLogin, MainScreen)
ScreenManager:
id: sm:
TelaLogin:
name: 'tela_login'
MainScreen:
name: 'main'
TelaSingIn:
name: 'tela_singin'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment