AttributeError 'Button' object has no attribute scrlFBtn - python

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.core.window import Window
from kivy.uix.scrollview import ScrollView
from kivy.effects.scroll import ScrollEffect
from kivy.uix.widget import Widget
from kivy.uix.button import Button
class BSGameMain:
def sas(self):
# blmain.remove_widget(scrlFBtns)
self.scrlFBtns.remove_widget(blbtns)
blmain = BoxLayout(orientation = 'vertical') # MainBoxLayout init
scrlFBtns = ScrollView(effect_cls = 'ScrollEffect')
blbtns = BoxLayout(
orientation = 'vertical',
size_hint_y = None
) # BoxLayout for buttons
blbtns.bind(minimum_height = blbtns.setter('height'))
scrlFBtns.add_widget(blbtns)
for i in range (2):
blbtns.add_widget(Button(
text='asd',
size_hint_y = None,
height = 40,
on_press = sas
))
lblmain = Label(text = 'asd')
blmain.add_widget(lblmain)
blmain.add_widget(scrlFBtns)
class BSApp(App):
def build(self):
game = BSGameMain()
return game.blmain
if __name__ == "__main__":
BSApp().run()
AttributeError 'Button' object has no attribute scrlFBtn. What is the problem? I'm trying to make it so that when you clicked, the screen was cleared (Widget was deleted). Рelp me please =)

Your code has several errors and bad programming practices:
if you declare variables that are inside a class and outside any method of the class will be class variables and not attributes of the class, so it is not a good practice to do so if you want to use later self, all that code must be within a method of a class.
on_someproperty wait as parameter a function that receives parameters, in your case sas() does not receive them so the solution is to use a lambda method.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView
from kivy.effects.scroll import ScrollEffect
from kivy.uix.button import Button
class BSGameMain:
def __init__(self):
self.blmain = BoxLayout(orientation = 'vertical') # MainBoxLayout init
self.scrlFBtns = ScrollView(effect_cls = 'ScrollEffect')
self.blbtns = BoxLayout(
orientation = 'vertical',
size_hint_y = None )
self.blbtns.bind(minimum_height = self.blbtns.setter('height'))
self.scrlFBtns.add_widget(self.blbtns)
for i in range(2):
self.blbtns.add_widget(Button(
text='asd',
size_hint_y = None,
height = 40,
on_press = lambda *args: self.sas()))
lblmain = Label(text = 'asd')
self.blmain.add_widget(lblmain)
self.blmain.add_widget(self.scrlFBtns)
def sas(self):
self.scrlFBtns.remove_widget(self.blbtns)
class BSApp(App):
def build(self):
game = BSGameMain()
return game.blmain
if __name__ == "__main__":
BSApp().run()

Related

Not able to print the text taken from kivy.uix.textinput.TextInput in KIVY Python

What I want to do is take input from kivy.uix.textinput.TextInput() and show it on the screen.
I am new to gui Programming and I think it is an easy task.
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
class MyWindowApp(App):
def __init__(self):
super(MyWindowApp, self).__init__()
self.lbl = Label(text='Read Me!')
self.inp = TextInput(multiline=False,
size_hint =(1, 0.05),
pos_hint = {"x":0, "y":0.05})
def build(self):
self.inp.bind(on_text_validate=self.on_enter)
#self.bt1.bind(on_press=self.clk)
layout = FloatLayout()
layout.orientation = 'vertical'
layout.add_widget(self.lbl)
layout.add_widget(self.inp)
return layout
def on_enter(self,value):
print(value)
def clk(self, obj):
print ('input')
x = input()
self.lbl.text = x
window = MyWindowApp()
window.run()
when i run the code, I get the regular output output.
when I type say "hello world" in the textbox, this is the output:
<kivy.uix.textinput.TextInput object at 0x03F5AE30>
I do not get what I typed.
please suggest what should I do
Modify the following ...
def on_enter(self, value):
print(value.text)

How to access the custom class in python?

I am newbies to programming, just picking up python. I have a very simple program which is showing a popup message, and it seems OK:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.popup import Popup
class t6App(App):
def build(self):
lb = Label(text="Welcome Here",size_hint=(1,0.8),pos_hint={'left':1,'top':1})
bt = Button(text="Press Me", size_hint=(1,0.1),pos_hint={'left':1,'x':0})
fl = FloatLayout()
fl.add_widget(lb)
fl.add_widget(bt)
cp = Popup(title='Guys', content=fl)
return cp
t6App().run()
Then I wanted to modify it, and add more things to it, the popup didn't show then: (2 programs always the same)
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.popup import Popup
class CustPop(Popup):
def build(self):
lb = Label(text="Welcome Here",size_hint=(1,0.8),pos_hint={'left':1,'top':1})
bt = Button(text="Press Me", size_hint=(1,0.1),pos_hint={'left':1,'x':0})
fl = FloatLayout()
fl.add_widget(lb)
fl.add_widget(bt)
cp = Popup(title='Guys', content=fl)
return cp
class t6App(App):
def build(self):
cp1 = CustPop()
return cp1
t6App().run()
The codes do run, but it seems like the layout /button /label in CustPop() can't be accessed (became a blank popup). My question is why and how to make it work?
Thx guys. I am appreciated.
You have defined a build() method in your CustPop, but unlike the App class, that build() method is not automatically called. You should put that code (with a couple minor changes) in the __init__() method.
class CustPop(Popup):
def __init__(self, **kwargs):
super(CustPop, self).__init__(**kwargs)
lb = Label(text="Welcome Here", size_hint=(1, 0.8), pos_hint={'left': 1, 'top': 1})
bt = Button(text="Press Me", size_hint=(1, 0.1), pos_hint={'left': 1, 'x': 0})
fl = FloatLayout()
fl.add_widget(lb)
fl.add_widget(bt)
# cp = Popup(title='Guys', content=fl)
self.title = 'Guys'
self.content = fl

Kivy change label text [duplicate]

This question already has answers here:
What is the purpose of the `self` parameter? Why is it needed?
(26 answers)
Closed 3 years ago.
I would like to change a Label-text in Python/Kivy after a swipe event has been detected. Changing the text works basically via the following line
self.Translation.text = "test"
but I have to change the text after detecting a swipe event from another class, in which I call a function to change the label text:
MyWidget.ThisDoesntWork("self_dummy")
In this function the exact same line as above gives me an error.
How can I change the Label-text from class "Swiping_class" calling function "MyWidget.ThisDoesntWork("self_dummy")"?
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.base import EventLoop
from kivy.clock import Clock
from kivy.factory import Factory
from kivy.uix.stacklayout import StackLayout
from kivy.uix.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.graphics import *
from kivy.properties import ListProperty
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen
from random import random
import pickle
import random
kv = '''
<ColoredLabel>:
size: (self.size_x,self.size_y)
pos: (0,0) # no effect
background_color:
canvas.before:
Color:
rgba: self.background_color
Rectangle:
pos: self.pos
size: (self.size_x,self.size_y)
'''
Builder.load_string(kv)
class ColoredLabel(Label):
background_color = ListProperty((0,0,0,1))
s_global = Window.size
size_x = s_global[0]
size_y = s_global[1]/3
class MyWidget(BoxLayout):
#init
def __init__(self, **kwargs):
super().__init__(**kwargs)
s_global = Window.size
size_x = s_global[0]
size_y = s_global[1]/3
self.ForeignLanguage = ColoredLabel(text="str_fl", size_hint=(None, None),size = (size_x,size_y), background_color=(0/255,171/255,169/255, 1))
self.Translation = ColoredLabel(text="str_tr", size_hint=(None, None),size = (size_x,size_y), background_color=(45/255,137/255,239/255, 1))
self.Example = ColoredLabel(text="str_ex", size_hint=(None, None),size = (size_x,size_y), background_color=(43/255,87/255,151/255, 1))
self.verticalBox = BoxLayout(orientation='vertical')
self.verticalBox.add_widget(self.ForeignLanguage)
self.verticalBox.add_widget(self.Translation)
self.verticalBox.add_widget(self.Example)
self.Translation.text = "test"
s=Swiping_class()
s.add_widget(self.verticalBox)
self.add_widget(s)
def ThisDoesntWork(self):
print("this is printed")
self.Translation.text = "I wanna change this via fucntion"
print("this is not printed anymore")
class Swiping_class(Screen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.initial = 0
def on_touch_down(self, touch):
self.initial = touch.x
def on_touch_up(self, touch):
if touch.x < self.initial:
print("swiped left")
MyWidget.ThisDoesntWork("self_dummy")
else:
print("swiped right")
class BoxLayoutDemo(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
BoxLayoutDemo().run()
I think I found a solution. Within your Swiping_class, replace this line:
MyWidget.ThisDoesntWork("self_dummy")
with this line:
MyWidget.ThisDoesntWork(self.parent)
That way, instead of passing a string to your method, you pass the label object, which contains the text attribute you are trying to modify.

Python Kivy - Adding a GridLayout to a BoxLayout

I want to create an UI with Buttons on top and a few Labels on bottom and if the labels exceeds the height it should be scrollable.
Something like this:
So far this is my code:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
class MyApp(App):
main_layout = BoxLayout(orientation='vertical')
top_layout = BoxLayout(orientation='horizontal')
scrollView = ScrollView()
gridLayout = GridLayout()
gridLayout.cols = 1
gridLayout.minimum_height = 10
gridLayout.padding = [0, 0, 0, 0]
scrollView.add_widget(gridLayout)
main_layout.add_widget(top_layout)
main_layout.add_widget(scrollView)
def btn_create(self, instance):
self.gridLayout.add_widget(Label(text='test'))
def btn_edit(self, instance):
pass
def btn_delete(self, instance):
pass
def build(self):
self.top_layout.size_hint=(1, .1)
# Button 'Erstellen'
btnCreate = Button()
btnCreate.text = 'Erstellen'
btnCreate.bind(on_press=self.btn_create)
# Button 'Bearbeiten'
btnEdit = Button()
btnEdit.text = 'Bearbeiten'
btnEdit.bind(on_press=self.btn_edit)
# Button 'Löschen'
btnDelete = Button()
btnDelete.text = 'Löschen'
btnDelete.bind(on_press=self.btn_delete)
self.top_layout.add_widget(btnCreate)
self.top_layout.add_widget(btnEdit)
self.top_layout.add_widget(btnDelete)
return self.main_layout
if __name__ == '__main__':
MyApp().run()
I added a GridLayout to a ScrollView, but this doesn't seem to work.
How can i make a scrollable list?
You have to set the size_hint_y of the GridLayout to None so that the height does not depend on the ScrollView and the size is minimum equal to the size of the GridLayout. On the other hand the Label must have size_hint_y to None so that the height does not depend on the GridLayout.
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
class MyApp(App):
main_layout = BoxLayout(orientation='vertical')
top_layout = BoxLayout(orientation='horizontal')
scrollView = ScrollView()
gridLayout = GridLayout(size_hint_y=None)
gridLayout.cols = 1
gridLayout.padding = [0, 0, 0, 0]
gridLayout.bind(minimum_height=gridLayout.setter('height'))
scrollView.add_widget(gridLayout)
main_layout.add_widget(top_layout)
main_layout.add_widget(scrollView)
def btn_create(self, instance):
self.gridLayout.add_widget(Label(text='test', size_hint_y=None))
def btn_edit(self, instance):
pass
def btn_delete(self, instance):
pass
def build(self):
self.top_layout.size_hint=(1, .1)
# Button 'Erstellen'
btnCreate = Button()
btnCreate.text = 'Erstellen'
btnCreate.bind(on_press=self.btn_create)
# Button 'Bearbeiten'
btnEdit = Button()
btnEdit.text = 'Bearbeiten'
btnEdit.bind(on_press=self.btn_edit)
# Button 'Löschen'
btnDelete = Button()
btnDelete.text = 'Löschen'
btnDelete.bind(on_press=self.btn_delete)
self.top_layout.add_widget(btnCreate)
self.top_layout.add_widget(btnEdit)
self.top_layout.add_widget(btnDelete)
return self.main_layout
if __name__ == '__main__':
MyApp().run()

Kivy button binding function with argument

I am trying to learn how to create application in Kivy and I have problem with sending argument to the function. I want to send text from input to the function and print it. Can somebody tell me how can I do it ?
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
class TutorialApp(App):
def gratulation(self, *args):
print args
def build(self):
boxLayout = BoxLayout(spacing=10,orientation='vertical')
g = TextInput(text='Enter gratulation',
multiline=False,
font_size=20,
height=100)
button = Button(text='Send')
button.bind(on_press=self.gratulation)
boxLayout.add_widget(g)
boxLayout.add_widget(button)
return boxLayout
if __name__ == "__main__":
TutorialApp().run()
Yo must get the text from "g" and then send it to the button callback, there is 2 ways of doing this, by a lambda function, or calling your class method aplying to it.
Lambda Version:
from __future__ import print_function ##Need to import this for calling print inside lambda
def build(self):
boxLayout = BoxLayout(spacing=10,orientation='vertical')
g = TextInput(text='Enter gratulation',
multiline=False,
font_size=20,
height=100)
button = Button(text='Send')
buttoncallback = lambda:print(g.text)
button.bind(on_press=buttoncallback)
...
The partial version:
from functools import partial ##import partial, wich allows to apply arguments to functions returning a funtion with that arguments by default.
def build(self):
boxLayout = BoxLayout(spacing=10,orientation='vertical')
g = TextInput(text='Enter gratulation',
multiline=False,
font_size=20,
height=100)
button = Button(text='Send')
buttoncallback = partial(self.gratulation, g.text)
button.bind(on_press=buttoncallback)
...
One way to do it:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
class TutorialApp(App):
def gratulation(self, instance):
print(self.g.text)
def build(self):
boxLayout = BoxLayout(spacing=10,orientation='vertical')
self.g = TextInput(text='Enter gratulation',
multiline=False,
font_size=20,
height=100)
button = Button(text='Send')
button.bind(on_press=self.gratulation)
boxLayout.add_widget(self.g)
boxLayout.add_widget(button)
return boxLayout
if __name__ == "__main__":
TutorialApp().run()
Hope it helps!

Categories