Reputation: 15
Hi i created a class "LabelledSlider" in my .kv file that contains 2 Labels and 1 Slider with some properties already set in the definition of the class.
When i then try to change one of this properties (in this case the text of one of the Labels) it throws a SyntaxError (but the Syntax is in my opinion correct).
Here the .kv file for overview:
#:import Factory kivy.factory.Factory
<PopupStart@Popup>:
id : popup_start
title: "Start Function Pop-up"
auto_dismiss: False
size_hint : (.4, .4)
RelativeLayout:
size_hint : (.8, .9)
Button:
text: 'Close me!'
size_hint : (.45, .25)
pos_hint : {'center_x':0.5, 'y':0.1}
on_release: root.dismiss()
Label:
text : "The start function will run the AI Algorithm \n and will be provided soon"
font_size : 15
size_hint : (.55, .45)
pos_hint : {'center_x':0.5, 'top':1}
<PopupCalibrate@Popup>:
id : popup_calibrate
title: "Calibrate Function Pop-up"
auto_dismiss: False
size_hint : (.4, .4)
RelativeLayout:
size_hint : (.8, .9)
Button:
text: 'Close me!'
size_hint : (.45, .25)
pos_hint : {'center_x':0.5, 'y':0.1}
on_release: root.dismiss()
Label:
text : "The calibrate function will run the Camera Calibration \n and will be provided soon"
font_size : 13
size_hint : (.55, .45)
pos_hint : {'center_x':0.5, 'top':1}
<LabelledSlider>:
# The y-displacement relative to slider is +0.2 for "property" Label and -0.3 for "value" Label
slider_value : slider.value
property_name : property.text
propertyX : property
Label:
id: property
text: ""
font_size : 15
pos_hint_center_x : .5
pos_hint_center_y : .7
Slider:
id : slider
value_track : True
value_track_color : [1, 0, 0, 1]
range : (0, 100) #Range must be checked with camera Specs!
value : 0
step : 1
pos_hint_center_x : .5
pos_hint_center_y : .5
size_hint_y : None
height : 50
on_value : root.slider_value = self.value
Label:
text : "%(property)s at %(value)scm" % {"property" : root.property_name, "value" : str(root.slider_value)}
font_size : 10
pos_hint_center_x : .5
pos_hint_center_y : .2
<CameraView>:
playing_camera : playing_camera
orientation : "vertical" #should be omitted (related to BoxLayout) but still works
Camera:
id : playing_camera
play : True
index : 0
#DA ELIMINARE, MA COSI FUNZIONA
Button:
size_hint : (.1,.1)
on_release : root.parent.select_camera_button()
Label:
text : "Camera n.%s" % str(playing_camera.index)
font_size : "15sp"
size_hint : (.3,.1)
pos_hint : {'center_x':0.5, 'top':1}
bold : True
<ControlsView>:
focus_value : focus_slider.value
Button:
id : btn_start
text : "Start"
font_size : 20
size_hint : (0.7,.1)
pos_hint : {'center_x':0.5, 'y':0.05}
background_normal : ""
background_color : (0,1,0,.5)
bold : True
on_release: Factory.PopupStart().open()
#Check where the function definition should be placed
#Also check if "self." is the right expression
Button:
id : btn_calibrate
text : "Calibrate"
font_size : 18
size_hint : (0.7,.1)
pos_hint : {'center_x':0.5, 'top':0.75}
background_normal : ""
background_color : (0, 0, 1, .5)
on_release: Factory.PopupCalibrate().open()
#Strange behaviour: If a ")" is present it will interpreted as EOF, hence returning an error
Label:
text : "logic.portable"
font_size : 25
pos_hint : {'top':1.45}
Label:
text : "Gewicht in g"
pos_hint : {'center_x':0.5, 'top':1.35}
color : (1,0,0,.5)
Label:
text : "Focus"
font_size : 15
pos_hint : {'center_x': .5, 'center_y': .27}
Slider:
id : focus_slider
value_track : True
value_track_color : [1, 0, 0, 1]
range : (20, 100) #Range must be checked with camera Specs!
value : 20
step : 1
pos_hint : {'center_x': .5, 'center_y': .25}
size_hint_y : None
height : 50
on_value : root.focus_value = self.value
Label:
text : "Focus at %scm" % str(root.focus_value)
font_size : 10
pos_hint : {'center_x': .5, 'center_y': .22}
LabelledSlider:
pos_hint : {'center_x': .5, 'center_y': .18}
propertyX:
text : "Brightness"
<InteractiveGUI>:
cameraview : cameraview
controlsview : controlsview
CameraView:
id : cameraview
size_hint_x : 4
ControlsView:
id : controlsview
here only the intersting parts:
<LabelledSlider>:
# The y-displacement relative to slider is +0.2 for "property" Label and -0.3 for "value" Label
slider_value : slider.value
property_name : property.text
propertyX : property
Label:
id: property
text: ""
font_size : 15
pos_hint_center_x : .5
pos_hint_center_y : .7
Slider:
id : slider
value_track : True
value_track_color : [1, 0, 0, 1]
range : (0, 100) #Range must be checked with camera Specs!
value : 0
step : 1
pos_hint_center_x : .5
pos_hint_center_y : .5
size_hint_y : None
height : 50
on_value : root.slider_value = self.value
Label:
text : "%(property)s at %(value)scm" % {"property" : root.property_name, "value" : str(root.slider_value)}
font_size : 10
pos_hint_center_x : .5
pos_hint_center_y : .2
<ControlsView>:
focus_value : focus_slider.value
[...]
LabelledSlider:
pos_hint : {'center_x': .5, 'center_y': .18}
propertyX:
text : "Brightness"
And finally the python file:
import kivy
from kivy.properties import ObjectProperty
kivy.require('2.1.0')
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.uix.gridlayout import GridLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.label import Label
from kivy.uix.camera import Camera
from kivy.uix.dropdown import DropDown
from kivy.base import runTouchApp
from kivy.uix.slider import Slider
from kivy.uix.screenmanager import ScreenManager
class InteractiveGUI(BoxLayout):
cameraview = ObjectProperty(None)
controlsview = ObjectProperty(None)
def select_camera_button(self):
if self.cameraview.playing_camera.index == 0:
self.cameraview.playing_camera.index = 1
else:
self.cameraview.playing_camera.index = 0
def select_camera(self, data):
if str(data) == "Camera 1":
self.cameraview.playing_camera.index = 0
elif str(data) == "Camera 2":
self.cameraview.playing_camera.index = 1
elif str(data) == "Camera 3":
self.cameraview.playing_camera.index = 2
elif str(data) == "Camera 4":
self.cameraview.playing_camera.index = 3
else:
pass
class CameraView(RelativeLayout):
playing_camera = ObjectProperty(None)
'''def change_camera(self):
if (playing_camera.index == 0):
playing_camera.index = 1
else:
playing_camera.index = 0'''
class ControlsView(RelativeLayout):
playing_camera = ObjectProperty(None)
def __init__(self, **kwargs):
super(ControlsView, self).__init__(**kwargs)
# A dropdown Menu for camera selection needs to be implemented:
# Define the Dropdown menu here in Python code, because it has a lot of logic behind
self.camera_sel = DropDown()
for index in range(1, 5):
btn = Button(text='Camera %d' % index,
size_hint_x=.7,
size_hint_y=None,
height=25
)
btn.bind(on_release=lambda btn: self.camera_sel.select(btn.text))
self.camera_sel.add_widget(btn)
self.mainbutton = Button(text='Select Camera',
size_hint_x=.7,
size_hint_y=None,
height=35,
pos_hint={'center_x': .5, 'center_y': .5}
)
self.add_widget(self.mainbutton)
self.mainbutton.bind(on_release = self.camera_sel.open)
self.camera_sel.bind(on_select = lambda instance, x: setattr(self.mainbutton, 'text', x))
self.camera_sel.bind(on_select = self.select_camera1) #CAN'T CALL PARENT INSIDE __init()__
def select_camera1(self, instance, data):
print(self.parent)
print(data)
print(type(data))
return self.parent.select_camera(data)
class LabelledSlider(Slider):
pass
class CustomDropDown(DropDown):
pass
class LogPortGUI_DropPython(App):
def build(self):
'''
All the "simple" UI Design of the GUI can be found in the LogPort.kv file
in this directory.
In this GUI.py file will then remain only the logic, function defintion and
smaller adjustement to maintain a better overview.
:return: The main GUI of the App
'''
root = InteractiveGUI()
print(root)
print(root.children)
for child in root.children:
print("Now the 1 Level children\n")
print(child)
for granchild in child.children:
print("Now 2nd level Children\n")
print(granchild)
return root
if __name__ == '__main__':
LogPortGUI_DropPython().run()
The Error message displys:
File "/Users/____/opt/anaconda3/lib/python3.7/site-packages/kivy/lang/parser.py", line 194, in precompile self.co_value = compile(value, self.ctx.filename or '<string>', mode) File "/Users/____/PycharmProjects/untitled/logportgui_droppython.kv", line 179 text : "Brightness" ^ SyntaxError: invalid syntax
John's answer worked perfectly, but still the positioning of Labels on top and at the bottom of the slider doesn't work correctly.
Added John's suggestion to get the property_Label.text to work
Changed the Inheritance of LabeledSlider to RelativeLayout (originally it was, wrognly, inheriting from the Slider class)
Changed the pos_hint_center_y to 1 and 0 respectively (idea was to put the first Label at the top of the LabelledSlider's RelativeLayout and the value Slider at the bottom, to see if actually something would change.)
class LabelledSlider(RelativeLayout): pass
LabelledSlider's class definition:
<LabelledSlider>:
# The y-displacement relative to slider is +0.2 for "property" Label and -0.3 for "value" Label
slider_value : slider.value
property_name : property.text
property_text : ""
Label:
id: property
text: root.property_text
size_hint : (1,.2)
font_size : 15
pos_hint_center_x : .5
pos_hint_center_y : 1
Slider:
id : slider
value_track : True
value_track_color : [1, 0, 0, 1]
range : (0, 100) #Range must be checked with camera Specs!
value : 0
step : 1
pos_hint_center_x : .5
pos_hint_center_y : .5
size_hint_y : None
height : 50
on_value : root.slider_value = self.value
Label:
text : "%(property)s at %(value)scm" % {"property" : root.property_name, "value" : str(root.slider_value)}
font_size : 10
size_hint : (1,.2)
pos_hint_center_x : .5
pos_hint_center_y : 0
And then add the sliders as children of Controlsview (another RelativeLayout):
<ControlsView>:
focus_value : focus_slider.value
Label:
text : "Focus"
font_size : 15
pos_hint : {'center_x': .5, 'center_y': .27}
Slider:
id : focus_slider
value_track : True
value_track_color : [1, 0, 0, 1]
range : (20, 100) #Range must be checked with camera Specs!
value : 20
step : 1
pos_hint : {'center_x': .5, 'center_y': .25}
size_hint_y : None
height : 50
on_value : root.focus_value = self.value
Label:
text : "Focus at %scm" % str(root.focus_value)
font_size : 10
pos_hint : {'center_x': .5, 'center_y': .22}
LabelledSlider:
id : brightness_slider
size_hint : (1, 0.2)
pos_hint : {'center_x': .5, 'center_y': .47}
property_text : "Brightness"
LabelledSlider:
id : other_slider
size_hint : (1, 0.2)
pos_hint : {'center_x': .5, 'center_y': .40}
property_text : "Other"
The croocked Output looks like this:
Upvotes: 0
Views: 67
Reputation: 39092
Try adding a Property
to the LabelledSlider
. You can do this in the kv
:
<LabelledSlider>:
# The y-displacement relative to slider is +0.2 for "property" Label and -0.3 for "value" Label
slider_value : slider.value
property_name : property.text
propertyX : property
property_text: '' # new property
Label:
id: property
text: root.property_text # use the new property here
font_size : 15
pos_hint_center_x : .5
pos_hint_center_y : .7
Then you can set that property like this:
LabelledSlider:
pos_hint : {'center_x': .5, 'center_y': .18}
property_text: "Brightness"
Upvotes: 1