I want to add a few text fields defined by a user to an image and export is as one .png file.
I thought of just making screenshot of whole widget but that's low quality and it's not what I'm realling looking into.
For now I have code:
kv = '''
PageLayout:
orientation: 'vertical'
RelativeLayout:
Image:
pos:10,10
id: template
source: 'template.png'
Label:
pos: 50,50
markup: True
text: 'Test'
BoxLayout:
Button:
text: 'Configure'
on_release: app.open_settings()
Button:
id: savebtn
text: 'Save'
on_release: app.sc()
'''
And is it better to write it in kv language or python?
Thanks for any input!
Related
I am building a simple Kivy app with a couple of screens. The first screen has a couple of buttons which, when clicked, move to the second screen. The second screen has a text input widget and a button inside a Float Layout. The layout is loaded as a root widget by an explicit call to the kv file through Builder.
Everything was working fine and I added a 'focus: True' tag in the text input attributes. The app worked fine and I could type in the text input field with focus set as True. However, the text input field suddenly stopped working without any change in code or layout. I was not sure and searched Google for a couple of probable solutions, none of which worked:
Removed the 'focus: True' attribute and reloaded the app but the text input field still did not respond. I was unable to type anything from my keyboard.
Another post pointed out that the kv file was being loaded twice resulting in erratic behaviour. I tried to remove the explicit Builder file call and returned the root widget (Screen Manager) in the main code. However, it messed up my entire app and only showed a black empty screen.
Can you please advise as to what I may be doing wrong? The code is provided below:
Python Code:
from kivy.config import Config
Config.set('kivy','window_icon','sivaicon.png')
Config.set('graphics', 'resizable', True)
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.lang.builder import Builder
class SivaLoginScreen(Screen):
def twitter_authentication(self):
App.get_running_app().root.current='verify_screen'
def linkedin_authentication(self):
App.get_running_app().root.current='verify_screen'
class SivaVerifyScreen(Screen):
pass
class SivaTabbedScreen(Screen):
pass
class SivaScreenManager(ScreenManager):
pass
class ImageButton(ButtonBehavior, Image):
pass
# Tell Kivy to directly load a file. If this file defines a root widget, it will be returned by the method.
root_widget = Builder.load_file('siva.kv')
class SivaApp(App):
def build(self):
# Initialize root widget
return root_widget
if __name__ == '__main__':
# Run application
SivaApp().run()
kv file:
SivaScreenManager:
SivaLoginScreen:
SivaVerifyScreen:
SivaTabbedScreen:
<ImageButton>:
keep_ratio: True
<SivaLoginScreen>:
name: 'login_screen'
canvas.before:
Color:
rgba: 195/255, 60/255, 35/255, 1
Rectangle:
pos: self.pos
size: self.size
FloatLayout:
size: root.width, root.height
Image:
id: login_logo_siva
source: 'images/sivalogo1.png'
keep_ratio: True
size_hint: 0.3, 0.3
pos_hint: {'center_x':0.5, 'center_y':0.75}
Label:
id: login_label_siva
pos: self.x*0.5-4, self.y*0.5+15
markup: True
font_name: 'roboto/Roboto-Medium.ttf'
text: '[color=#FDFD98]S.[/color][color=#B29DD9]I[/color][color=#FDFD98].[/color][color=#77DD77]V[/color][color=#FDFD98].[/color][color=#779ECB]A[/color]'
font_size: '40sp'
Label:
id: login_label_slogan1
pos: self.x*0.5-3, self.y*0.5-6
markup: True
font_name: 'roboto/Roboto-Regular.ttf'
text: '[color=#FDFD98]SLOGAN TEXT[/color]'
font_size: '13sp'
Label:
id: login_label_slogan2
pos: self.x*0.5-3, self.y*0.5-20
markup: True
font_name: 'roboto/Roboto-Regular.ttf'
text: '[color=#FDFD98]HEADLINE TEXT[/color]'
font_size: '13sp'
BoxLayout:
id:login_button_layout
orientation: 'horizontal'
size_hint: 0.2, 0.2
pos_hint: {'center_x':0.5, 'center_y':0.25}
ImageButton:
id: twitter_button
source: {'normal': 'images/twitter-96.png', 'down': 'images/twitter-96.png'} [self.state]
on_release: root.twitter_authentication()
ImageButton:
id: linkedin_button
source: {'normal': 'images/linkedin-96.png', 'down': 'images/linkedin-96.png'} [self.state]
on_release: root.linkedin_authentication()
<SivaVerifyScreen>:
name: 'verify_screen'
canvas.before:
Color:
rgba: 195/255, 60/255, 35/255, 1
Rectangle:
pos: self.pos
size: self.size
FloatLayout:
size: root.width, root.height
Label:
id: verify_label
markup: True
font_name: 'roboto/Roboto-Regular.ttf'
text: 'Paste the verification code'
font_size: '16sp'
pos_hint: {'center_x':0.5, 'center_y':0.7}
size_hint: 1, 0.4
TextInput:
id: verify_input
multiline: False
font_size: '30sp'
pos_hint: {'center_x':0.5, 'center_y':0.55}
size_hint: 0.5, 0.1
ImageButton:
id: verify_button
source: {'normal': 'images/lock-96.png', 'down': 'images/lock-96.png'} [self.state]
pos_hint: {'center_x':0.5, 'center_y':0.35}
size_hint: 0.5, 0.5
<SivaTabbedScreen>:
name: 'tabbed_screen'
FloatLayout:
size: root.width, root.height
Label:
pos: self.x*0.5, self.y*0.5
text: 'SECOND SCREEN'
font_size: '50sp'
Please advise. I am helplessly stuck. :(
Thanks in advance
Okay so this was the problem: Some of my widgets were overlapping each other thereby rendering the widgets underneath as unresponsive. In my case, a button widget was overlapping my textinput widget due to which I was unable to enter text in the textinput widget.
I used the Kivy inspector tool to identify the extent of the widgets' dimensions:
python3 main.py -m inspector
Use Ctrl+e to launch the inspector while the app is running and click on each widget to check its size, position and parent. I reduced the button widget's size and converted the float layout into a stacked box layout and this resolved the issue.
Assuming I have a layout written in kv and I define a BoxLayout with an id value, how would I later add more widgets into this layout without Kv language? I could do this in python, but I feel like it would be more efficient to do this in Kv language.
Here is some example code (Note: Widgets is a BoxLayout):
<Content#BoxLayout>:
orientation: 'vertical'
Button:
text: 'Test'
BoxLayout:
id: to_change
orientation: 'horizontal'
Button:
text: 'Button 1'
<Widgets>:
orientation: 'vertical'
Content:
# How would I add this button to the layout called "to_change"?
to_change:
Button:
text: 'Button 2'
I have a widget that I defined in Kv language, which exists within a layout that I also defined in Kv language. I would like to change the text of the widget in the layout in Kv. How would I go about is?
Python code:
import kivy
kivy.require('1.11.1')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
class Test(BoxLayout):
pass
class KivyTestApp(App):
def build(self):
return Test()
app = KivyTestApp()
app.run()
Kv code:
<Header#BoxLayout>:
orientation: 'horizontal'
size_hint_y: 0.2
Button:
text: 'Button 1'
Button:
id: edit_but
<Test>:
orientation: 'vertical'
Header:
edit_but.text: 'Button 2'
# How do I do this ^ ?
Label:
text: 'Filler'
In your kv, you can add a Property to your Header rule (I named it edit_text). That property can be used to set the text of the Button by using text: root.edit_text. That Property can be set whenever you use the Header in kv as edit_text: 'Button 2':
<Header#BoxLayout>:
orientation: 'horizontal'
size_hint_y: 0.2
edit_text: ''
Button:
text: 'Button 1'
Button:
id: edit_but
text: root.edit_text
<Test>:
orientation: 'vertical'
Header:
edit_text: 'Button 2'
# How do I do this ^ ?
Label:
text: 'Filler'
I get:
AttributeError: 'Carousel' object has no attribute 'switch_on'
error whenever I try to click on the button
-------main.py----------
class main(App):
def build(self):
class SampBoxLayout(BoxLayout):
# For Switch
def switch_on(self, instance, value):
if value is True:
print("Switch On")
else:
print("Switch Off")
return Carousel()
sample_app = kv_main()
sample_app.run()
----------main.kv--------------
:
Label:
text: "Page 1"
size_hint: 1, .1
width :100
SampBoxLayout:
# ----------Switch ----------
BoxLayout:
BoxLayout:
orientation: "horizontal"
size_hint_x: .25
CustLabel:
text: "On / Off"
Switch:
id: switch_id
on_active: root.switch_on(self, self.active)# <--need help on this
Label:
text: "Page 2"
size_hint: 1, .1
width :100
Button:
text: "Button 2.1"
size_hint: None, None
width :100
Label:
text: "Page 3"
size_hint: 1, .1
width :100
Button:
text: "Button 3.1"
size_hint: None, None
width :100
You are using root.switch_on. As the error indicates, your root class is the carousel. Since SampBoxLayout is not root, you should give SampBoxLayout an id, and call it with it´s id.
Edited from your example:
SampBoxLayout:
id: samp
BoxLayout:
BoxLayout:
orientation: "horizontal"
size_hint_x: .25
CustLabel:
text: "On / Off"
Switch:
id: switch_id
on_active: samp.switch_on(self, self.active)
I don't know if you did something wrong when posting this, or if your code really looks like this. But you should not define classes inside your app class. Keep the classes on top level to access them in kv.
And your kv code is unusual. You have your widgets in a label.
I'm in the process of converting an application from pure Python, to using kivy for screen handling. I'm a kivy newbie!
I'm attempting to replicate a screen which displays current date and time, on two lines, with different sizes for the two lines. I use two different [size=?] markups in the string to be displayed, but the two lines are always displayed at the same size (the second size specified) - how can I get them to be different sizes?
I have seen suggestions that this could be achieved using html, but fear that would be horribly inefficient.
Code is:
<C>:
BoxLayout:
orientation: 'vertical'
BoxLayout:
Button:
text:
'[size=48]' + app.date + '[/size]' + \
'\n[size=96]' + app.time + '[/size]'
background_color: (0, 0, 0, 0)
halign: 'center'
markup: True
on_press: app.stop()
Status:
id: stat
I used your code and the lines had a different font size. Therefore the problem must be outside of the code you provided.
py:
from kivy.app import App
from kivy.properties import StringProperty
class MyApp(App):
date = StringProperty('2017-09-30')
time = StringProperty('Now')
if __name__ == '__main__':
MyApp().run()
kv:
BoxLayout:
orientation: 'vertical'
BoxLayout:
Button:
text:
'[size=48]' + app.date + '[/size]' + \
'\n[size=200]' + app.time + '[/size]'
background_color: (0, 0, 0, 0)
halign: 'center'
markup: True
on_press: app.stop()
Alternatively, you can use the following kv-file:
Button:
on_press: app.stop()
BoxLayout:
pos: self.parent.pos
size: self.parent.size
orientation: 'vertical'
Label:
text: app.date
font_size: 48
Label:
text: app.time
font_size: 96
To generate sth which also behaves more like a button in kv, changes the background on press.