Last active
April 12, 2021 17:19
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'''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