Why popup dismiss method causes an error? (python kivymd) - python

I'm trying to make a app. On button click on the bottom right of the screen there appears a dialog window(popup). On "Done" click the popup window is expected to close (close_dialog method), but for some reason there appears AttributeError:
AttributeError: 'grudget4App' object has no attribute 'close_dialog'
Could you please tell me why the code doesn't work and how to fix it. Thanks.
.py code:
from kivy.lang import Builder
from kivy.core.window import Window
from kivymd.app import MDApp
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.scrollview import ScrollView
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog
from kivymd.uix.textfield import MDTextField
from kivy.uix.textinput import TextInput
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.uix.list import TwoLineAvatarListItem
Window.size = (288, 511)
class DialogContent(BoxLayout):
pass
class Container(Screen):
dialog = None
def show_dialog(self, *args):
'''
Create group creation popup
'''
if not self.dialog:
self.dialog = MDDialog(
title="Create new group",
type="custom",
content_cls=DialogContent(),
auto_dismiss=False
)
self.dialog.open()
def close_dialog(self, *args):
'''
Close popup on Done click
'''
self.dialog.dismiss()
class grudget4App(MDApp):
def build(self):
container = Container()
return container
if __name__ == '__main__':
grudget4App().run()
.kv code:
<DialogContent>:
textfield: textfield
orientation: "vertical"
spacing: "12dp"
size_hint_y: None
height: "120dp"
MDTextField:
id: textfield
hint_text: "Group name"
MDFlatButton:
id: btn1
text: "Done"
text_color: self.theme_cls.primary_color
on_release: app.close_dialog()
<Container>:
MDFloatingActionButton:
pos_hint: {'right': 0.95, 'y': 0.05}
icon: "icon.png"
theme_text_color: "Custom"
text_color: app.theme_cls.primary_color
on_release:
root.show_dialog()
Screen:
NavigationLayout:
ScreenManager:
Screen:
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: 'Demo Application'
left_action_items: [["menu", lambda x: nav_drawer.toggle_nav_drawer()]]
elevation:10
Widget:
MDNavigationDrawer:
id: nav_drawer

The method on_release: app.close_dialog() refers to your grudget4App class, but you want to call the method inside your Container class.
So we need to get the right screen inside your app. Since Container is the only screen there, and also the root, you can use:
on_release: app.root.close_dialog()

Related

Kivymd call a page by function to open after click on the button

I hope you are doing well.
I would like to ask a question about how to call a page in kivy from a function and I m using screen_manager.
I want this function to open the next page
if(clickedStart):
screen_manager.add_widget(Builder.load_file("splashloading.kv"))
screen_manager.current = "splashloading.kv"
Clock.schedule_once(self.Login,6)
but it doesn't open why and how i can pass to splashloading page and after 5s of splashloading page must go to main page which is commented in the code right now.
this my main python code
from kivy.uix.screenmanager import ScreenManager,Screen, WipeTransition, FadeTransition, NoTransition
from kivymd.app import MDApp
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.clock import Clock
from kivy.core.text import LabelBase
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
Window.size =(350, 580)
clickedStart = False
class StartPage(MDApp):
def build(self):
LabelBase.register(name='Lemonada',fn_regular='fonts/Lemonada-VariableFont_wght.ttf')
global screen_manager
screen_manager = ScreenManager()
screen_manager.add_widget(Builder.load_file("firstUse.kv"))
print(screen_manager)
#screen_manager.add_widget(Builder.load_file("main.kv"))
#screen_manager.add_widget(Builder.load_file("result.kv"))
return screen_manager
print(clickedStart)
def getStarted(self, instance):
clickedStart = True
print(clickedStart)
print(clickedStart)
def on_start(self):
if(clickedStart):
screen_manager.add_widget(Builder.load_file("splashloading.kv"))
screen_manager.current = "splashloading.kv"
Clock.schedule_once(self.Login,6)
def Login(self, *args):
screen_manager.current = "main page"
if __name__ == "__main__":
StartPage().run()
then the firstpage.kv code
MDScreen:
name:"oneFirst"
MDFloatLayout:
md_bg_color: (255/255, 250/255, 245/255, 1)
Image:
source:"assets/1.png"
size_hint:.50,.50
pos_hint:{"center_x":.5,"center_y":.8}
MDLabel:
text:"the Vine Reco App"
pos_hint:{"center_x":.5,"center_y":.63}
halign:"center"
theme_text_color:"Custom"
text_color: (106/255, 90/255, 200/255, 1)
font_size:"28sp"
font_name:"Lemonada"
MDLabel:
text:"Recognizing the Type of the vine based on the image of list leaves"
pos_hint:{"center_x":.5,"center_y":.4}
halign:"center"
theme_text_color:"Custom"
text_color: (5/255, 215/255, 80/255, 1)
font_size:"22sp"
padding:[40,0]
MDRaisedButton:
id: startdBtn
text:"Get Started"
font_name: 'Fonts/Poppins-Regular.ttf'
font_size:35
markup: True
pos_hint:{"center_x":.5,"center_y":.12}
md_bg_color:(140/255, 220/255, 150/255, 1)
text_color: (22/255, 160/255, 133/255, 1)
on_press:app.getStarted(self)
MDLabel:
text:"2022 ELTE-IK (NWYUK6)| All Rights Reserved ©"
pos_hint:{"center_x":.5,"center_y": .03}
halign:"center"
theme_text_color:"Custom"
text_color: (51/255, 140/255, 180/255, 1)
font_size:"13sp"
the page i want to open after click on Button is that one
splashloading.kv
MDScreen:
name:"laodingFirst"
MDFloatLayout:
md_bg_color: (1,1,1,1)
Image:
source:"assets/start.gif"
size_hint:1,1
pos_hint:{"center_x":.5,"center_y":.5}

kivy positioning all items in a single box

I am writing a program that requires a label, a text_input, and a checkbox to be aligned on screen in that order. They should span the width of the screen and be at the same y level.
I have written this code in my .kv file which uses identical pos_hint values, but only the text_input box moves
Below is my .kv code:
<Union>:
BoxLayout:
orientation: "vertical"
BoxLayout:
orientation: "horizontal"
pos_hint_y: {"top":.85}
Label:
text: 'Session Length'
pos_hint: {"x":.3, "top":.85}
TextInput:
id: input
text: "test"
pos_hint: {"x":.5, "top":.85}
size_hint: 0.3, 0.05
background_disabled_normal: ""
disabled: not checkbox.active
on_text: app.return_text()
CheckBox:
id: checkbox
pos_hint: {"x":.7, "top":.85}
and here is my main.py
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.dropdown import DropDown
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import Screen, ScreenManager
Window.size = (309, 555)
class MenuScreen(Screen):
pass
class SetupScreen(Screen):
pass
class drop_content(DropDown):
pass
class UnionScreen(Screen):
class Checkbox_Setup(FloatLayout):
pass
class TheApp(App):
def build(self):
# Create the screen manager
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(SetupScreen(name='setup'))
sm.add_widget(UnionScreen(name='union'))
return sm
def return_text(self):
text = self.root.get_screen('union').ids.input.text
print(text)
def main():
Builder.load_file('menu.kv')
app = TheApp()
app.run()
if __name__ == '__main__':
main()
Finally, here is the output I am currently getting, with the label and checkbox in line but underneath the text_input which is in the right place.
I am relatively new to kivy so any help would be greatly appreciated. Thanks in advance!

Accessing function in other kivy sceens

I am trying to figure out how to ensure my the calculations function is available as a global function able to be used no matter where in the app it is called.
Currently I am getting:
AttributeError: 'InputScreen' object has no attribute 'calculations'
main.py
import math
import kivy
from kivy.app import App
from decimal import Decimal, ROUND_UP
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.textinput import TextInput
class ScreenSwitch(ScreenManager):
pass
class DisplayScreen(Screen):
pass
class InputScreen(Screen):
pass
class Calculations():
def calculations(self):
org_amount = self.ids.orgamount.text
org_1 = int(self.ids.orgtip.text)
total = org_amount * org_1
class testApp(App):
def build(self):
self.title= "test1 v:1"
testApp().run()
test.kv
ScreenSwitch:
DisplayScreen:
InputScreen:
<DisplayScreen>:
name: "display"
GridLayout:
rows:1
cols:1
Button:
id: Displaymanualentry
text: "Manual Entry"
on_release: app.root.current = "input"
<InputScreen>:
name: "input"
GridLayout:
rows: 1
cols: 2
Button:
id: Inputreset
text: "Reset"
on_release: app.root.current= "display"
Button:
id: Inputsubmit
text: "Submit"
on_press: root.calculations()
on_release: app.root.current = "display"

cannot remove widget in Kivy

i cannot remove widget using the screen with kivy python, i dont know why it just does not do anything
the code was suppose to remove textinput with id:name on the first screen but it just does not do anything and no error message.
here is all of the code it is tested on python 3.7.4, kivy 1.11.1 on window.
module_media_player.py
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.core.audio import SoundLoader
from kivy.uix.videoplayer import VideoPlayer
from kivy.uix.screenmanager import ScreenManager,Screen
class Player(Screen):
def press(self):
self.ids.name.text = 'nice'
def remove(self):
self.remove_widget(self.ids.name)
class MediaPlayer(Screen):
pass
class WindowManager(ScreenManager):
pass
kv = Builder.load_file('my.kv')
class GoodApp(App):
def build(self):
return kv
if __name__ == '__main__':
GoodApp().run()
my.kv
WindowManager:
Player:
MediaPlayer:
<Player>:
name:"player"
BoxLayout:
orientation:"vertical"
size:root.width,root.height
cols:2
TextInput:
id:name
multiline:False
text:"first"
font_size:12
size_hint_y:0.3
Button:
text:"click me"
on_press:root.remove()
Button:
text:"next window"
font_size:14
size_hint_y:0.7
on_release:
app.root.current = "mediaplayer"
root.manager.transition.direction = "left"
<MediaPlayer>:
name:"mediaplayer"
BoxLayout:
orientation:"vertical"
size:root.width,root.height
Label:
text:"second"
font_size:12
Button:
text:"previous window"
font_size:14
on_release:
app.root.current = "player"
root.manager.transition.direction = "right"
Your code:
def remove(self):
self.remove_widget(self.ids.name)
is trying to remove the TextInput from the Player Screen, but that Textinput is not a child of Player. It is actually a child of the BoxLayout. You can fix this by modifying your remove() method:
def remove(self):
textinput = self.ids.name
textinput.parent.remove_widget(textinput) # remove widget from its parent

How to create a new button by pressing a button in popup (python kivy)

I'm trying to make a app. On button click on the bottom right of the screen there appears a dialog window(popup). I want to create a new button at the main screen on "Done" click.
I believed that the button would appear as on "Done" click "close_dialog" method is called, and this method calls "new_window" method afterwards. Could you please tell me why the code doesn't work and how to fix it. Thanks.
Code .py:
from kivy.lang import Builder
from kivy.core.window import Window
from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivymd.uix.label import MDLabel
from kivy.uix.gridlayout import GridLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.scrollview import ScrollView
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog
from kivymd.uix.textfield import MDTextField
Window.size = (240, 426)
class ContentNavigationDrawer(BoxLayout):
pass
class Content(BoxLayout):
pass
class Container(BoxLayout):
dialog = None
button_amount = 1
def show_dialog(self):
if not self.dialog:
self.dialog = MDDialog(
title="Create new group",
type="custom",
content_cls=Content(),
)
self.dialog.open()
def close_dialog(self, *args):
self.dialog.dismiss()
self.new_window()
def new_window(self, *args):
self.add_widget(
MDFlatButton(text="New group", size_hint_y=None, height=100))
class testApp(MDApp, Container):
def build(self):
return Container()
if __name__ == '__main__':
testApp().run()
Code .kv:
<Content>
orientation: "vertical"
spacing: "12dp"
size_hint_y: None
height: "120dp"
MDCheckbox:
hint_text: "Online"
size_hint: (None, None)
active: True
pos_hint: {'center_x': .5, 'center_y': .4}
MDTextField:
hint_text: "Group name"
MDFlatButton:
id: btn1
text: "Done"
text_color: self.theme_cls.primary_color
on_release: app.close_dialog()
<Container>
orientation: "vertical"
Screen:
MDFloatingActionButton:
pos_hint: {'right': 0.95, 'y': 0.05}
theme_text_color: "Custom"
text_color: app.theme_cls.primary_color
on_release:
app.show_dialog()
NavigationLayout:
ScreenManager:
Screen:
BoxLayout:
orientation: 'vertical'
MDToolbar:
size_hint: 1, 0.15
title: "Navigation Drawer"
elevation: 10
left_action_items: [['menu', lambda x: nav_drawer.toggle_nav_drawer()]]
Widget:
MDNavigationDrawer:
id: nav_drawer
ContentNavigationDrawer:
First, the button Done it's not beeing clicked because the dialog is auto dismissing before you can click it. So change your dialog to:
self.dialog = MDDialog(
title="Create new group",
type="custom",
content_cls=Content(),
auto_dismiss=False
)
Then you need to tell your app where you want to insert the widget. Currently you are trying to put it on the App class and it won't work. In this example I put it in the main window, but you can change according to where you want:
def new_window(self, *args):
btn = MDFlatButton(text="New group", size_hint_y=None, height=100)
self.root.add_widget(btn)

Categories

Resources