In a part of my app I want to show a list of numbers (1 to 100) and when the "filter" button selected list numbers change (1 to 10). I've tried several solutions like this but none of them worked !
what is the problem in your idea?
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.listview import ListView
from kivy.uix.label import Label
class SingleApp(App):
def build(self):
hole = BoxLayout()
right = BoxLayout(size_hint_x=0.2)
left = BoxLayout(size_hint_x=0.8, orientation='vertical')
side_panel = ListView(item_strings=['no %i' %i for i in range(100)])
right.add_widget(side_panel)
btn = Button(text='Show 1 to 10 ')
lbl = Label(text='Show list of numbers (test)')
btn2 = Button(text='reset')
left.add_widget(btn)
left.add_widget(lbl)
left.add_widget(btn2)
hole.add_widget(right)
hole.add_widget(left)
btn.bind(on_press=self.change(right))
btn2.bind(on_press=self.reset(right))
return hole
def change(self, side):
side.clear_widgets()
side_panel = ListView(item_strings=['NUMBER %i' %i for i in range(10)])
side.add_widget(side_panel)
def reset(self, side):
side.clear_widgets()
side_panel = ListView(item_strings=['no %i' %i for i in range(100)])
side.add_widget(side_panel)
if __name__=='__main__':
SingleApp().run()
Related
I need to make an application consisting of a window. In its upper half, this window has 2 text boxes and a button, aligned horizontally.
If you enter two numbers, one in each of the text boxes, and press the button, an operation of these two numbers is displayed in the lower half of the screen.
In the middle of the screen, 4 checkboxes (addition, subtraction, multiplication or division) to define the operation on the 2 numbers.
If one of the two numbers is not a digit, an error message is displayed.
from kivy.app import App
from kivy.config import Config
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.checkbox import CheckBox
class MyApp(App):
def __init__(self, **kwargs):
super().__init__()
self.a = None
self.b = None
self.button = None
self.display = None
def build(self):
self.title = 'Addition'
"""------------------------------------------------"""
calc = BoxLayout(orientation='horizontal')
self.a = TextInput(multiline=False)
calc.add_widget(self.a)
calc.add_widget(Label(text='+', font_size=20))
self.b = TextInput(multiline=False)
calc.add_widget(self.b)
self.button = Button(text='Entrer', font_size=20)
self.button.bind(on_press=self.add_numbers)
calc.add_widget(self.button)
"""------------------------------------------------"""
check = BoxLayout(orientation='horizontal')
check.add_widget(CheckBox(group='op'))
check.add_widget(Label(text='add'))
check.add_widget(CheckBox(group='op'))
check.add_widget(Label(text='sub'))
check.add_widget(CheckBox(group='op'))
check.add_widget(Label(text='mult'))
check.add_widget(CheckBox(group='op'))
check.add_widget(Label(text='div'))
"""------------------------------------------------"""
display = BoxLayout(orientation='horizontal')
self.display = Label(text='Result: ')
display.add_widget(self.display)
"""------------------------------------------------"""
box = BoxLayout(orientation='vertical')
box.add_widget(calc)
box.add_widget(check)
box.add_widget(display)
return box
def add_numbers(self, instance):
num1 = self.a.text
num2 = self.b.text
try:
somme = float(num1) + float(num2)
self.display.text = "Result: " + str(somme)
except ValueError:
self.display.text = "Erreur, vous devez entrer des chiffres."
Config.set('graphics', 'width', '350')
Config.set('graphics', 'height', '50')
if __name__ == '__main__':
MyApp().run()
That's my program at the moment.
I've been trying to link the checkboxes to the function but without success
Can somebody help me?
I want to make an internet speed test application for Android with Python.
I have done the back-end side but I have a hard time with the front-end.
After research, I decided to use the Kivy framework, however, I need guidance on how to create a gauge like this.
There are two ways to create a gauge. The first one is by using code with mathematics and the second one is by using graphic files for cadran and needle. Below, you will find the implementation of the second way, with the help of the original code of the gauge widget of Kivy Garden project, in which you will be able to understand how the gauge works more easily.
import kivy
kivy.require('1.6.0')
from kivy.app import App
from kivy.clock import Clock
from kivy.properties import NumericProperty
from kivy.properties import StringProperty
from kivy.properties import BoundedNumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.uix.scatter import Scatter
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.progressbar import ProgressBar
from os.path import join, dirname, abspath
class Gauge(Widget):
'''
Gauge class
'''
unit = NumericProperty(1.8)
value = BoundedNumericProperty(0, min=0, max=100, errorvalue=0)
path = dirname(abspath(__file__))
file_gauge = StringProperty(join(path, "cadran.png"))
file_needle = StringProperty(join(path, "needle.png"))
size_gauge = BoundedNumericProperty(128, min=128, max=256, errorvalue=128)
size_text = NumericProperty(10)
def __init__(self, **kwargs):
super(Gauge, self).__init__(**kwargs)
self._gauge = Scatter(
size=(self.size_gauge, self.size_gauge),
do_rotation=False,
do_scale=False,
do_translation=False
)
_img_gauge = Image(
source=self.file_gauge,
size=(self.size_gauge, self.size_gauge)
)
self._needle = Scatter(
size=(self.size_gauge, self.size_gauge),
do_rotation=False,
do_scale=False,
do_translation=False
)
_img_needle = Image(
source=self.file_needle,
size=(self.size_gauge, self.size_gauge)
)
self._glab = Label(font_size=self.size_text, markup=True)
self._progress = ProgressBar(max=100, height=20, value=self.value)
self._gauge.add_widget(_img_gauge)
self._needle.add_widget(_img_needle)
self.add_widget(self._gauge)
self.add_widget(self._needle)
self.add_widget(self._glab)
self.add_widget(self._progress)
self.bind(pos=self._update)
self.bind(size=self._update)
self.bind(value=self._turn)
def _update(self, *args):
'''
Update gauge and needle positions after sizing or positioning.
'''
self._gauge.pos = self.pos
self._needle.pos = (self.x, self.y)
self._needle.center = self._gauge.center
self._glab.center_x = self._gauge.center_x
self._glab.center_y = self._gauge.center_y + (self.size_gauge / 4)
self._progress.x = self._gauge.x
self._progress.y = self._gauge.y + (self.size_gauge / 4)
self._progress.width = self.size_gauge
def _turn(self, *args):
'''
Turn needle, 1 degree = 1 unit, 0 degree point start on 50 value.
'''
self._needle.center_x = self._gauge.center_x
self._needle.center_y = self._gauge.center_y
self._needle.rotation = (50 * self.unit) - (self.value * self.unit)
self._glab.text = "[b]{0:.0f}[/b]".format(self.value)
self._progress.value = self.value
if __name__ == '__main__':
from kivy.uix.slider import Slider
class GaugeApp(App):
increasing = NumericProperty(1)
begin = NumericProperty(50)
step = NumericProperty(1)
def build(self):
box = BoxLayout(orientation='horizontal', padding=5)
self.gauge = Gauge(value=50, size_gauge=256, size_text=25)
self.slider = Slider(orientation='vertical')
stepper = Slider(min=1, max=25)
stepper.bind(
value=lambda instance, value: setattr(self, 'step', value)
)
box.add_widget(self.gauge)
box.add_widget(stepper)
box.add_widget(self.slider)
Clock.schedule_interval(lambda *t: self.gauge_increment(), 0.03)
return box
def gauge_increment(self):
begin = self.begin
begin += self.step * self.increasing
if 0 < begin < 100:
self.gauge.value = self.slider.value = begin
else:
self.increasing *= -1
self.begin = begin
GaugeApp().run()
Of course, if you don't want to use the default cadran and needle, you will have to design your own, using a vector graphics editor.
Ok, My question goes this way How Can I Animate a Label in Kivy, My apologies if this question is annoyingly way too easy :)
Here is the Label in which I want animation. Can I have edits of the code in the comments?
Actually, I am obsessed with this script, racking my brains off to know the way to animate this thingy!! Pls Help!..
import kivy
from kivy.app import App
from kivy.uix.label import Label
class MyApp(App):
def build(self):
lu = Label(text = "This is a label! Pls help me with Animation!")
return lu
if __name__ == '__main__':
MyApp().run()
If you want to update text on Label every few seconds then you can use Clock and Clock.schedule_interval(function_name, seconds) to execute function_name(dt) every seconds and in this function you should change text in Label
Minimal example which displays current time.
from kivy.app import App
from kivy.uix.label import Label
from kivy.clock import Clock
import datetime
def update_label(dt):
new_text = datetime.datetime.now().strftime('%H:%M:%S')
label.text = new_text
#print(new_text)
label = None # create global variable to access the same `label` in two different functions
class MyApp(App):
def build(self):
global label # inform function to assign `Label` to global variable
label = Label(text="???")
Clock.schedule_interval(update_label, 1)
return label
#Clock.schedule_interval(update_label, 1)
if __name__ == '__main__':
MyApp().run()
EDIT:
Another example which scroll text
from kivy.app import App
from kivy.uix.label import Label
from kivy.clock import Clock
import datetime
label = None
text = 'Hello World of Python!'
text_length = len(text)
index = 0
temp_text = text + ' ' + text
def update_label(dt):
global index
label.text = temp_text[index:index+15]
index += 1
if index >= text_length:
index = 0
class MyApp(App):
def build(self):
global label
label = Label(text="???")
Clock.schedule_interval(update_label, 0.20)
return label
if __name__ == '__main__':
MyApp().run()
EDIT:
For numerical values you can use Animation.
Here is blinking text.
It changes color to black (in 0.2 second) and next it change back to white (in 0.2 second). And it repeats it.
from kivy.app import App
from kivy.uix.label import Label
from kivy.animation import Animation
class MyApp(App):
def build(self):
label = Label(text='Hello World of Python!')
anim = Animation(color=(0, 0, 0, 1), duration=.2) + Animation(color=(1, 1, 1, 1), duration=.2)
anim.repeat = True
anim.start(label)
return label
if __name__ == '__main__':
MyApp().run()
I'm trying to output text from button presses and add it to a textbox each time it's pressed as well as delete the text when the delete button is pressed - in normal python.
I've been trying to use kivy.uix.textinput, but I'm not sure on how to output the value from the buttons as well as delete it.
This is what I've done so far.
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
class CodeScreen(Screen):
def __init__(self):
super(CodeScreen, self).__init__(name='code_screen')
main_grid_lay = GridLayout(cols=2,cols_minimum={0:640, 1:175})
self.add_widget(main_grid_lay)
#Code ouput display
display_code = TextInput(text='Code!', readonly = True, id=output)
main_grid_lay.add_widget(display_code)
#Options Buttons
box_lay = BoxLayout(orientation='vertical')
main_grid_lay.add_widget(box_lay)
delete_button = Button(
text='Delete',
size_hint_x= None,
width=160,
id='' #unsure on how to delete
)
box_lay.add_widget(delete_button)
base_left = Button(
text='Base Left',
#on_release= b_left(),
#id='left',
)
base_right = Button(
text='Base Right',
on_release=self.degree_popup,
#on_release= b_right(),
)
#b_left = self.ids.output.text='left'
#b_left = self.ids.output.text='right'
box_lay.add_widget(base_left)
box_lay.add_widget(base_right)
# The app class
class MyMain(App):
def build(self):
return CodeScreen()
# Runs the App
if __name__ == '__main__':
MyMain().run()
It currently sends an error and is probably because of the ids. Not fully sure how ids work without using kv language. Any help is appreciated.
The id only makes sense in .kv, in python they are useless. In this case the solution is to access the objects in the methods connected to on_release but for this they must be class attributes.
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
class CodeScreen(Screen):
def __init__(self):
super(CodeScreen, self).__init__(name="code_screen")
self.display_code = TextInput(text="Code!", readonly=True)
self.delete_button = Button(
text="Delete", size_hint_x=None, width=160, on_release=self.delete_clicked
)
self.base_left = Button(text="Base Left", on_release=self.left_clicked)
self.base_right = Button(text="Base Right", on_release=self.right_clicked)
main_grid_lay = GridLayout(cols=2, cols_minimum={0: 640, 1: 175})
main_grid_lay.add_widget(self.display_code)
self.add_widget(main_grid_lay)
box_lay = BoxLayout(orientation="vertical")
box_lay.add_widget(self.delete_button)
main_grid_lay.add_widget(box_lay)
box_lay.add_widget(self.base_left)
box_lay.add_widget(self.base_right)
def delete_clicked(self, instance):
self.display_code.text = ""
def left_clicked(self, instance):
self.display_code.text += "left"
def right_clicked(self, instance):
self.display_code.text += "right"
# The app class
class MyMain(App):
def build(self):
return CodeScreen()
# Runs the App
if __name__ == "__main__":
MyMain().run()
I want to create an Accordion containing content consisting of an RstDocument and a button. The Accordion shall be scrollable as well as the content of the RstDocument when this content is larger than the given space. So I came up with the following code but after some clicks on AccordionItems all further interaction is blocking. What am I doing wrong here?
from kivy.app import App
from kivy.uix.scrollview import ScrollView
from kivy.uix.rst import RstDocument
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.button import Button
class ShowrstApp (App):
def update_size(self, instance, *args):
instance.size = 60 * len(instance.children)
def build (self):
numitems = 10
root = BoxLayout()
accheight = numitems * 60
accitems = Accordion(id='acc_panel', orientation='vertical', pos_hint={'top': 1}, size_hint_y=None,
height=accheight, md_bg_color=(1, 1, 1, 1))
for i in xrange(numitems):
item = AccordionItem(title='This is item: %d' % i)
somecontent = BoxLayout(orientation='vertical')
somecontent.add_widget(RstDocument(text='Some nicely formatted text here'))
somecontent.add_widget(Button(text='click here', height=(42), size_hint=(1,None)))
item.add_widget(somecontent)
item.bind(children=self.update_size)
accitems.add_widget(item)
sv = ScrollView(do_scroll_x = False)
sv.add_widget(accitems)
root.add_widget(sv)
return root
Window.size = (350,650)
showrst = ShowrstApp()
showrst.run()
Below the scrolling effect works when the RstDocument Boxlayout is either horizontal of vertical, but an issue I saw was that when the BoxLayout was set to vertical, the toggle of each item was mute, you had to go one by one from the bottom-up. This was weird. You can click on each AccordionItem, where the RstDocument is not. This should be a great starting point. Noticed this effect doesn't occur when using a Label, so that could be a another option.
from kivy.app import App
from kivy.uix.scrollview import ScrollView
from kivy.uix.rst import RstDocument
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.button import Button
class ShowrstApp (App):
def update_size(self, instance, *args):
instance.height = 100 * len(instance.children) # set Accordion height to the number of accordionItem times the height accordionItem height
def build (self):
numitems = 10
root = BoxLayout()
accheight = numitems * 60
accitems = Accordion(id='acc_panel', orientation='vertical', size_hint_y=None, pos_hint={'top':1}
height=accheight, md_bg_color=(1, 1, 1, 1))
for i in xrange(numitems * 2): # *2 to show it works
item = AccordionItem(title='This is item: %d' % i)
somecontent = BoxLayout(orientation = 'horizontal') # couldn't solve an issue I notice so I used horizontal
somecontent.add_widget(RstDocument(text='Some nicely formatted text here' * 10))
somecontent.add_widget(Button(text='click here', height=(42), size_hint=(1,None)))
item.add_widget(somecontent)
accitems.bind(size=self.update_size)
accitems.add_widget(item)
sv = ScrollView(do_scroll_x = False)
sv.add_widget(accitems)
root.add_widget(sv)
return root
Window.size = (350,650)
showrst = ShowrstApp()
showrst.run()
I was having the same issue with RstDocuments in a ScrollView. The problem arises because RstDocuments have their own scrolling and 'intercept' the scroll command because it thinks you're trying to scroll inside the RstDocument. If you're fine with non-scrolling RstDocuments, you can set do_scroll_y: False for RstDocument, and scrolling will then work fine in the ScrollView regardless of mousing over an RstDocument.