Screen doesn't change after pressing a button in Xcode simulator - xcode

My Kivy app work fine in python2. Running in Xcode (10.1) simulator gives me the main screen, but pressing button does not bring me to the second one (drawing screen). Interestingly when moving and pressing on the mouse, the app print the coordinates as it should.
I've tried create a very simple project with only 1 button and 2 screens: again, on python works OK but in the simulator not.
Any suggestions?
python
class MainScreen(Screen):
username = ObjectProperty(None)
test_type = ObjectProperty(None)
test_date = ObjectProperty(None)
def reset(self):
self.username.text = ""
self.test_type.text = ""
self.test_date.text = ""
class SecondScreen(Screen):
pass
class AnotherScreen(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class DrawInput(Widget):
def on_touch_down(self, touch):
timing_ms = ApplePenApp.get_running_app().sw_seconds
print('test')
with self.canvas:
Color(0, 0, 0)
touch.ud["line"] = Line(points = (touch.x, touch.y))
def on_touch_move(self, touch):
timing_ms = ApplePenApp.get_running_app().sw_seconds
touch.ud["line"].points += (touch.x, touch.y)
def on_touch_up(self, touch):
timing_ms = ApplePenApp.get_running_app().sw_seconds
presentation = Builder.load_file("applepen_kivy.kv")
class ApplePenApp(App):
def build(self):
return presentation
if __name__=="__main__":
ApplePenApp().run()
Kivy
# File name: main.py
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManagement:
transition: FadeTransition()
MainScreen:
id: main
SecondScreen:
AnotherScreen:
<MainScreen>:
name: "main"
#define global variables
username: username
test_type: test_type
test_date: test_date
GridLayout:
cols:1
#organise the window
size: root.width, root.height
GridLayout:
cols: 2
Label:
text: "Username: "
color: 0.5,0.5, 0.5, 1
font_size: 30
TextInput:
id: username
multiline: False
font_size: 30
Label:
text: "Copy/Recall/Recall2: "
color: 0.5,0.5, 0.5, 1
font_size: 30
TextInput:
id: test_type
multiline: False
font_size: 30
Label:
text: "Date: "
color: 0.5,0.5, 0.5, 1
font_size: 30
TextInput:
id: test_date
multiline: False
font_size: 30
Button:
font_size: 30
size_hint: 0.5, 0.5
text: "Submit"
on_press: app.root.current = "drawing"
<SecondScreen>:
name: "drawing"
FloatLayout:
DrawInput:
id: drawing
Button:
font_size: 30
size_hint: 0.2, 0.05
pos_hint: {"x": 0.4, "bottom": 1}
text: "finish"
on_release: app.root.current = "main"

Related

Show the text form a TextInput in class A in a Label in class B

I'm so deeply stuck in this!!! I tried through hours of frustration to get this little thing done... Every help would be so kind and relieving.
So here's my problem:
I know there's a bit of code, but the hole question turns just about two classes...
In the class Datum, I want a Label.
In the class Alledaten, I want a TextInput.
Now I want that TextInput to bind on_text_validate to update my Labels text.
I know how that works within the same class... (its pretty simple)
but not in two different classes
'''
from kivy.app import App
from kivy.core.window import Window
from kivy.metrics import dp, sp
from kivy.properties import StringProperty, ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.textinput import TextInput
from wochenplaner_script import CodefuerWochenplaner_ausgeglichen as CW
Builder.load_file("kivy.kv")
Window.clearcolor = (1, 1, .5, .5)
# 1. File Managing -------------------------------
class Wochenplan(App):
def build(self):
# Designate .kv design file
# Builder.load_file("kivy.kv")
sm = ScreenManager()
sm.add_widget(Maininterface(name="screen_maininterface"))
sm.current = "screen_maininterface"
return sm
class Screenmanager(ScreenManager):
pass
# 2. Code ----------------------------------------
class Zeitplanprotag(GridLayout):
def __init__(self, **kwargs):
super(Zeitplanprotag, self).__init__(**kwargs)
y = Window.system_size[1]
for i in range(1, 16, 1):
buttonleft = Button(text=f'{i} left', size_hint=(.5, None), height=y * 0.1, halign="left", valign="middle")
buttonright = Button(text=f'{i} right', size_hint=(1, None), height=y * 0.1, halign="left", valign="middle")
self.add_widget(buttonleft)
self.add_widget(buttonright)
class Wochentage(BoxLayout):
def __init__(self, **kwargs):
super(Wochentage, self).__init__(**kwargs)
button = Button(size_hint=(.5, 1))
button.text = "Zeit"
button2 = Button(size_hint=(1, 1))
button2.text = "Plan"
self.add_widget(button)
self.add_widget(button2)
class Datum(BoxLayout):
text_input_str = StringProperty("tag")
def ooon_text_validate(self, widget):
self.text_input_str = widget.text
print(self.text_input_str)
# self.ids.label_am_arsch.text = self.text_input_str
self.ids.which_day.text = "harald"
# 2.2 Textinput -------------- <------ in here is my question
class Alledaten(BoxLayout):
# text_input_str = StringProperty("Tag 1")
def __init__(self, *args, **kwargs):
super(Alledaten, self).__init__(**kwargs)
input_ab_wann = TextInput(hint_text="Ab Tag: ",
hint_text_color=(0, 0, 0, 1),
background_color=(1, 1, 1, 1),
halign="center",
multiline=False)
# ids="input_ab_wann_id")
# input_ab_wann.bind(on_text_validate=Datum().ooon_text_validate) <----- **whyyy does this not go inside the function ooon_text_validate?**
def on_text(widget):
Datum().ooon_text_validate(widget) # <------ **but with this the terminal prints the input text, but doesn't change the Label text**
input_ab_wann.bind(on_text_validate=on_text)
self.add_widget(input_ab_wann)
# 3. Appearance ----------------------------------
class Spalteprotag(BoxLayout):
pass
# 4. Screens -------------------------------------
class Maininterface(Screen):
def float_in_int(self, float, **kwargs):
super(Maininterface).__init__(**kwargs)
de_int = float
return int(de_int)
# ----------------------------------
if __name__ == "__main__":
Wochenplan().run()
'''
and my kv file:
'''
<Screenmanager>:
Maininterface:
<Maininterface>:
# 1. Stufe
BoxLayout:
# 1. vBox -> 2. hBox -> 3. vBox -> 4. Grid 2 cols
orientation: "vertical"
size: root.width, root.height
# 1. Stufe
BoxLayout:
size_hint: (1, .15)
orientation: "horizontal"
Alledaten:
orientation: "vertical"
size_hint: (.3, 1)
Label:
text: "Wochenplan"
size_hint: (1, 1)
# texture_size: self.size
text_size: self.size
halign: "center"
valign: "middle"
markup: True
font_size: dp(20)
color: (0, 0, 0, 1)
Label:
text: ""
size_hint: (.3, .5)
Datum: # <------ in here is my Label
# 2. Stufe
BoxLayout:
orientation: "horizontal"
# 1 Spalte in Tabelle
Spalteprotag:
# 2 Spalte in Tabelle
# Spalteprotag:
<Spalteprotag>:
# -> BoxLayout
orientation: "vertical"
# size_hint: (.25, 1)
# 3. Stufe
Wochentage:
size_hint: (1, .1)
ScrollView:
do_scroll_x: False
do_scroll_y: True
Zeitplanprotag:
cols: 2
height: self.minimum_height
size_hint_y: None
# row_default_height: 100
row_force_default: False
# spacint: 10
<Zeitplanprotag>:
# 4. Stufe -> GridLayout
<Wochentage>:
<Datum>:
orientation: "horizontal"
size_hint: (1, .1)
TextInput:
id: zweite_input
hint_text: "this text input is just an example to show my question\n ->> the textinput above should work like that one!"
multiline: False
on_text_validate: root.text_input_str = self.text
Label: # <------ this is the label which causes problems
id: which_day
# text: root.text_input_str
text: root.text_input_str
# background_color: (0, 0, 0, 1)
color: (0, 0, 0, 1)
# size_hint: (1, 1)
<Alledaten>:
# TextInput:
# id: ab_tag_textin
# hint_text:"Ab Tag: "
# hint_text_color:(0, 0, 0, 1)
# background_color:(1, 1, 1, 1)
# halign:"center"
# multiline:False
# on_text_validate: Datum.ooon_text_validate = self.text <---- I tried it with an TextInput in the kv File but I did't know how to reference to another class...
if someone knows the solution via kv file im also very happy, but I want to now what I did wrong in my way to fix it via python file...
'''

How to set image size inside TabbedPanel in Kivy?

I'm trying to set the size of an image which is a child item of the TabbedPanel.
How do I increase the size of the added image (which is small as seen above) and make it responsive to any screen resize events. Below is my code snippet.
.kv
TabbedPanel:
do_default_tab: False
tab_height:20
tab_width: self.parent.width / 4
TabbedPanelItem:
text: "ONE"
Image:
src: "img.jpg"
size: 400, 500
allow_stretch: True
keep_ratio: True
TabbedPanelItem:
text: "TWO"
Image:
src: " "
size: 400, 500
allow_stretch: True
keep_ratio: True
Should the image widget be enclosed within another layout? Thanks for your time.
Solution
Please refer to the example for details.
Replace src: with source:.
Remove size: 400, 500
Example
main.py
from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.lang import Builder
Builder.load_string("""
<Test>:
do_default_tab: False
tab_height:20
tab_width: self.width / 4
TabbedPanelItem:
text: "ONE"
Image:
source: "brown-bear-150x150.jpg"
allow_stretch: True
keep_ratio: True
TabbedPanelItem:
text: "TWO"
Image:
source: "grizzly-bear-150x150.jpg"
allow_stretch: True
keep_ratio: True
TabbedPanelItem:
text: 'THREE'
Image:
source: "giant-panda-150x150.jpg"
allow_stretch: True
keep_ratio: True
TabbedPanelItem:
text: 'FOUR'
Image:
source: "polar-bear-150x150.jpg"
allow_stretch: True
keep_ratio: True
""")
class Test(TabbedPanel):
pass
class TabbedPanelApp(App):
def build(self):
return Test()
if __name__ == '__main__':
TabbedPanelApp().run()
Output

Kivy Popup not able to access root method

I am a newbie here so feel free to correct me if I am not following proper procedures.
I have a Kivy app that opens a popup. In the popup, I can enter 2 numbers then click the Add button which should add the 2 numbers. I get an error saying, "AttributeError: 'CustomPopup' object has no attribute 'addNum'"
Why would this be?
test.py file
import kivy
kivy.require('1.9.1') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.properties import StringProperty
from kivy.properties import ObjectProperty
class CustomPopup(Popup):
pass
class MyStuff(BoxLayout):
num1 = StringProperty
num2 = StringProperty
answer = ''
def openPopup(self):
the_popup = CustomPopup()
the_popup.open()
def addNum(self):
self.answer = str(int(self.num1) + int(self.num2))
class MyStuffApp(App):
def build(self):
return MyStuff()
if __name__ == '__main__':
MyStuffApp().run()
mystuff.kv file
#: import main test
<MyStuff>:
orientation: 'vertical'
spacing: 5
padding: 5
Button:
text: 'Change numbers'
on_press: root.openPopup()
font_size: 50
Label:
text: root.answer
<CustomPopup>:
size_hint: .5, .5
auto_dismiss: False
title: 'Addition'
num1: number2
num2: number2
BoxLayout:
orientation: 'vertical'
Label:
text: '1st number'
TextInput:
id: number1
Label
text: '2nd number'
TextInput
id: number2
Button:
text: 'Add'
on_press: root.addNum()
First of all, to access addNum, you have to call app.root.addNum from the kv part.
You also have to send the values to be added, which are the text you entered in the text boxes: (number1.text, number2.text).
So the running code could be something like this:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
Builder.load_string("""
<MyStuff>:
orientation: 'vertical'
spacing: 5
padding: 5
Button:
text: 'Change numbers'
on_press: root.openPopup()
font_size: 50
Label:
text: root.answer
<CustomPopup>:
size_hint: .5, .5
auto_dismiss: False
title: 'Addition'
num1: number2
num2: number2
BoxLayout:
orientation: 'vertical'
Label:
text: '1st number'
TextInput:
id: number1
Label
text: '2nd number'
TextInput
id: number2
Button:
text: 'Add'
on_press: app.root.addNum(number1.text, number2.text)
""")
class CustomPopup(Popup):
pass
class MyStuff(BoxLayout):
# num1 = StringProperty()
# num2 = StringProperty()
answer = ''
def openPopup(self):
the_popup = CustomPopup()
the_popup.open()
def addNum(self, *args):
# self.answer = str(int(self.num1) + int(self.num2))
self.answer = str(int(args[0]) + int(args[1]))
print(self.answer)
class MyStuffApp(App):
def build(self):
return MyStuff()
if __name__ == '__main__':
MyStuffApp().run()
You can access the methods from MyStuff if you have a reference somewhere to that class.
When you do root.addNum() you try to access a method inside CustomPopup which is root in that case.
So what I would do in this case, is to define MyStuff as an attribute of your App class, (self.ms = MyStuff()). That way you can access it in kv by doing app.ms.addNum()
Also you need to pass the numbers to addNum
In py.:
class MyStuff(BoxLayout):
answer = ''
def openPopup(self):
the_popup = CustomPopup()
the_popup.open()
def addNum(self, num1, num2):
self.answer = str(int(num1) + int(num2))
class MyStuffApp(App):
def build(self):
self.ms = MyStuff()
return self.ms
And in kv.:
Button:
text: 'Add'
on_press: app.ms.addNum(number1.text, number2.text)

How can I make a Kivy (KVlang) cascaded spinner set respond to my first on_release?

My cascaded spinners do what i want on the SECOND release of the master spinner.
How can i make this work on the FIRST release?
Thanks in advance. Here is my KVlang and Python code.
KVlang:
# 0009_spinnerCascade.kv
<MyLayout#BoxLayout>:
orientation: 'vertical'
Spinner:
id: s1
text: 'colors'
values: 'colors numbers days'.split()
size_hint_y: None
height: '48dp'
my_string_property: 'hello from s1'
on_release: s2.my_key = self.text
Label:
text: 'Mid label'
Spinner:
id: s2
text: 'choose one'
my_dict: {'colors': 'red green blue'.split(), 'numbers': '1 2 3'.split(), 'days':'mon tue wed'.split() }
my_key: 'numbers'
values: self.my_dict[self.my_key]
size_hint_y: None
height: '48dp'
MyLayout
Python
''' 0009_spinnerCascade.py
'''
import kivy
kivy.require('1.8.0')
from kivy.app import App
from kivy.lang import Builder
from kivy.config import Config
Config.set('graphics', 'width', '430')
Config.set('graphics', 'height', '430')
class MyApp(App):
def build(self):
self.root = Builder.load_file('0009_spinnerCascade.kv')
return self.root
if __name__ == '__main__':
MyApp().run()
release event is triggered when your spinner opens and shows options, before you select any. In that moment value of s2.my_key is set to s1.text. After you select option, release event is not triggered and s2.my_key remains unchanged. Then after you display list of s1 options with second click, second release event is triggered and value od s2.my_key is finally setted to right value. Observe this behaviour with:
<MyLayout#BoxLayout>:
# ...
Spinner:
id: s1
# ...
on_release: s2.my_key = self.text ; print("spinner opened")
# ...
You actually need to observe text property to detect changes:
<MyLayout#BoxLayout>:
# ...
Spinner:
id: s1
# ...
on_text: s2.my_key = self.text ; print("option selected")
# ...
I implemented this behaviour as follows:
def callback(instance,value):
print(instance,value)
class spinnerName(Spinner):
values = ('1','2','3')
spinInstance = Spinner()
spinInstance.bind(text=callback)
print(instance,value) will be called every time you click an item in the Spinner.

How do I position an image in kivy using the python language?

How do I position the image using python as opposed to the kivy language (.kv files)?
My work is as follows.
import kivy
kivy.require('1.8.0') # current kivy version
import ConfigParser
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.image import Image
class login(Widget):
#checking to see if the user logging in has privilage to access program
def validate(self, *args):
username = self.ids['user']
user = username.text
config = ConfigParser.ConfigParser()
config.read('Privilage.cfg')
if not config.has_section('users'):
print 'the Privilage.cfg file has been tampered with'
if not config.has_option('users',user):
print 'user is not listed'
else:
userPriv = config.get('users',user)
print 'user',user,'has privilage',userPriv
with self.canvas:
Image(source='/Users/Kevin/Desktop/Python-extras/SSS Assistant/Manager_images/check-icon.png',pos=self.pos,size=self.size)
class DataApp(App):
def build(self):
return login()
if __name__ == '__main__':
DataApp().run()
My goal is to verify if the user exists and then put a check mark by the username box if it does and then later (no code yet) verify a matching password (no code yet either). I didn't want to code what happens if the verification fails or password matches yet because if I can't change the image position there is not point.
Currently the image appears right in the center and is very large (I need to shrink it too). I've searched the Kivy API in kivy.uix.image.Image and I can't find a solution (searched for position change or center_x kind of stuff and can't find). I am trying to do this in python because I'm putting the image constructor in the if statement and I'm not sure .kv files can do that since they control properties.
**The line I'm concerned with is:
with self.canvas:
Image(source="path",pos=self.pos,size=self.size)
Here is the accompanying kivy file just in case:
#:kivy 1.8.0
<login>:
canvas:
Rectangle:
source:"/Users/Kevin/Desktop/Python-extras/SSS Assistant/Manager_images/background.jpg"
pos: self.pos
size: self.size
Label:
center_x: root.width / 2
top: (root.top/2) + 150
text: 'Please login with your ID and password'
Label:
center_x: (root.width/2)-130
top: (root.top/2)+110
text: 'Username:'
Label:
center_x: (root.width/2)-130
top: (root.top/2)+83
text: 'Password:'
TextInput:
id: user
center_x: (root.width/2) +10
top:(root.top/2)+75
size_hint: None, None
size: 200, 30
max_lines: 1
valign: 'middle'
halighn: 'center'
font_size: 15
multiline: False
on_text_validate: root.validate()
TextInput:
id: password
center_x: (root.width/2) +10
top:(root.top/2)+45
size_hint: None, None
size: 200, 30
max_lines: 1
valign: 'middle'
halighn: 'center'
font_size: 15
multiline: False
password: True
Thanks in advance!
with self.canvas:
Image(source="path",pos=self.pos,size=self.size)
Image is a Widget, not a canvas instruction. You should add it with self.add_widget and not use the canvas at all.
I think you're also reinventing the wheel a bit with all your position and size instructions in kv, you might find it easier to use kivy's layout classes to manage much of this for you.

Resources