Related
I want to make a launcher app which matches the windows 11 theme. i made the background and i want to make a button which would close the launcher, but the button does not work for some reason when i put it in a different class. i can put it in the same class but i want to learn this method as i would use it while making the app icons. the code it provided below.
from kivy.config import Config
from kivy.core.window import Window
from kivy.graphics import Rectangle
from kivy.graphics.context_instructions import Color
from kivy.properties import Clock
from kivy.uix.image import Image
import cv2
from kivy.uix.widget import Widget
Config.set('graphics', 'fullscreen', 'auto')
Config.set('graphics', 'borderless', 'true')
Config.set('graphics', 'window_state', 'maximized')
from kivy.app import App
import pyautogui
from kivy.uix.floatlayout import FloatLayout
theme = 'dark'
screen = 'main'
x_button_size = (100,100)
x_button_pos = (50,50)
class XButton(Image):
def __init__(self):
super().__init__(source='assets/images/bg_image.png')
class MainScreenWidget(FloatLayout):
bg = None
rectangle = None
def __init__(self, **kwargs):
super(MainScreenWidget, self).__init__(**kwargs)
Clock.schedule_interval(self.update, 1.0/60.0)
self.init_bg()
# x_button_size = (self.width , self.height )
self.x_button = XButton()
def init_bg(self):
with self.canvas.before:
self.bg = Image(source='assets/images/bg_image.png', size_hint=[1, 1])
if theme == 'light':
Color(0.9, .9, .9, 0.7)
elif theme == 'dark':
Color(0, 0, 0, 0.6)
self.rectangle = Rectangle(size=self.size)
pass
def update(self, dt):
self.update_bg()
self.update_x_button()
def update_bg(self):
self.bg.size = self.width, self.height
self.bg.pos_hint = {'center_x': self.width / 2, 'center_y': self.height / 2}
self.rectangle.size = self.size
pass
def update_x_button(self):
self.x_button.size = (Window.size[0], Window.size[1])
self.x_button.pos = (5, 5)
pass
class LauncherApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
bg_image = pyautogui.screenshot()
bg_image.save(r'assets/images/bg_image.png')
image = cv2.imread('assets/images/bg_image.png')
blurred_image = cv2.GaussianBlur(image, (75, 75), 0)
cv2.imwrite('assets/images/bg_image.png', blurred_image)
LauncherApp().run()
any recommendations for how to make the icons are also helpful
I am trying to add navigation in my kivy app using .py file but because the things I tried are not working and I am a complete beginner. I don't know what problem is occurring and I am not able to find any solutions on my own pls help me. I am trying to change the main screen from class Dre to class SecondWindow when the play button is clicked. BTW the things I already tried are tagged now. Pls give the solution in .py file because I am trying to do everything on it. Here is the code. Thanks
import kivy
from kivy.app import App
from kivy.core.audio import SoundLoader
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Rectangle
from kivy import platform
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
class MainWindow(Screen):
pass
#class ThirdWindow(ScreenManager):
# def load(self):
# sm = ScreenManager
# sm.add_widget(Dre(name='Dre'))
# sm.add_widget(SecondWindow(name='SecondWindow'))
# self.sm.current = 'Dre'
class Dre(RelativeLayout):
def __init__(self, **kwargs):
super(Dre, self).__init__(**kwargs)
self.color = [254/255, 102/255, 37/255, 1]
self.H_color = [254/255, 102/255, 37/255]
self.sound_theme = None
self.init_audio()
# self.kv = Builder.load_file('Levels.py')
# self.callback()
if platform in ('linux', 'win', 'macosx'):
with self.canvas.before:
self.bg = Rectangle(size=self.size, source='Neo.png')
self.bind(pos=self.update_bg)
self.bind(size=self.update_bg)
else:
with self.canvas.before:
self.bg = Rectangle(size=self.size, source='Neon.png')
self.bind(pos=self.update_bg)
self.bind(size=self.update_bg)
def update_bg(self, *args):
if platform in ('linux', 'win', 'macosx'):
self.bg.pos = self.pos
self.bg.size = self.size
self.add_widget(Label(text='D R E A M S',
pos_hint={'center_x': .5, 'center_y': .8},
font_size='60dp', font_name='Roboto-Bold.ttf', color=self.H_color))
B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
pos_hint={'center_x': .5, "center_y": .3}, background_color = self.color, background_normal='')
# B1.bind(on_press=return self.kv)
self.add_widget(B1)
else:
self.bg.pos = self.pos
self.bg.size = self.size
self.add_widget(Label(text='D R E A M S',
pos_hint={'center_x': .5, 'center_y': .8},
font_size='30dp', font_name='Roboto-Bold.ttf', color=self.H_color))
B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
pos_hint={'center_x': .5, "center_y": .3}, background_color=self.color, background_normal='',
on_press=self.callback)
self.add_widget(B1)
# def callback(self, instance):
# print('working')
# self.manager.current = 'SecondWindow'
def init_audio(self):
self.sound_theme = SoundLoader.load('Bg_theme.mp3')
self.sound_theme.volume = 1
self.sound_theme.loop = True
if self.sound_theme:
self.sound_theme.play()
print('okay')
else:
print('not okay')
class SecondWindow(Screen):
def __init__(self, **kwargs):
super(SecondWindow, self).__init__(**kwargs)
self.color = [254 / 255, 102 / 255, 37 / 255, 1]
if platform in ('linux', 'win', 'macosx'):
with self.canvas.before:
self.bg = Rectangle(size=self.size, color=self.color)
class LabApp(App):
def build(self):
return Dre()
if __name__ == '__main__':
LabApp().run()
Here's the correct code for that (at least for me):
import kivy
from kivy.app import App
from kivy.core.audio import SoundLoader
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Rectangle
from kivy import platform
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
class SM(ScreenManager):
pass
class MainWindow(Screen, RelativeLayout):
def __init__(self, **kwargs):
super(MainWindow, self).__init__(**kwargs)
self.color = [254/255, 102/255, 37/255, 1]
self.H_color = [254/255, 102/255, 37/255]
self.sound_theme = None
self.init_audio()
# self.kv = Builder.load_file('Levels.py')
# self.callback()
if platform in ('linux', 'win', 'macosx'):
with self.canvas.before:
self.bg = Rectangle(size=self.size, source='Neo.png')
self.bind(pos=self.update_bg)
self.bind(size=self.update_bg)
else:
with self.canvas.before:
self.bg = Rectangle(size=self.size, source='Neon.png')
self.bind(pos=self.update_bg)
self.bind(size=self.update_bg)
def bruh(self):
App.get_running_app().root.current = 'SecondWindow'
def update_bg(self, *args):
if platform in ('linux', 'win', 'macosx'):
self.bg.pos = self.pos
self.bg.size = self.size
self.add_widget(Label(text='D R E A M S',
pos_hint={'center_x': .5, 'center_y': .8},
font_size='60dp', font_name='Roboto-Bold.ttf', color=self.H_color))
B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
pos_hint={'center_x': .5, "center_y": .3}, background_color = self.color, background_normal='', on_press= lambda x: self.bruh())
# B1.bind(on_press=return self.kv)
self.add_widget(B1)
else:
self.bg.pos = self.pos
self.bg.size = self.size
self.add_widget(Label(text='D R E A M S',
pos_hint={'center_x': .5, 'center_y': .8},
font_size='30dp', font_name='Roboto-Bold.ttf', color=self.H_color))
B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
pos_hint={'center_x': .5, "center_y": .3}, background_color=self.color, background_normal='',
on_press=self.callback)
self.add_widget(B1)
# def callback(self, instance):
# print('working')
# self.manager.current = 'SecondWindow'
def init_audio(self):
self.sound_theme = SoundLoader.load('Bg_theme.mp3')
self.sound_theme.volume = 1
self.sound_theme.loop = True
if self.sound_theme:
self.sound_theme.play()
print('okay')
else:
print('not okay')
class SecondWindow(Screen):
def __init__(self, **kwargs):
super(SecondWindow, self).__init__(**kwargs)
self.color = [254 / 255, 102 / 255, 37 / 255, 1]
if platform in ('linux', 'win', 'macosx'):
with self.canvas.before:
self.bg = Rectangle(size=self.size, color=self.color)
class LabApp(App):
def build(self):
sm = SM()
sm.add_widget(MainWindow(name='MainWindow'))
sm.add_widget(SecondWindow(name='SecondWindow'))
return sm
if __name__ == '__main__':
LabApp().run()
The main changes here are the fact that the build method for LabApp is required, since the .kv file isn't used; to also inherit the Screen class into the MainWindow class, which is renamed from Dre for less confusing code, since it is essential forScreenManager; and the bruh method in the MainWindow (im not good at naming ok dont roast me) that changes to the SecondWindow screen when the B1 button's on_press event is called. Sorry for the confusing English but at least it's understandable(?) ig
So, I want that my buttons call a function when released, so that my labels come up visible.
As you can see the button's on_release is set to buttonPress where I wanted to do this, but whichever button I press it passes the last label into the function. How can I fix this? Is there a better way to do this?
def buttonPress(self, label):
print("hi")
print(label)
label.height = '50dp'
label.font_size = '20sp'
def on_pre_enter(self, *args):
mainLayout = RelativeLayout()
self.add_widget(mainLayout)
scroll = ScrollView(do_scroll_x = False,pos_hint={"top":0.8,"center_x":0.75})
infoLayout = GridLayout(cols = 1, size_hint = (0.5, None))
mainLayout.add_widget(scroll)
scroll.add_widget(infoLayout)
files = glob.glob("user/*.txt")
InfoWidgetButtonArray = []
InfoWidgetLabelArray = []
for x in range(len(files)):
InfoWidgetLabelArray.append(Label(text="hello mate", size_hint_y=None,height = '0dp', font_size='0sp', color = (0, 0, 0, 1), id=str(x)))
print(InfoWidgetLabelArray[x])
InfoWidgetButtonArray.append(Button(text=files[x][5:][:-4], font_size=14, size_hint=(0.5, None), height=30,on_release=lambda lambdaFunction: self.buttonPress(InfoWidgetLabelArray[x])))
infoLayout.add_widget(InfoWidgetButtonArray[x])
infoLayout.add_widget(InfoWidgetLabelArray[x])
Here is a minimal reproducible example:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.uix.widget import Widget
Window.clearcolor = (1,1,1,1)
class InfoScreen(Screen, Widget):
new = True
def buttonPress(self, label):
print("hi")
print(label)
label.height = '50dp'
label.font_size = '20sp'
def on_pre_enter(self, *args):
mainLayout = RelativeLayout()
self.add_widget(mainLayout)
scroll = ScrollView(do_scroll_x = False,pos_hint={"top":0.8,"center_x":0.75})
infoLayout = GridLayout(cols = 1, size_hint = (0.5, None))
mainLayout.add_widget(scroll)
scroll.add_widget(infoLayout)
InfoWidgetButtonArray = []
InfoWidgetLabelArray = []
for x in range(2):
InfoWidgetLabelArray.append(Label(text="hello mate", size_hint_y=None,height = '0dp', font_size='0sp', color = (0, 0, 0, 1), id=str(x)))
print(InfoWidgetLabelArray[x])
InfoWidgetButtonArray.append(Button(text="name"+str(x), font_size=14, size_hint=(0.5, None), height=30,on_release=lambda lambdaFunction: self.buttonPress(InfoWidgetLabelArray[x])))
infoLayout.add_widget(InfoWidgetButtonArray[x])
infoLayout.add_widget(InfoWidgetLabelArray[x])
SpacingButton = Button(text='Hello world', font_size=14, size_hint=(0.5, None), height=50, color=(0, 0, 0, 0), background_color=(0,0,0,0))
infoLayout.add_widget(SpacingButton)
infoLayout.bind(minimum_height=infoLayout.setter('height'))
sm = ScreenManager()
sm.add_widget(InfoScreen(name='Info'))
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
I think you're looking for the partial function from the functools module. It binds the input in your for loop and returns the actual function you want it to have.
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.properties import StringProperty
from functools import partial #Changed This
Window.clearcolor = (1,1,1,1)
class InfoScreen(Screen, Widget):
new = True
def buttonPress(self, label, *args):
print("hi")
print(label)
label.height = '50dp'
label.font_size = '20sp'
def on_pre_enter(self, *args):
mainLayout = RelativeLayout()
self.add_widget(mainLayout)
scroll = ScrollView(do_scroll_x = False, pos_hint={"top":0.8,"center_x":0.75}, size_hint_max_y=300) #To enable scrolling be sure to set a maximal value, or have enough buttons to cover the whole window
infoLayout = GridLayout(cols = 1, size_hint = (0.5, None))
mainLayout.add_widget(scroll)
scroll.add_widget(infoLayout)
InfoWidgetButtonArray = []
InfoWidgetLabelArray = []
for x in range(5):
InfoWidgetLabelArray.append(Label(text="hello mate", size_hint_y=None,height = '0dp', font_size='0sp', color = (0, 0, 0, 1), id=str(x)))
print(InfoWidgetLabelArray[x])
InfoWidgetButtonArray.append(Button(text="name"+str(x), font_size=14, size_hint=(0.5, None), height=30, on_release=partial(self.buttonPress, InfoWidgetLabelArray[x]))) #Changed This
infoLayout.add_widget(InfoWidgetButtonArray[x])
infoLayout.add_widget(InfoWidgetLabelArray[x])
SpacingButton = Button(text='Hello world', font_size=14, size_hint=(0.5, None), height=50, color=(0, 0, 0, 0), background_color=(0,0,0,0))
infoLayout.add_widget(SpacingButton)
infoLayout.bind(minimum_height=infoLayout.setter('height'))
sm = ScreenManager()
sm.add_widget(InfoScreen(name='Info'))
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
Hope this is what you were looking for, I spent some time rereading the question before I hopefully understood.
[Here i have pasted my Code in GitHub Kindly Look Into it]
{ https://github.com/BollamReddy-Python-Vba/python/commit/710bd80f649968cd19181e0abda21f5164e8ba9f}
import kivy
kivy.require('1.10.0')
from kivy.core.window import Window
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.base import runTouchApp
from kivy.uix.label import Label
from kivy.graphics import Color, Rectangle
from kivy.uix.textinput import TextInput
from kivy.uix.spinner import Spinner
from kivy.uix.checkbox import CheckBox
Window.size = (500, 400)
Window.clearcolor = (0.1, 0.1, 0.3, 0.2)
def show_selected_value(spinner, text):
print('Selected Process', spinner, 'have text', text)
class LRefConfigAutomation(App):
config = None
def build_config(self, config):
config.setdefaults('LefConfigWindowSection', {
'PartInputLabel': 'Please Enter your Part No',
'TypeOfProcessLabel': 'Select Type Of Process',
'NormalFolderName': 'Enter Normal Folder Name',
})
self.config = config
def build(self):
config = self.config
root = FloatLayout()
lbl = config.get('LefConfigWindowSection', 'PartInputLabel')
self.label = Label(text=lbl, pos_hint={"center_x": .66, "center_y": .90}, size_hint=(1.0, 1.0), halign="left",valign="middle", font_name='Georgia')
self.label.bind(size=self.label.setter('text_size'))
self.label.font_size = '14.5dp' # something that'll give texture bigger than phone's screen size
root.add_widget(self.label)
with self.label.canvas:
Color(0, 0, 0, 0)
Rectangle(pos=self.label.pos, size=self.label.size)
self.txtKemNo = TextInput(pos_hint={"center_x": .66, "center_y": .90}, size_hint=(None, None),font_name="Georgia", size=(100, 30), multiline=False, hint_text="Part Number")
root.add_widget(self.txtKemNo)
lbl = config.get('LefConfigWindowSection', 'TypeOfProcessLabel')
self.label = Label(text=lbl, pos_hint={"center_x": .66, "center_y": .75}, size_hint=(1.0, 1.0), halign="left",valign="middle", font_name='Georgia')
self.label.bind(size=self.label.setter('text_size'))
self.label.font_size = '14.5dp' # something that'll give texture bigger than phone's screen size
root.add_widget(self.label)
with self.label.canvas:
Color(0, 0, 0, 0)
Rectangle(pos=self.label.pos, size=self.label.size)
self.requestsspinner = Spinner(
# default value shown
text='Select Process',
# available values will be binded to the combo
values=("Normal", "Official"),
# just for positioning in our example
size_hint=(None, None),
size=(110, 20),
pos_hint={'center_x': .66, 'center_y': .75}, font_name='Georgia')
self.requestsspinner.font_size = '14.5dp'
self.requestsspinner.bind(text=show_selected_value)
self.requestsspinner.bind(on_click=self.CreateLable)
root.add_widget(self.requestsspinner)
runTouchApp(root)
def CreateLable(self, spinner, text):
root = FloatLayout()
print(text)
if text == "Normal":
pass
elif text == "Official":
config = self.config
lbl = config.get('LefConfigWindowSection', 'NormalFolderName')
print(lbl)
self.label = Label(text=lbl, pos_hint={"center_x": .66, "center_y": .65}, size_hint=(1.0, 1.0),halign="left",valign="middle", font_name='Georgia')
self.label.bind(size=self.label.setter('text_size'))
self.label.font_size = '14.5dp'
root.add_widget(self.label)
with self.label.canvas:
Color(0, 0, 0, 0)
Rectangle(pos=self.label.pos, size=self.label.size)
if __name__ == "__main__":
LRefConfigAutomation().run()
There are three problems. First, your build() method is not returning the root (which is what it is intended to do). Remove the line:
runTouchApp(root)
and replace it with:
return root
Second, your CreateLable() is not being called. I suggest changing:
self.requestsspinner.bind(on_click=self.CreateLable)
to:
self.requestsspinner.bind(text=self.CreateLable)
The third problem is that in CreateLable() you are not adding the new Label to the display. The root that you create in that method has no relation to the root of your display. I suggest changing that method to:
def CreateLable(self, spinner, text):
if text == "Normal":
pass
elif text == "Official":
config = self.config
lbl = config.get('LefConfigWindowSection', 'NormalFolderName')
self.label = Label(text=lbl, pos_hint={"center_x": .66, "center_y": .65}, size_hint=(1.0, 1.0),halign="left",valign="middle", font_name='Georgia')
self.label.bind(size=self.label.setter('text_size'))
self.label.font_size = '14.5dp'
self.root.add_widget(self.label) # add label to the GUI
with self.label.canvas:
Color(0, 0, 0, 0)
Rectangle(pos=self.label.pos, size=self.label.size)
You might want to delete the canvas instructions at the end of the above method. It is creating an invisible Rectangle at the bottom left od your display. The pos and size of the new Label are still at the default values of (0,0) and (100,100) at that point, so that is where the Rectangle is drawn, and where it will stay.
Here is the entire code:
import kivy
kivy.require('1.10.0')
from kivy.core.window import Window
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.graphics import Color, Rectangle
from kivy.uix.textinput import TextInput
from kivy.uix.spinner import Spinner
Window.size = (500, 400)
Window.clearcolor = (0.1, 0.1, 0.3, 0.2)
def show_selected_value(spinner, text):
print('Selected Process', spinner, 'have text', text)
class LRefConfigAutomation(App):
config = None
def build_config(self, config):
config.setdefaults('LefConfigWindowSection', {
'PartInputLabel': 'Please Enter your Part No',
'TypeOfProcessLabel': 'Select Type Of Process',
'NormalFolderName': 'Enter Normal Folder Name',
})
self.config = config
def build(self):
config = self.config
root = FloatLayout()
lbl = config.get('LefConfigWindowSection', 'PartInputLabel')
self.label = Label(text=lbl, pos_hint={"center_x": .66, "center_y": .90}, size_hint=(1.0, 1.0), halign="left",valign="middle", font_name='Georgia')
self.label.bind(size=self.label.setter('text_size'))
self.label.font_size = '14.5dp' # something that'll give texture bigger than phone's screen size
root.add_widget(self.label)
with self.label.canvas:
Color(0, 0, 0, 0)
Rectangle(pos=self.label.pos, size=self.label.size)
self.txtKemNo = TextInput(pos_hint={"center_x": .66, "center_y": .90}, size_hint=(None, None),font_name="Georgia", size=(100, 30), multiline=False, hint_text="Part Number")
root.add_widget(self.txtKemNo)
lbl = config.get('LefConfigWindowSection', 'TypeOfProcessLabel')
self.label = Label(text=lbl, pos_hint={"center_x": .66, "center_y": .75}, size_hint=(1.0, 1.0), halign="left",valign="middle", font_name='Georgia')
self.label.bind(size=self.label.setter('text_size'))
self.label.font_size = '14.5dp' # something that'll give texture bigger than phone's screen size
root.add_widget(self.label)
with self.label.canvas:
Color(0, 0, 0, 0)
Rectangle(pos=self.label.pos, size=self.label.size)
self.requestsspinner = Spinner(
# default value shown
text='Select Process',
# available values will be binded to the combo
values=("Normal", "Official"),
# just for positioning in our example
size_hint=(None, None),
size=(110, 20),
pos_hint={'center_x': .66, 'center_y': .75}, font_name='Georgia')
self.requestsspinner.font_size = '14.5dp'
self.requestsspinner.bind(text=show_selected_value)
self.requestsspinner.bind(text=self.CreateLable)
root.add_widget(self.requestsspinner)
return root
def CreateLable(self, spinner, text):
if text == "Normal":
pass
elif text == "Official":
config = self.config
lbl = config.get('LefConfigWindowSection', 'NormalFolderName')
self.label = Label(text=lbl, pos_hint={"center_x": .66, "center_y": .65}, size_hint=(1.0, 1.0),halign="left",valign="middle", font_name='Georgia')
self.label.bind(size=self.label.setter('text_size'))
self.label.font_size = '14.5dp'
self.root.add_widget(self.label)
if __name__ == "__main__":
LRefConfigAutomation().run()
I want to draw multi-box on a image. How to chage the parameters of the box pos, size and lable in a LineRectangle class in python kivy?
class LineRectangle(Widget):
def __init__(self, **kwargs):
super(LineRectangle, self).__init__(**kwargs)
with self.canvas:
Color(1, 0, 0, 1)
self.line = Line(width=2, rectangle=(self.x, self.y, self.width, self.height))
self.label = Label(text='Rectangle', pos=(self.x, self.y), size=(10, 10))
class LineExtendedApp(App):
def build(self):
root = FloatLayout()
image = Image(source='000001.jpg', allow_stretch=False, keep_ratio=True)
root.add_widget(image)
bbox1 = LineRectangle()
bbox1.line = Line(width=1, rectangle=(100, 100, 100, 100))
bbox1.label = Label(text='bbox1', pos=(100, 100), size=(10, 10))
bbox2 = LineRectangle()
bbox2.line = Line(width=1, rectangle=(300, 300, 100, 100))
bbox2.label = Label(text='bbox1', pos=(300, 300), size=(10, 10))
root.add_widget(bbox1)
root.add_widget(bbox2)
return root
if __name__ == '__main__':
LineExtendedApp().run()
You can create Properties for the parameters that you want to be able to change. Then use a kv rule to create bindings (so that changes to a Property are automatically shown in your display). Here is an example of how to do that:
from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.properties import ListProperty, NumericProperty, StringProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.uix.widget import Widget
class LineRectangle(Widget):
line_color = ListProperty([])
line_rect = ListProperty([])
line_width = NumericProperty()
label_text = StringProperty('')
label_pos = ListProperty([])
def __init__(self, **kwargs):
self.line_color = kwargs.pop('line_color', [1,1,1,1])
self.line_rect = kwargs.pop('line_rect', [0,0,50,50])
self.line_width = kwargs.pop('line_width', 1)
self.label_text = kwargs.pop('label_text', 'text')
self.label_pos = kwargs.pop('label_pos', [0,0])
super(LineRectangle, self).__init__()
Builder.load_string('''
<LineRectangle>:
canvas:
Color:
rgba: root.line_color
Line:
width: root.line_width
rectangle: root.line_rect
Label:
text: root.label_text
pos: root.label_pos
size: 10, 10
''')
class LineExtendedApp(App):
def build(self):
root = FloatLayout()
image = Image(source='000001.jpg', allow_stretch=False, keep_ratio=True)
root.add_widget(image)
self.bbox1 = LineRectangle(line_wdth=2, line_rect=[100, 100, 100, 100], line_color=[1,0,0,1], label_text='bbox1', label_pos=[100, 100])
bbox2 = LineRectangle(line_width=1, line_rect=[300, 300, 300, 300], line_color=[0,1,0,1], label_text='bbox2', label_pos=[300, 300])
root.add_widget(self.bbox1)
root.add_widget(bbox2)
Clock.schedule_once(self.adjust, 2) # just to demonstrate change parameter
return root
def adjust(self, dt):
self.bbox1.line_width = 10
if __name__ == '__main__':
LineExtendedApp().run()