mirror of https://github.com/kivy/kivy.git
Merge pull request #746 from buchuki/master
Revised example Kivy script
This commit is contained in:
commit
29bae666e2
Binary file not shown.
|
@ -0,0 +1,18 @@
|
|||
This is the Kivy Catalog viewer. It serves two purposes:
|
||||
|
||||
1. To showcase the various widgets available in Kivy
|
||||
2. To allow interactive editing of Kivy language files
|
||||
to get immediate feedback as to how they work
|
||||
|
||||
To use it, you'll need to install Kivy and it's dependencies
|
||||
a la http://kivy.org/docs/installation/installation.html Then run
|
||||
python main.py and browse or edit widgets to your heart's content.
|
||||
|
||||
Known bugs:
|
||||
* The DropDown item I had tested completely crashes Kivy
|
||||
* The GridLayout example could use some extra features
|
||||
* If you try to start the app with focused set to true, weird stuff happens.
|
||||
but it works fine if you set focused to true and press render.
|
||||
* Video playback doesn't work for me, but this may be a dependency issue
|
||||
* Popups are displayed inline
|
||||
* Some widgets are still missing
|
|
@ -0,0 +1,15 @@
|
|||
#:kivy 1.4
|
||||
|
||||
AnchorLayout:
|
||||
anchor_x: "right"
|
||||
anchor_y: "bottom"
|
||||
Button:
|
||||
text: "Button 1"
|
||||
size_hint: .2, .4
|
||||
Button:
|
||||
text: "Button 2"
|
||||
size_hint: .4, .2
|
||||
|
||||
Button:
|
||||
text: "Button 3"
|
||||
size_hint: .2, .2
|
|
@ -0,0 +1,14 @@
|
|||
#:kivy 1.4
|
||||
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
padding: 20
|
||||
spacing: 10
|
||||
Button:
|
||||
text: "Button 1"
|
||||
size_hint: 1, None
|
||||
Button:
|
||||
text: "Button 2"
|
||||
size_hint: 1, 0.5
|
||||
Button:
|
||||
text: "Button 3"
|
|
@ -0,0 +1,27 @@
|
|||
#:kivy 1.4
|
||||
|
||||
GridLayout:
|
||||
cols: 2
|
||||
Button:
|
||||
text: "Button 1"
|
||||
Button:
|
||||
text: "Button 2"
|
||||
font_size: 24
|
||||
Button:
|
||||
text: "Button 3"
|
||||
background_color: .7, .7, 1, 1
|
||||
Button:
|
||||
text: "Button 4"
|
||||
on_press: self.text = 'pressed'
|
||||
on_release: self.text = 'Button 4'
|
||||
ToggleButton:
|
||||
text: "A toggle button"
|
||||
ToggleButton:
|
||||
text: "a toggle button in a group"
|
||||
group: "money"
|
||||
ToggleButton:
|
||||
text: "A toggle in the down state"
|
||||
state: "down"
|
||||
ToggleButton:
|
||||
text: "another toggle button in a group"
|
||||
group: "money"
|
|
@ -0,0 +1,27 @@
|
|||
#:kivy 1.4
|
||||
|
||||
GridLayout:
|
||||
cols: 2
|
||||
CheckBox:
|
||||
Label:
|
||||
text: "A checkbox"
|
||||
active: True
|
||||
CheckBox:
|
||||
Label:
|
||||
text: "Another checkbox"
|
||||
CheckBox:
|
||||
group: "money"
|
||||
Label:
|
||||
text: "A radio in a group"
|
||||
CheckBox:
|
||||
group: "money"
|
||||
Label:
|
||||
text: "Another radio in same group"
|
||||
active: True
|
||||
Switch:
|
||||
Label:
|
||||
text: "A Switch"
|
||||
Switch:
|
||||
active: True
|
||||
Label:
|
||||
text: "An active switch"
|
|
@ -0,0 +1,19 @@
|
|||
#:kivy 1.4
|
||||
|
||||
BoxLayout:
|
||||
# Double as a Tabbed Panel Demo!
|
||||
TabbedPanel:
|
||||
tab_pos: "top_right"
|
||||
default_tab_text: "List View"
|
||||
default_tab_content: list_view_tab
|
||||
|
||||
TabbedPanelHeader:
|
||||
text: 'Icon View'
|
||||
content: icon_view_tab
|
||||
|
||||
FileChooserListView:
|
||||
id: list_view_tab
|
||||
|
||||
FileChooserIconView:
|
||||
id: icon_view_tab
|
||||
show_hidden: True
|
|
@ -0,0 +1,16 @@
|
|||
#:kivy 1.4
|
||||
|
||||
FloatLayout:
|
||||
Button:
|
||||
text: "Button 1"
|
||||
pos: 100, 100
|
||||
size_hint: .2, .4
|
||||
Button:
|
||||
text: "Button 2"
|
||||
pos: 200, 200
|
||||
size_hint: .4, .2
|
||||
|
||||
Button:
|
||||
text: "Button 3"
|
||||
pos_hint: {'x': .8, 'y': .6}
|
||||
size_hint: .2, .2
|
|
@ -0,0 +1,20 @@
|
|||
#:kivy 1.4
|
||||
|
||||
GridLayout:
|
||||
cols: 2
|
||||
Button:
|
||||
text: "Button 1"
|
||||
size_hint_x: None
|
||||
width: 100
|
||||
Button:
|
||||
text: "Button 2"
|
||||
Button:
|
||||
text: "Button 3"
|
||||
size_hint_x: None
|
||||
Button:
|
||||
text: "Button 4"
|
||||
Button:
|
||||
text: "Button 5"
|
||||
Button:
|
||||
text: "Button 6"
|
||||
size_hint_x: None
|
|
@ -0,0 +1,21 @@
|
|||
#:kivy 1.4
|
||||
|
||||
GridLayout:
|
||||
rows: 2
|
||||
Label:
|
||||
text: "Label 1"
|
||||
Label:
|
||||
text: "Label with\nmultiple lines"
|
||||
Label:
|
||||
text: "Label [color=ff3333]with[/color] [color=3333ff][b]markup[/b][/color]"
|
||||
markup: True
|
||||
Label:
|
||||
text: "Label with [ref=reference]reference[/ref]"
|
||||
markup: True
|
||||
on_ref_press: self.text = "ref clicked"
|
||||
Label:
|
||||
text: "different font"
|
||||
bold: True
|
||||
font_name: "DroidSansMono.ttf"
|
||||
font_size: 32
|
||||
valign: "bottom"
|
|
@ -0,0 +1,9 @@
|
|||
#:kivy 1.4
|
||||
|
||||
BoxLayout:
|
||||
orientation: "vertical"
|
||||
Image:
|
||||
source: "../../widgets/softboy.png"
|
||||
Video:
|
||||
source: "../../widgets/softboy.avi"
|
||||
state: "play"
|
|
@ -0,0 +1,6 @@
|
|||
#:kivy 1.4
|
||||
|
||||
Label:
|
||||
text_size: self.width-60, self.height-60
|
||||
valign: "middle"
|
||||
text: "The Kivy Catalog is an interactive showcase of Kivy Widgets defined in the Kivy language. For each widget you see, you can directly edit the .kv language syntax to see what effects your changes have on the widget. Click 'Render' or hit 'Ctrl-S' to view your changes.\n\nThere is also a playground on this tab where you can test your Kivy language code directly. This is beta software. The basics seem to work, but some widgets are missing or don't have the ideal .kv representation. Not all widgets are represented yet. It is trivial to add a new .kv file to the interface.\n\nPull requests are welcome."
|
|
@ -0,0 +1,23 @@
|
|||
#:kivy 1.4
|
||||
|
||||
BoxLayout:
|
||||
orientation: "vertical"
|
||||
Bubble:
|
||||
size_hint: (None, None)
|
||||
size: (150, 50)
|
||||
pos_hint: {'center_x': .5, 'y': .6}
|
||||
arrow_pos: 'bottom_mid'
|
||||
orientation: 'horizontal'
|
||||
BubbleButton:
|
||||
text: 'Click'
|
||||
BubbleButton:
|
||||
text: 'A'
|
||||
BubbleButton:
|
||||
text: 'Bubble'
|
||||
Popup:
|
||||
id: popup
|
||||
title: "An example popup"
|
||||
content: popupcontent
|
||||
Label:
|
||||
id: popupcontent
|
||||
text: "Some text\nin the popup"
|
|
@ -0,0 +1,17 @@
|
|||
#:kivy 1.4
|
||||
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
padding: 50
|
||||
ProgressBar:
|
||||
id: bar
|
||||
value: 140
|
||||
max: 300
|
||||
Slider:
|
||||
id: slider
|
||||
max: 200
|
||||
value: 140
|
||||
on_value: bar.value = self.value
|
||||
Slider:
|
||||
orientation: 'vertical'
|
||||
on_value: slider.value = self.value
|
|
@ -0,0 +1,5 @@
|
|||
#:kivy 1.4
|
||||
|
||||
BoxLayout:
|
||||
RstDocument:
|
||||
text: ".. _top:\n\nHello world\n===========\n\nThis is an **emphased text**, some ``interpreted text``.\nAnd this is a reference to top_::\n\n $ print 'Hello world'\n"
|
|
@ -0,0 +1,16 @@
|
|||
#:kivy 1.4
|
||||
|
||||
FloatLayout:
|
||||
Scatter:
|
||||
size_hint: None, None
|
||||
size: 100, 100
|
||||
pos: 100, 100
|
||||
Image:
|
||||
source: "../../widgets/softboy.png"
|
||||
Scatter:
|
||||
size_hint: None, None
|
||||
size: 100, 100
|
||||
pos: 100, 100
|
||||
do_rotation: False
|
||||
Label:
|
||||
text: "something"
|
|
@ -0,0 +1,10 @@
|
|||
#:kivy 1.4
|
||||
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Spinner:
|
||||
text: "Work"
|
||||
values: "Work", "Home", "Mobile", "Skype"
|
||||
size_hint: (None, None)
|
||||
size: (100, 44)
|
||||
# Wanted to put DropDown here, too, but it seems not to be working too well when loaded from .kv
|
|
@ -0,0 +1,25 @@
|
|||
#:kivy 1.4
|
||||
|
||||
StackLayout:
|
||||
orientation: 'tb-lr'
|
||||
padding: 10
|
||||
spacing: 5
|
||||
Button:
|
||||
text: "Button 1"
|
||||
size_hint: .2, .4
|
||||
width: 100
|
||||
Button:
|
||||
text: "Button 2"
|
||||
size_hint: .2, .4
|
||||
Button:
|
||||
text: "Button 3"
|
||||
size_hint: .2, .4
|
||||
Button:
|
||||
text: "Button 4"
|
||||
size_hint: .2, .4
|
||||
Button:
|
||||
text: "Button 5"
|
||||
size_hint: .2, .4
|
||||
Button:
|
||||
text: "Button 6"
|
||||
size_hint: .2, .4
|
|
@ -0,0 +1,20 @@
|
|||
#:kivy 1.4
|
||||
|
||||
BoxLayout:
|
||||
orientation: "vertical"
|
||||
TextInput:
|
||||
text: "Single Line Input"
|
||||
multiline: False
|
||||
TextInput:
|
||||
text: "Text Input, start typing here\nmultiline\nsupport"
|
||||
background_color: .8, .8, 0, 1
|
||||
size_hint: 1, 3
|
||||
TextInput:
|
||||
text: "Password (but you can't see it)"
|
||||
password: True
|
||||
multiline: False
|
||||
on_text: viewer.text = self.text
|
||||
TextInput:
|
||||
id: viewer
|
||||
read_only: True
|
||||
text: "edit the password to see it here"
|
|
@ -0,0 +1,120 @@
|
|||
#:kivy 1.4
|
||||
|
||||
[ContainerToggle@ToggleButton]:
|
||||
group: "container_toggle"
|
||||
text: ctx.text
|
||||
on_press: root.parent.parent.parent.show_kv(*args)
|
||||
state: ctx.state if hasattr(ctx, "state") else "normal"
|
||||
|
||||
<Catalog>:
|
||||
language_box: language_box
|
||||
screen_manager: screen_manager
|
||||
BoxLayout:
|
||||
BoxLayout:
|
||||
size_hint: None, 1
|
||||
orientation: "vertical"
|
||||
ContainerToggle:
|
||||
text: "Welcome"
|
||||
state: "down"
|
||||
ContainerToggle:
|
||||
text: "Float Layout"
|
||||
ContainerToggle:
|
||||
text: "Box Layout"
|
||||
ContainerToggle:
|
||||
text: "Anchor Layout"
|
||||
ContainerToggle:
|
||||
text: "Grid Layout"
|
||||
ContainerToggle:
|
||||
text: "Stack Layout"
|
||||
ContainerToggle:
|
||||
text: "Buttons"
|
||||
ContainerToggle:
|
||||
text: "Labels"
|
||||
ContainerToggle:
|
||||
text: "Booleans"
|
||||
ContainerToggle:
|
||||
text: "Progress Bar"
|
||||
ContainerToggle:
|
||||
text: "Media"
|
||||
ContainerToggle:
|
||||
text: "Text"
|
||||
ContainerToggle:
|
||||
text: "Popups"
|
||||
ContainerToggle:
|
||||
text: "Selectors"
|
||||
ContainerToggle:
|
||||
text: "File Choosers"
|
||||
ContainerToggle:
|
||||
text: "Scatter"
|
||||
ContainerToggle:
|
||||
text: "ReST"
|
||||
ScreenManager:
|
||||
id: screen_manager
|
||||
Screen:
|
||||
name: "Welcome"
|
||||
PlaygroundContainer:
|
||||
Screen:
|
||||
name: "Float Layout"
|
||||
FloatLayoutContainer
|
||||
Screen:
|
||||
name: "Box Layout"
|
||||
BoxLayoutContainer:
|
||||
Screen:
|
||||
name: "Anchor Layout"
|
||||
AnchorLayoutContainer:
|
||||
Screen:
|
||||
name: "Grid Layout"
|
||||
GridLayoutContainer:
|
||||
Screen:
|
||||
name: "Stack Layout"
|
||||
StackLayoutContainer:
|
||||
Screen:
|
||||
name: "Buttons"
|
||||
ButtonContainer:
|
||||
Screen:
|
||||
name: "Labels"
|
||||
LabelContainer:
|
||||
Screen:
|
||||
name: "Booleans"
|
||||
CheckBoxContainer:
|
||||
Screen:
|
||||
name: "Progress Bar"
|
||||
ProgressBarContainer:
|
||||
Screen:
|
||||
name: "Media"
|
||||
MediaContainer:
|
||||
Screen:
|
||||
name: "Text"
|
||||
TextContainer:
|
||||
Screen:
|
||||
name: "Popups"
|
||||
PopupContainer:
|
||||
Screen:
|
||||
name: "Selectors"
|
||||
SelectorsContainer:
|
||||
Screen:
|
||||
name: "File Choosers"
|
||||
FileChooserContainer:
|
||||
Screen:
|
||||
name: "Scatter"
|
||||
ScatterContainer:
|
||||
Screen:
|
||||
name: "ReST"
|
||||
RestContainer:
|
||||
|
||||
BoxLayout:
|
||||
id: bl
|
||||
orientation: "vertical"
|
||||
size_hint: None, 1
|
||||
width: 400
|
||||
KivyRenderTextInput:
|
||||
text_size: self.width-20, self.height-20
|
||||
font_name: "DroidSansMono.ttf"
|
||||
valign: "top"
|
||||
id: language_box
|
||||
text: "This box will display the kivy language for whatever has been selected"
|
||||
Button:
|
||||
size_hint: 1, None
|
||||
height: 50
|
||||
text: "Render"
|
||||
on_press: root.change_kv(*args)
|
|
@ -0,0 +1,153 @@
|
|||
import kivy
|
||||
kivy.require('1.4.2')
|
||||
import os
|
||||
import sys
|
||||
from kivy.app import App
|
||||
from kivy.factory import Factory
|
||||
from kivy.lang import Builder, Parser, ParserException
|
||||
from kivy.properties import ObjectProperty
|
||||
from kivy.config import Config
|
||||
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.popup import Popup
|
||||
from kivy.uix.label import Label
|
||||
from kivy.uix.textinput import TextInput
|
||||
|
||||
print Config.get('graphics', 'width')
|
||||
|
||||
Config.set('graphics', 'width', '1024')
|
||||
Config.set('graphics', 'height', '768')
|
||||
|
||||
'''List of classes that need to be instantiated in the factory from .kv files.
|
||||
'''
|
||||
CONTAINER_CLASSES = [c[:-3] for c in os.listdir('container_kvs')
|
||||
if c.endswith('.kv')]
|
||||
|
||||
|
||||
class Container(BoxLayout):
|
||||
'''A container is essentially a class that loads its root from a known
|
||||
.kv file.
|
||||
|
||||
The name of the .kv file is taken from the Container's class.
|
||||
We can't just use kv rules because the class may be edited
|
||||
in the interface and reloaded by the user.
|
||||
See :meth: change_kv where this happens.
|
||||
'''
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Container, self).__init__(**kwargs)
|
||||
parser = Parser(content=file(self.kv_file).read())
|
||||
widget = Factory.get(parser.root.name)()
|
||||
Builder._apply_rule(widget, parser.root, parser.root)
|
||||
self.add_widget(widget)
|
||||
|
||||
@property
|
||||
def kv_file(self):
|
||||
'''Get the name of the kv file, a lowercase version of the class name.'''
|
||||
return os.path.join('container_kvs',
|
||||
self.__class__.__name__ + ".kv")
|
||||
|
||||
|
||||
for class_name in CONTAINER_CLASSES:
|
||||
globals()[class_name] = type(class_name, (Container,), {})
|
||||
|
||||
|
||||
class KivyRenderTextInput(TextInput):
|
||||
def _keyboard_on_key_down(self, window, keycode, text, modifiers):
|
||||
is_osx = sys.platform == 'darwin'
|
||||
# Keycodes on OSX:
|
||||
ctrl, cmd = 64, 1024
|
||||
key, key_str = keycode
|
||||
|
||||
if text and not key in (self.interesting_keys.keys() + [27]):
|
||||
# This allows *either* ctrl *or* cmd, but not both.
|
||||
if modifiers == ['ctrl'] or (is_osx and modifiers == ['meta']):
|
||||
if key == ord('s'):
|
||||
self.parent.parent.parent.change_kv(True)
|
||||
return
|
||||
|
||||
super(KivyRenderTextInput, self)._keyboard_on_key_down(
|
||||
window, keycode, text, modifiers)
|
||||
|
||||
|
||||
class Catalog(BoxLayout):
|
||||
'''Catalog of widgets. This is the root widget of the app. It contains
|
||||
a tabbed pain of widgets that can be displayed and a textbox where .kv
|
||||
language files for widgets being demoed can be edited.
|
||||
|
||||
The entire interface for the Catalog is defined in kivycatalog.kv, although
|
||||
individual containers are defined in the container_kvs directory.
|
||||
|
||||
To add a container to the catalog,
|
||||
first create the .kv file in container_kvs
|
||||
The name of the file (sans .kv) will be the name of the widget available
|
||||
inside the kivycatalog.kv
|
||||
Finally modify kivycatalog.kv to add an AccordionItem
|
||||
to hold the new widget.
|
||||
Follow the examples in kivycatalog.kv to ensure the item
|
||||
has an appropriate id and the class has been referenced.
|
||||
|
||||
You do not need to edit any python code, just .kv language files!
|
||||
'''
|
||||
language_box = ObjectProperty()
|
||||
screen_manager = ObjectProperty()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Catalog, self).__init__(**kwargs)
|
||||
self.show_kv(None)
|
||||
|
||||
def show_kv(self, object):
|
||||
'''Called when an accordionitem is collapsed or expanded. If it
|
||||
was expanded, we need to show the .kv language file associated with
|
||||
the newly revealed container.'''
|
||||
|
||||
# if object is not passed, it's initialization, we just need to load
|
||||
# the file
|
||||
if object:
|
||||
# one button must always be pressed, even if user presses it again
|
||||
if object.state == "normal":
|
||||
object.state = "down"
|
||||
|
||||
self.screen_manager.current = object.text
|
||||
|
||||
with open(self.screen_manager.current_screen.content.children[
|
||||
0].kv_file) as file:
|
||||
self.language_box.text = file.read()
|
||||
|
||||
def change_kv(self, button):
|
||||
'''Called when the update button is clicked. Needs to update the
|
||||
interface for the currently active kv widget, if there is one based
|
||||
on the kv file the user entered. If there is an error in their kv
|
||||
syntax, show a nice popup.'''
|
||||
kv_container = self.screen_manager.current_screen.content.children[0]
|
||||
try:
|
||||
parser = Parser(content=self.language_box.text.encode('utf8'))
|
||||
kv_container.clear_widgets()
|
||||
widget = Factory.get(parser.root.name)()
|
||||
Builder._apply_rule(widget, parser.root, parser.root)
|
||||
kv_container.add_widget(widget)
|
||||
except (SyntaxError, ParserException) as e:
|
||||
content = Label(text=str(e), text_size=(350, None))
|
||||
popup = Popup(title="Parse Error in Kivy Language Markup",
|
||||
content=content, text_size=(350, None),
|
||||
size_hint=(None, None), size=(400, 400))
|
||||
popup.open()
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
popup = Popup(title="Boom",
|
||||
content=Label(text="Something horrible happened while parsing your Kivy Language", text_size=(350, None)),
|
||||
text_size=(350, None),
|
||||
size_hint=(None, None), size=(400, 400))
|
||||
popup.open()
|
||||
|
||||
|
||||
class KivyCatalogApp(App):
|
||||
'''The kivy App that runs the main root. All we do is build a catalog
|
||||
widget into the root.'''
|
||||
def build(self):
|
||||
return Catalog()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
KivyCatalogApp().run()
|
Loading…
Reference in New Issue