Kivy Popup misbehaviour when called from inside 'on_enter' - python

I am trying to display a Popup in case today is a date on DB.
the problem is the popup pops, but it seems to be built behind the main screen.
I am supposing this is due to be called on "on_enter" method, but couldn't work around this.
Please, note that this "Settings" button is being rendered from the Main screen not from the popup itself.
Here is my main.py:
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen, ScreenManager
from datetime import date, datetime
from calendar import weekday
from kivymd.toast import toast
from kivymd.uix.list import TwoLineIconListItem
from kivymd.uix.picker import MDDatePicker, MDTimePicker
from datahelper import CreateTable, InsertEstudo, DeletStudy, ReadStudy, UpdateStudy
from kivy.factory import Factory
class Gerenciador(ScreenManager):
pass
class Main(Screen):
# def verificar_estudos(self):
def on_enter(self, *args):
ler_dbestudos = ReadStudy()
resultado = ler_dbestudos.ler_estudos()
for s in resultado:
dia = s[2].split("-")[-1]
mes = s[2].split("-")[-2]
ano = s[2].split("-")[0]
print(f"{dia}/{mes}/{ano}")
dia_hoje = date.today().day
mes_hoje = date.today().month
ano_hoje = date.today().year
if int(dia) == dia_hoje:
print('Hoje é dia de revisão de matéria')
tudo = self.children
Factory.DiaDeRevisao().open()
if int(dia) + 14 == dia_hoje:
print('Hoje é dia de revisão de matéria')
Factory.DiaDeRevisao().open()
if int(mes)+1 == mes_hoje:
print('Hoje é dia de revisão de matéria')
Factory.DiaDeRevisao().open()
class Revisao(Screen):
def ver_estudos(self, *args):
read_studies = ReadStudy()
studies = read_studies.ler_estudos()
for s in studies:
self.ids.scrollviewid.add_widget(TwoLineIconListItem(text=s[1], secondary_text=s[2]))
def ver_lista(self, *args):
for r in range(20):
self.ids.scrollviewid.add_widget(TwoLineIconListItem(text='Azul', secondary_text="Texto Secundário"))
class AddStudy(Screen):
def open_calendar(self):
date_dialog = MDDatePicker(callback=self.get_date)
if self.ids.dtinist.focused == True:
date_dialog.open()
def get_date(self, *args):
'''
:type date: <class 'datetime.date'>
'''
print(args[0])
print(type(args[0]))
self.ids.dtinist.focused = False
self.ids.dtinist.text = str(args[0])
self.ids.dtinist.focused = False
return args[0]
def open_clock(self):
time_dialog = MDTimePicker()
time_dialog.bind(time=self.get_time)
if self.ids.tminist.focused == True:
time_dialog.open()
def get_time(self,*args):
self.ids.tminist.focused = False
self.ids.tminist.text = str(args[1])
self.ids.tminist.focused = False
return args[1]
def selected(self, path, selection):
tipo = selection[0].split(".")[-1]
print(tipo)
if tipo == 'mp3':
toast('Arquivo MP3 selecionado')
with open(selection[0], 'rb') as f:
barq = f.read()
insert = InsertEstudo()
insert.criar_novo_estudo()
def confirm_new(self):
materia = self.ids.materia_estudo.text
data_estudo = self.ids.dtinist.text
hora_estudo = self.ids.tminist.text
insert_new_study = InsertEstudo()
if insert_new_study.criar_novo_estudo(materia, data_estudo, hora_estudo):
toast('Estudo adicionado com sucesso')
else:
toast('Algo deu muito errado. O estudo não foi adicionado. Tente novamente mais tarde')
class SettingsScreen(Screen):
def select_path(self, path):
print(path)
'''It will be called when you click on the file name
or the catalog selection button.
:type path: str;
:param path: path to the selected directory or file;
'''
self.exit_manager()
toast(path)
def open_file_manager(self):
self.file_manager.show('/') # output manager to the screen
self.manager_open = True
def exit_manager(self):
self.manager_open = False
self.file_manager.close()
class SelectAlarm(Screen):
def selected(self, path, selection):
tipo = selection[0].split(".")[-1]
print(tipo)
if tipo == 'mp3':
toast('Arquivo MP3 selecionado')
with open(selection[0], 'rb') as f:
barq = f.read()
insert = InsertEstudo()
insert.criar_novo_estudo()
else:
toast('Por favor, seleecione um arquivo mp3')
class BoraEstudarApp(MDApp):
def on_pause(self):
return True
def build(self):
data_hoje = f"{date.today().year}-{date.today().month}-{date.today().day}"
sm = Gerenciador()
sm.add_widget(Main(name='Principal'))
sm.add_widget(SettingsScreen(name='Preferencias'))
sm.add_widget(AddStudy(name='NovaMateria'))
sm.add_widget(Revisao(name='Revisoes'))
sm.add_widget(SelectAlarm(name='SelecionarAlarme'))
return sm
if __name__ == "__main__":
boraestudar = BoraEstudarApp()
boraestudar.run()
and here is my kv file:
#:import Factory kivy.factory.Factory
<ScreenManager>:
<DiaDeRevisao#Popup>:
title: 'Atenção dia de revisão'
auto_dismiss: False
size_hint:0.7,0.7
BoxLayout:
canvas.before:
Color:
rgba:(1,1,1,1)
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
orientation:'vertical'
MDLabel:
text:'Hoje é dia de revisão'
Button:
text: 'OK'
on_press: root.dismiss()
<FileChooserPop#Popup>:
title:'Escolha o arquivo de audio MP3'
BoxLayout:
canvas.before:
Color:
rgba:(0,0,0,0.35)
Rectangle:
size: self.size
pos: self.pos
orientation: 'vertical'
BoxLayout:
size_hint_y: None
height: sp(52)
Button:
text: 'Icon View'
on_press: fc.view_mode = 'icon'
Button:
text: 'List View'
on_press: fc.view_mode = 'list'
FileChooser:
id: fc
FileChooserIconLayout
FileChooserListLayout
BoxLayout:
size_hint_y: None
MDTextButton:
size_hint_x:0.4
text: 'Voltar'
on_press: root.dismiss()
MDIconButton:
halign:'center'
icon:'content-save'
on_press:root.selected(fc.path, fc.selection)
on_release: root.manager.current = 'Principal'
<Main>:
BoxLayout:
orientation:"vertical"
spacing:'50dp'
padding:'70dp'
BoxLayout:
MDTextButton:
text: 'Revisões'
on_press: root.manager.current = 'Revisoes'
# on_release:Factory.FileChooserPop().open()
BoxLayout:
Button:
text: 'Settings'
on_press: root.manager.current = 'Preferencias'
BoxLayout:
MDIconButton:
icon: "plus"
on_press: root.manager.current = 'NovaMateria'
<AddStudy>:
BoxLayout:
orientation:'vertical'
spacing:'100sp'
padding: '100dp'
MDTextField:
id:materia_estudo
hint_text: 'Matéria'
MDTextField:
id: dtinist
text: ''
hint_text: 'data do Estudo'
on_focus: root.open_calendar()
MDTextField:
id:tminist
text:''
hint_text: 'Hora do Estudo'
on_focus: root.open_clock()
BoxLayout:
MDTextButton:
text:'Voltar'
on_press: root.manager.current = 'Principal'
MDTextButton:
text: 'Salvar'
on_press: root.confirm_new()
<SettingsScreen>:
BoxLayout:
MDTextButton:
text: 'Selecionar Alarme'
on_press: root.manager.current = 'SelecionarAlarme'
<SelectAlarm>:
BoxLayout:
canvas.before:
Color:
rgba:(0,0,0,0.35)
Rectangle:
size: self.size
pos: self.pos
orientation: 'vertical'
BoxLayout:
size_hint_y: None
height: sp(52)
Button:
text: 'Icon View'
on_press: fc.view_mode = 'icon'
Button:
text: 'List View'
on_press: fc.view_mode = 'list'
FileChooser:
id: fc
FileChooserIconLayout
FileChooserListLayout
BoxLayout:
size_hint_y: None
MDTextButton:
size_hint_x:0.4
text: 'Voltar'
on_press: root.manager.current = 'Principal'
MDIconButton:
halign:'center'
icon:'content-save'
on_press:root.selected(fc.path, fc.selection)
on_release: root.manager.current = 'Principal'
<Revisao>:
BoxLayout:
orientation:'vertical'
BoxLayout:
ScrollView:
do_scroll_y: True
size_hint_y: None
height: '500dp'
MDList:
id:scrollviewid
BoxLayout:
size_hint_y: 0.15
MDTextButton:
size_hint_x: None
text:"Voltar"
on_release: root.manager.current = 'Principal'
MDTextButton:
text:"Ver Lista"
on_release: root.ver_estudos()
This is odd and I couldn't figure this out.
I appreciate any help. Cheers!

The problem is that the on_enter() event is triggered too early, so it the Popup gets drawn before the Main Screen. You can fix that by adding a very short delay before displaying the Popup. I changing the:
Factory.DiaDeRevisao().open()
to:
Clock.schedule_once(lambda dt: Factory.DiaDeRevisao().open())
will provide that delay and allow the Popup to display on top of the Screen.

Related

Kivy Incorporating Video to Navigation Drawer

I have been trying off and on for two weeks to figure this out with no luck. This is the first time in my coding learning journey i've felt actually completely stuck. Any help is incredibly appreciated.
Right now my issue is changing screens outside of my .kv file. Right now I am trying to use:
class RootScreen(Screen):
def onNextScreen(self, btn, fileName):
MDApp.get_running_app().root.current = "ScreenVideo1"
MDApp.get_running_app().root.ScreenVideo1.test_on_enter(r'C:\file\location' + fileName + '.MOV')
But that gives the error code:
'RootScreen' object has no attribute 'ScreenVideo1'
main.py
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivymd.theming import ThemableBehavior
from kivymd.uix.list import MDList
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.properties import ObjectProperty
from kivy.uix.videoplayer import VideoPlayer
from kivy.uix.actionbar import ActionBar
from kivy.uix.button import Button
from kivy.core.window import Window
#remove after dev
Window.size = (300,500)
Window.clearcolor = (.976, .980, .996, 1)
screen_helper = r"""
RootScreen:
MDNavigationLayout:
ScreenManager:
id: screen_manager
ScreenHome:
id: screen_home
manager: screen_manager
name: "Home"
ScrollView:
pos_hint: {'bottom':1}
do_scroll_y: True
BoxLayout:
orientation: 'vertical'
padding: 15
spacing: 20
#size_hint: None, None
height: self.minimum_height
size_hint: (1, 2)
MDToolbar:
title: "POTUS"
left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
elevation: 8
Widget:
StrokeButton:
text: "Video Category 1"
back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
on_release: screen_manager.current = "Video1"
ScreenAbout:
id: screen_about
manager: screen_manager
name: "About"
MDLabel:
text: "About"
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "POTUS"
left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
elevation: 8
Widget:
ScreenHelp:
id: screen_help
manager: screen_manager
name: "Help"
MDLabel:
text: "Help"
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "POTUS"
left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
elevation: 8
Widget:
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "POTUS"
left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
elevation: 8
Widget:
ScreenVideo1:
id: screen_video1
manager: screen_manager
name: "Video1"
GridLayout:
pos_hint: {'top': 1}
cols:1
rows:5
ActionBar:
pos_hint: {'top': 1}
height:'100sp'
ActionView:
ActionPrevious:
with_previous: True
on_release: screen_manager.current = "Home"
StrokeButton:
text: " Video option 1"
back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
on_release: root.onNextScreen(self, 'heart')
StrokeButton:
text: "Video option 2"
back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
on_release:
StrokeButton:
text: "Video option 3"
back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
on_release:
MDNavigationDrawer:
id: nav_drawer
BoxLayout:
orientation: 'vertical'
spacing: '8dp'
padding: '8dp'
MDLabel:
text: "blah blah blah"
font_style: 'Subtitle1'
size_hint_y: None
height: self.texture_size[1]
MDLabel:
text: "blah blah blah"
font_style: "Caption"
size_hint_y: None
height: self.texture_size[1]
ScrollView:
MDList:
OneLineIconListItem:
on_release:
screen_manager.current = "Home"
text: 'Home'
IconLeftWidget:
icon:"folder-home"
on_release:
screen_manager.current = "Home"
OneLineIconListItem:
on_release:
screen_manager.current = "Help"
text: 'Help'
IconLeftWidget:
icon:"help-circle-outline"
on_release:
screen_manager.current = "Help"
OneLineIconListItem:
on_release:
screen_manager.current = "About"
text: 'About'
IconLeftWidget:
icon: "doctor"
on_release:
screen_manager.current = "About"
<StrokeButton#Button>:
background_color:(0,0,0,0)
background_normal:''
back_color:(1,0,1,1)
border_radius: 18
color: self.back_color
bold: True
canvas.before:
Color:
rgba: self.back_color
Line:
rounded_rectangle: (self.pos[0],self.pos[1],self.size[0],self.size[1],self.border_radius)
width: 1.2
"""
class RootScreen(Screen):
def onNextScreen(self, btn, fileName):
MDApp.get_running_app().root.current = "ScreenVideo1"
MDApp.get_running_app().root.ScreenVideo1.test_on_enter(r'C:\file\location' + fileName + '.MOV')
class ScreenHome(Screen):
pass
class ScreenAbout(Screen):
pass
class ScreenHelp(Screen):
pass
class ScreenVideo1(Screen):
def test_on_enter(self, vidname):
#self.add_widget(Button(text="Back"))
self.vid = VideoPlayer(source=vidname, state='play',
options={'allow_stretch':True,
'eos': 'loop'})
self.add_widget(self.vid)
def on_leave(self):
pass
def onBackBtn(self):
self.vid.state = 'stop'
self.remove_widget(self.vid)
MDApp.get_running_app().root.current = "ScreenVideo1"
class DemoApp(MDApp):
def build(self):
screen = Builder.load_string(screen_helper)
return screen
DemoApp().run()
It used to be very easy when I was building my app with Manager
class Manager(ScreenManager):
transition = NoTransition()
screen_one = ObjectProperty(None)
screen_two = ObjectProperty(None)
screen_home = ObjectProperty(None)
def __init__(self, *args, **kwargs):
super(Manager, self).__init__(*args, **kwargs)
# list to keep track of screens we were in
self.list_of_prev_screens = []
class ScreensApp(MDApp):
def build(self):
return Manager()
if __name__ == "__main__":
ScreensApp().run()
And then I would just change screens using manager. But now that I am using the navigation drawer I can no longer build my app with manager.
class ScreenOne(Screen):
def onNextScreen(self, btn, fileName):
self.manager.list_of_prev_screens.append(btn.parent.name)
self.manager.current = 'screen2'
self.manager.screen_two.test_on_enter(r'C:\file\location' + fileName + '.MOV')
Your code:
class RootScreen(Screen):
def onNextScreen(self, btn, fileName):
MDApp.get_running_app().root.current = "ScreenVideo1"
MDApp.get_running_app().root.ScreenVideo1.test_on_enter(r'C:\file\location' + fileName + '.MOV')
is trying to treat the root widget of the App as a ScreenManager, but it isn't, it is a RootScreen. So, you need to access the ScreenManager, like this:
class RootScreen(Screen):
def onNextScreen(self, btn, fileName):
MDApp.get_running_app().root.ids.screen_manager.current = "Video1"
MDApp.get_running_app().root.ids.screen_manager.current_screen.test_on_enter(r'C:\file\location' + fileName + '.MOV')

how to redirect from one page two other page with an if statement

I want this program to read information from the database and if it was correct, go to the main page of the program
Otherwise say that the information is wrong
how to redirect from one page two other page with an if statement
if user input and password was True by pressing button go to home
otherwise print password or user wrong
It is supposed to read data from the database
.py
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.lang import Builder
from kivy import Config
Builder.load_file("kivy.kv")
class AddUser(Screen):
def changeScreen(self):
self.ids.Gotologin.on_press = self.manager.transition.direction = 'up'
def getUserInfo(self):
name = self.ids.addusername.text
paswd = self.ids.addpassword.text
phone = self.ids.addphone.text
gmail = self.ids.addgmial.text
if len(paswd) == 0 and len(name) == 0:
self.ids.passwordles.text = "Enter your name & Password !"
elif len(paswd) <= 0:
self.ids.passwordles.text = "Add a Pssword !"
elif len(paswd) <= 6:
self.ids.passwordles.text = "Password is too small"
elif len(name) <= 0:
self.ids.passwordles.text = "Enter your Name !"
class Home(Screen):
def add(self):
name = self.ids.Name.text
number = self.ids.Number.text
ID = self.ids.Id.text
Buy = self.ids.Buy.text
sale = self.ids.Sale.text
ex_date = self.ids.exdate.text
usage = self.ids.Usage.text
medicine = self.ids.Medicine.text
Category = self.ids.Catigory.text
class LogIn(Screen):
def get(self):
cr.execute("SELECT * FROM login")
log = cr.fetchall()
user = self.ids.username.text
paswd = self.ids.password.text
Screen_Manager = ScreenManager()
Screen_Manager.add_widget(AddUser(name="Adduser"))
Screen_Manager.add_widget(LogIn(name="Login"))
Screen_Manager.add_widget(Home(name="Home"))
# main class to run application
class MainApp(App):
def build(self):
return Screen_Manager
if __name__ == "__main__":
MainApp().run()
.kv
<AddUser>:
BoxLayout:
canvas.before:
Color:
rgba:0,0,1,1
Rectangle:
size:self.size
pos:self.pos
orientation:"vertical"
BoxLayout:
Label:
id:passwordles
text:""
BoxLayout:
orientation:'vertical'
BoxLayout:
Label:
size_hint_x:.22
text:""
Label:
text:"User Name *"
Label:
text:"Password *"
Label:
text:"Phone Number"
Label:
text:"Gmail"
Label:
size_hint_x:.22
BoxLayout:
Label:
size_hint_x:.22
text:""
TextInput:
id:addusername
size_hint_y:.5
hint_text:"User Name"
TextInput:
id:addpassword
size_hint_y:.5
password:True
hint_text:"Password"
TextInput:
id:addphone
size_hint_y:.5
hint_text:"Phone Number"
TextInput:
id:addgmial
size_hint_y:.5
hint_text:"Gmail"
Label:
size_hint_x:.22
BoxLayout:
Label:
text:""
Button:
id:Gotologin
radius: 100, 100, 100, 100
font_name:"fonts/MTCORSVA.TTF"
color:1,1,0,1
outline:0,0,0,1
outline_width:4
font_size:32
bolde:True
size_hint_y:.8
text:"Login"
on_press:
root.getUserInfo()
root.manager.transition.direction = 'up'
root.manager.transition.duration = .9
root.manager.current = 'Login'
Label:
text:""
BoxLayout:
Label:
text:""
<LogIn>:
BoxLayout:
orientation:'vertical'
canvas.before:
Color:
rgba:0,0,1,1
Rectangle:
size:self.size
pos:self.pos
BoxLayout:
Label:
text:""
BoxLayout:
orientation:'horizontal'
BoxLayout:
size_hint_x:.4
Label:
text:""
BoxLayout:
orientation:"vertical"
TextInput:
id:username
size_hint_y:.3
hint_text:"User Name"
TextInput:
id:password
size_hint_y:.3
hint_text:"Password"
BoxLayout:
orientation:"horizontal"
Label:
size_hint_x:.3
text:""
Button:
id:LoginFromButton
on_press:
root.manager.transition.direction='left'
root.manager.transition.duration = .9
root.manager.current = 'Home'
text:'Login'
font_name:"fonts/MTCORSVA.TTF"
color:1,1,0,1
outline:0,0,0,1
outline_width:4
font_size:32
bolde:True
size_hint_y:.5
Label:
size_hint_x:.3
text:""
BoxLayout:
size_hint_x:.4
Label:
text:""
BoxLayout:
Label:
text:""
<Home>:
Button:
text:"Home"
In your kv, set the on_press to a method, like this:
Button:
id:LoginFromButton
on_press:
root.do_login()
Then, in the LogIn screen class:
def check_login(self):
# do your check for legal login and return True or False
return True
def do_login(self):
if self.check_login():
self.manager.current = 'Home'

MDExpansion Panel - kivy.properties.DictProperty' object has no attribute 'panel_container'

I am currently building a mobile app with kivy. In one of my screens I am trying to include an MDExpansionPanel, although I have tried with a lot of different codes, and searched on the web for solutions, either I get an error, or simply the Expansion Panel is not rendered in my screen. I am using ScreenManager since I have 5 screens, with the possibility of increasing such number.
The relevant Python code is the following:
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.app import MDApp
from kivymd.theming import ThemeManager
from kivymd.toast import toast
from kivymd.uix.picker import MDDatePicker, MDTimePicker
from kivymd.uix.expansionpanel import MDExpansionPanel
from kivymd.uix.boxlayout import MDBoxLayout
class LoginWindow(Screen):
pass
class CreateAccountWindow(Screen):
pass
class MainWindow(Screen):
pass
class TravelManagerWindow(Screen):
pass
class IngActivWindow(Screen):
panel_container = ObjectProperty(None)
def on_pre_enter(self, *args):
self.add_panels()
def show_timepicker(self):
picker = MDTimePicker()
picker.bind(time=self.got_time)
picker.open()
def got_time(self, picker_widget, time):
self.text = str(time.hour) + ":" + str(time.minute)
self.focus = False
# selectedTime= self.text
print(self.text)
self.ids.tiempoActiv.text = self.text
def add_panels(self):
for i in range(5):
IngActivWindow.ids.panel_container.add_widget(
MDExpansionPanel(
icon="actividades.png",
content=MyContent(),
panel_cls=MDExpansionPanelOneLine(
text="Text",
)
)
)
class MyContent(MDBoxLayout):
pass
class WindowManager(ScreenManager):
ScreenManager().add_widget(LoginWindow(name='login'))
ScreenManager().add_widget(CreateAccountWindow(name='create'))
ScreenManager().add_widget(MainWindow(name='main'))
ScreenManager().add_widget(IngActivWindow(name='ingActiv'))
ScreenManager().add_widget(TravelManagerWindow(name='travelManager'))
class powerApp1(MDApp):
def build(self):
self.theme_cls.primary_palette = "Teal"
return WindowManager()
if __name__ == "__main__":
powerApp1().run()
The relevant kv code is the following:
(I have an image on the background and an Action Bar before the MDBoxLayout where I am trying to add the Expansion Panel)
<WindowManager>:
LoginWindow:
CreateAccountWindow:
MainWindow:
IngActivWindow:
TravelManagerWindow:
<IngActivWindow>:
name: 'ingActiv'
panel_container: panel_container
FloatLayout:
cols:1
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'ingActiv_background.png'
ActionBar:
pos_hint: {'top':1}
ActionView:
use_separator: True
ActionPrevious:
title: '---------'
with_previous: False
ActionButton:
icon: 'homeIcon.png'
on_press:
root.manager.current = 'main'
root.manager.transition.direction = 'right'
ActionGroup:
text: 'Gastos de Viaje'
mode: 'spinner'
size_hint:(None,None)
size: root.width/5,root.height/12
ActionButton:
text: 'Solicitar'
on_release:
root.manager.current = 'solicitud'
root.manager.transition.direction = 'left'
ActionButton:
text: 'Comprobar'
on_release:
root.manager.current = 'comprobar'
root.manager.transition.direction = 'left'
ActionGroup:
text: 'Opciones'
mode: 'spinner'
size_hint:(None,None)
size: root.width/5,root.height/12
ActionButton:
text: 'Ingresar Actividad'
on_release:
root.manager.current = 'ingActiv'
root.manager.transition.direction = 'left'
ActionButton:
text: 'Enviar Reporte'
ActionButton:
text: 'Cerrar Sesion'
on_release:
root.manager.current = 'login'
root.manager.transition.direction = 'down'
MDBoxLayout:
cols:1
size_hint: 1,0.6
pos_hint: {"center_x": 0.5, "center_y": 0.5}
ScrollView:
GridLayout:
id: panel_container
cols: 1
pos_hint: {"center_x": 0.5, "center_y": 0.5}
<MyContent>:
size_hint: 1, None
height: self.minimum_height
orientation: 'horizontal'
Button:
size_hint: None, None
Thanks a lot in advance for your support,
Have a great day.

How to get value from popup filechooser?

I got a popup filechooser from the below link:
Kivy popup Filechooser pass variable (selection)
I cannot get the file path string value to pass between my main Tab() class instance of the app and the class FileChoosePopup popup instance. I know this question has been asked before, but I cannot seem to figure it out. When I run the app and click on the file I want to pass to a TextInput on my main class I get the following error:
AttributeError: 'super' object has no attribute '__getattr__'
I have tried passing a reference to the popup class instance in the main class by using the super init method, but then the app does not even initialize.
Here is my popup in python:
class FileChoosePopup(Popup):
file_path = StringProperty("No file chosen")
def __init__(self, **kwargs):
super(FileChoosePopup, self).__init__(**kwargs)
self.Tab = Tab()
def load(self, selection):
self.file_path = str(selection[0])
path_file = self.file_path
the_file = self.ids.get_file #is the textinput id
if path_file != "No file chosen":
the_file.text = path_file
self.dismiss()
else:
self.dismiss()
class Tab(StackLayout):
def open_popup(self):
the_popup = FileChoosePopup()
the_popup.open()
Here the kivy code:
<FileChoosePopup>:
title: "Choose a .CSV File"
size_hint: .9, .9
auto_dismiss: False
BoxLayout:
orientation: "vertical"
FileChooser:
id: filechooser
FileChooserIconLayout
BoxLayout:
size_hint: (1, 0.1)
pos_hint: {'center_x': .5, 'center_y': .5}
spacing: 20
RoundedCancelButton:
text: "Cancel"
on_release: root.dismiss()
RoundedAcceptButton:
text: "Load"
on_release: root.load(filechooser.selection)
id: ldbtn
disabled: True if filechooser.selection==[] else False
<Tab>:
TabbedPanel:
do_defualt_tab: False
background_color: (.87, .87, .87, 1)
border: [0, 0, 0, 0]
background_image: 'path/to/background/image'
TabbedPanelItem:
text: 'Import'
background_color: (1, .5, 0, 1)
background_normal: ''
StackLayout:
orientation: 'lr-tb'
size_hint_y: None
height: 30
spacing: 5
Label:
text: ''
size_hint_x: 1
Label:
text: ''
size_hint_x: 0.2
RoundedButton:
text: 'Choose File'
size_hint_x: 0.2
on_press: root.open_popup()
TextInput:
id: get_file
readonly: True
size_hint_x: 0.4
Label:
text: ''
size_hint_x: 0.2
Can someone please give me some pointers on how to get the value to pass from the popup to the textinput?
Reference TextInput
Populate TextInput by using the following:
self.ids.get_file.text = self.file_path
Example
main.py
from kivy.app import App
from kivy.uix.popup import Popup
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.properties import ObjectProperty, StringProperty
from kivy.lang import Builder
class FileChoosePopup(Popup):
load = ObjectProperty()
class Tab(TabbedPanel):
file_path = StringProperty("No file chosen")
the_popup = ObjectProperty(None)
def open_popup(self):
self.the_popup = FileChoosePopup(load=self.load)
self.the_popup.open()
def load(self, selection):
self.file_path = str(selection[0])
self.the_popup.dismiss()
print(self.file_path)
# check for non-empty list i.e. file selected
if self.file_path:
self.ids.get_file.text = self.file_path
Builder.load_file('main.kv')
class TestApp(App):
def build(self):
return Tab()
if __name__ == "__main__":
TestApp().run()
main.kv
<FileChoosePopup>:
title: "Choose a .CSV File"
size_hint: .9, .9
auto_dismiss: False
BoxLayout:
orientation: "vertical"
FileChooser:
id: filechooser
FileChooserIconLayout
BoxLayout:
size_hint: (1, 0.1)
pos_hint: {'center_x': .5, 'center_y': .5}
spacing: 20
Button:
text: "Cancel"
on_release: root.dismiss()
Button:
text: "Load"
on_release: root.load(filechooser.selection)
id: ldbtn
disabled: True if filechooser.selection==[] else False
<Tab>:
do_default_tab: False
TabbedPanelItem:
text: 'Import'
background_color: (1, .5, 0, 1)
background_normal: ''
StackLayout:
orientation: 'lr-tb'
size_hint_y: None
height: 30
spacing: 5
Label:
text: ''
size_hint_x: 1
Label:
text: ''
size_hint_x: 0.2
Button:
text: 'Choose File'
size_hint_x: 0.2
on_press: root.open_popup()
TextInput:
id: get_file
readonly: True
size_hint_x: 0.4
Label:
text: ''
size_hint_x: 0.2
Output

How to make an input dialog box in kivy?

I have made an input dialog box in kivy. But I'm not sure if this is a correct format or correct code or correct way to code. I tried to display an error message itself in the popup below the button. It works while the input is empty, after input, also it's showing the error.
Can anyone help me to do it in a correct way?
Builder.load_string("""
<Main>:
Button:
text: 'Click'
on_press: root.callit()
<design>:
orientation: 'vertical'
cols:2
pos: self.pos
size: root.size
Label:
text: 'Enter Value'
TextInput:
id: val
multiline: False
hint_text:'Age'
input_filter: 'int'
Button:
text: 'Enter'
background_color: 255,0,0,0.9
on_press: root.enter()
Button:
text: 'Cancel'
background_color: 0,1,255,0.7
on_press: root.cancel()
#Label:
# id: er
# foreground_color: [1,250,100,1]
# text: 'Error'
""")
class design(GridLayout):
def __init__(self,**kwargs):
super(design,self).__init__(**kwargs)
#cancel=ObjectProperty(None)
self.er=Label(text='Please enter some input!')
def enter(self):
if self.ids.val.text=='':
print "Enter text"
#self.add_widget(self.er)#Label(text='Please enter some input!',width=200))
#time.sleep(10000)
#self.remove_widget(self.er)
#self.ids.er.text='Please enter some input!'
#self.ids.val.hint_text='Please enter input!'
else:
print self.ids.val.text
#self.ids.val.hint_text='Please enter input!'
self.ids.val.text=''
self.cancel()
def cancel(self):
obj=OpenDialog()
obj.call_pops(1)
class Main(BoxLayout):
pass
def callit(self):
obj=OpenDialog()
obj.call_pops(0)
class OpenDialog(Popup):
global popup
cont=design()
popup=Popup(title='InputDialog',content=cont,size_hint=(None, None), size=(400, 150),auto_dismiss=False)
def call_pops(self,val):
if val==1:
self.close_pops()
elif val==0:
popup.open()
def close_pops(self):
popup.dismiss()
class SriPop(App):
def build(self):
return Main()
if __name__ == '__main__':
SriPop().run()
You need to use the on_text event so that when a number is entered the label stops showing the error. For example:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.properties import NumericProperty, StringProperty, ObjectProperty
from kivy.lang import Builder
Builder.load_string("""
<Main>:
BoxLayout:
orientation: "vertical"
Button:
text: 'Click'
on_press: root.callit()
Label:
id: age_lab
size_hint_y: 0.1
text: root.str_age
<OpenDialog>:
title: 'InputDialog'
size_hint: None, None
size: 400, 120
auto_dismiss: False
text: input.text
lb_error: er
BoxLayout:
orientation: 'vertical'
pos: self.pos
size: root.size
BoxLayout:
orientation: 'horizontal'
Label:
text: 'Enter Value'
TextInput:
id: input
multiline: False
hint_text:'Age'
input_filter: 'int'
on_text: root.error = ''
BoxLayout:
orientation: 'horizontal'
Button:
text: 'Enter'
background_color: 255,0,0,0.9
on_press: root._enter()
Button:
text: 'Cancel'
background_color: 0,1,255,0.7
on_press: root._cancel()
Label:
id: er
foreground_color: 1, 250, 100, 1
color: 1, 0.67, 0, 1
size_hint_y: None
height: 0
text: root.error
""")
class Main(BoxLayout):
age = NumericProperty()
str_age = StringProperty("None")
def callit(self):
obj = OpenDialog(self)
obj.open()
def on_age(self, *args):
self.str_age = "Age: {}".format(self.age)
class OpenDialog(Popup):
_age = NumericProperty()
error = StringProperty()
def __init__(self, parent, *args):
super(OpenDialog, self).__init__(*args)
self.parent = parent
self.bind(_age=self.parent.setter('age'))
def on_error(self, inst, text):
if text:
self.lb_error.size_hint_y = 1
self.size = (400, 150)
else:
self.lb_error.size_hint_y = None
self.lb_error.height = 0
self.size = (400, 120)
def _enter(self):
if not self.text:
self.error = "Error: enter age"
else:
self._age = int(self.text)
self.dismiss()
def _cancel(self):
self.dismiss()
class SriPop(App):
def build(self):
return Main()
if __name__ == '__main__':
SriPop().run()

Categories

Resources