Kivy Screen not changing when button clicked python code - python

I have a button which was made in python file and I have been trying to make it so it changes screens from one to another.
def callback(instance):
print("Test 1")
sm = ScreenManager()
sm.add_widget(ScreenTwo(name="ScreenTwo"))
print("Test2")
class ScreenOne(Screen):
def on_enter(self):
self.add_widget(ImageURLButton(source=icon2, size=(100,100), size_hint=(0.1, 0.1), on_press=callback, pos_hint={"x":0.90, "top":1.0}))
class ScreenTwo(Screen):
pass
class ScreenManagement(ScreenManager):
pass
When I do click the button all it does it prints "Test1" and "Test2" without it changing the screen. Sorry if this is really obvious to others but I do not know how to fix it, could anyone help me please?

Would be better if you posted a MCVE, but I made one myself. Here is how it can be done:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
def callbackTo2(instance):
sm.current="ScreenTwo"
def callbackTo1(instance):
sm.current="ScreenOne"
class ScreenOne(Screen):
def __init__(self, *args):
super(ScreenOne, self).__init__(name='ScreenOne')
self.add_widget(Button(text='Switch To Screen Two', size_hint=(0.1, 0.1), on_press=callbackTo2, pos_hint={"x":0.90, "top":1.0}))
class ScreenTwo(Screen):
def __init__(self, *args):
super(ScreenTwo, self).__init__(name='ScreenTwo')
self.add_widget(Button(text='Switch To Screen One', size_hint=(0.1, 0.1), on_press=callbackTo1, pos_hint={"x":0.90, "top":1.0}))
sm = ScreenManager()
class ScreenPlayApp(App):
def build(self):
sm.add_widget(ScreenOne())
sm.add_widget(ScreenTwo())
return sm
if __name__ == '__main__':
app = ScreenPlayApp()
app.run()
Note that there is only one ScreenManager instance, all the screens can be added to the ScreenManager initially, and screens are switched by using sm.current=. Also, you can build your Screen in its __init__() method. Using the on_enter causes the members of the screen to be rebuilt each time the screen is displayed. Also, you cannot use both 'size' and 'size_hint' for the same widget unless you are setting 'size_hint' to 'None'.

Related

How do I create a button, and assign a function to it? Python, Kivy

I am a beginner in Python and Kivy. I want to create a simple program that should have an exit button on a window that must exit the app when pressed. Hi there, please help me. It's a request, please keep the code simple for a beginner. ^_^
Okay, I don't know how your code is, but this code could be copy-pasted as is and it will work (just import the necessary modules from kivy though):
.py
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
class yourscreen(FloatLayout):
def __init__(self, **kwargs):
#NEEDED
super(yourscreen, self).__init__(**kwargs)
self.button = Button(
text='exit',
size_hint=(0.5, 0.2)
)
self.button.bind(on_release= lambda x:self.exit())
self.add_widget(self.button)
def exit(self):
return MyApp().stop()
class MyApp(App):
def build(self):
return yourscreen()
if __name__ == '__main__':
MyApp().run()
You could pull out what you need which is MyApp().stop()

KIVY: How can I get the scroll direction in kivy?

I found this piece of code:
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
class Test(BoxLayout):
def __init__(self, **kwargs):
super(Test, self).__init__(**kwargs)
Window.bind(on_touch_down=self.window_on_touch_down)
def window_on_touch_down(self, *args):
print(args)
# scrolling the wheel down will give <MouseMotionEvent button="scrollup"
if '<MouseMotionEvent button="scrollup"' in args:
print('hello')
class TestApp(App):
def build(self):
return Test()
if __name__ == '__main__':
TestApp().run()
and while it prints the scrollup motion I can't use it... args has the string in it but the if doesn't work and "hello" isn't printed... anybody know why?
What you see in the prints are python objects not strings.
So you can't just check for a string.
A better way to get what you want is to check what button produces the MouseMotionEvent
def window_on_touch_down(self, window, mouse_event):
# scrolling the wheel down will give <MouseMotionEvent button="scrollup"
if mouse_event.button == "scrollup":
print('hello')

Kivy: Kivy launcher fall down

I have simple code for kivy, on W10 runs without problem. It falls down during loading in kivy launcher. Problem is without message.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
class View(BoxLayout):
def __init__(self):
super().__init__()
self.text = "No text"
but = Button(text = "Press",on_press = self.show)
self.add_widget(but)
self.lbl = Label()
self.add_widget(self.lbl)
def show(self,obj):
self.lbl.text = self.text
pass
class MyPaintApp(App):
def build(self):
return View()
if __name__ == '__main__':
MyPaintApp().run()
It does not run because you call super wrong.
As kivy launcher uses python 2, you need to pass your class (View) and the instance (self) to super.
You need to edit your class like this:
class View(BoxLayout):
def __init__(self,**kwargs):
super(View,self).__init__(**kwargs)
in every failure in kivy launcher, there is a '.kivy/log' directory inside the project directory that has a full log. you could find all the problem there.

Kivy : how to get widget by id (without kv)

Let's say I define on the fly in Kivy a few widgets (buttons) and dynamically assign their id.
I'm not using kv language in this use case.
I can keep a reference of a widget id without keeping track of the widget itself : then I'd like to access the widget through its id.
Can I do something like "get widget by id" ?
(If I had defined the widget in a kv file, I could have used self.ids.the_widget_id to access the widget itself through its id)
Kivy widgets make tree structure. Children of any widget are avaiable through children atribute. If you want, you can keep reference only to root window and then iterate over it's widgets using walk method:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
class MyWidget(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
button = Button(text="...", id="1")
button.bind(on_release=self.print_label)
l1 = BoxLayout(id="2")
l2 = BoxLayout(id="3")
self.add_widget(l1)
l1.add_widget(l2)
l2.add_widget(button)
def print_label(self, *args):
for widget in self.walk():
print("{} -> {}".format(widget, widget.id))
class MyApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
MyApp().run()
walk() and walk_reverse() method were added to kivy.uix.widget.Widget in 1.8.1 version of Kivy. For older versions you need to recursively parse tree yourself:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
class MyWidget(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
button = Button(text="...", id="1")
button.bind(on_release=self.print_label)
l1 = BoxLayout(id="2")
l2 = BoxLayout(id="3")
self.add_widget(l1)
l1.add_widget(l2)
l2.add_widget(button)
def print_label(self, *args):
children = self.children[:]
while children:
child = children.pop()
print("{} -> {}".format(child, child.id))
children.extend(child.children)
class MyApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
MyApp().run()
You can retrieve the widget using directly the ids. For example in your code you can modify the Button text with the following snippet:
self.ids.2.ids.3.ids.1.text = '!!!!'
You can change properties of each widget using ids:
self.ids['order_number'].text='S1212'

Kivy tutorial buttons don't print

I'm working through the Kivy tutorial, programming guide, and find the following code is not actually printing the button position anywhere, as far as I can tell---that is, the btn_pressed() method doesn't seem to do anything.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty
class RootWidget(BoxLayout):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
self.add_widget(Button(text='btn 1'))
cb = CustomBtn()
cb.bind(pressed=self.btn_pressed)
self.add_widget(cb)
self.add_widget(Button(text='btn 2'))
def btn_pressed(self, instance, pos):
print ('pos: printed from root widget: {pos}'.format(pos=pos))
class CustomBtn(Widget):
pressed = ListProperty([0, 0])
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
self.pressed = touch.pos
# we consumed the touch. return False here to propagate
# the touch further to the children.
return True
return super(CustomBtn, self).on_touch_down(touch)
def on_pressed(self, instance, pos):
print ('pressed at {pos}'.format(pos=pos))
class TestApp(App):
def build(self):
return RootWidget()
if __name__ == '__main__':
TestApp().run()
Does anyone have any hints or ideas why this isn't working? Is this the intended behavior and I missed something or is there an error in the tutorial?
Specifically, while the instructions above produce buttons that can be clicked and flash---there doesn't seem to be any output corresponding to the method:
def btn_pressed(self, instance, pos):
print ('pos: printed from root widget: {pos}'.format(pos=pos))
Maybe it's printing black on black?
The seemingly blank, unlabeled spot in the middle is the button that accepts location and prints location to the console. I was clicking on the buttons labeled "btn" and didn't notice this place existed.
This part of the tutorial is demonstrating how you can make custom buttons that do stuff precisely like this. It would be more clear if this were labeled, but that should be doable by looking at the API.
Anyway, the code is working as expected.

Categories