I'm making an app to rename files that come from a scanner in a specific format.
The idea is to scan the directory and load a list of files, which are renamed according to the text in the textinput box. I've stripped down the app to come directly to the problem
import csv, os, datetime, string, shutil
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager, FadeTransition
from kivy.properties import ObjectProperty, ListProperty, StringProperty, DictProperty
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from functools import partial
from kivy.uix.scrollview import ScrollView
class TestScreen(Screen):
def update_text(self, text):
print(text)
class ScreenManagement(ScreenManager):
pass
class TestApp(App):
default_font_size = 15
def build(self):
compiled_kv_file = Builder.load_file("TestApp.kv")
return compiled_kv_file
if __name__ == "__main__":
print("Main loop")
TestApp().run()
and the kv file is
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManagement:
transition:FadeTransition()
TestScreen:
<TestScreen>:
name: "TestScreen"
Button:
text:"Test Screen"
size_hint: 0.2,0.1
pos_hint: {"x":0.2,"y":0.8}
font_size: 20
TextInput:
id: my_textinputa
text:"File Screen"
size_hint: 0.2,0.1
pos_hint: {"x":0.4,"y":0.8}
font_size: 20
on_text:
root.update_text(self.text)
Label:
size_hint: 1,0.5
pos_hint: {"x":0,"y":0}
text: my_textinputa.text
font_size: 20
I'm using windows 10 and eclipse with pydev, if thats relevant. The textinput returns the entered text to the .py file. But the textinput does not update the entered text. Furthermore, There seem to be two labels rather than 1.
My gut says that I'm somehow adding two sets of widgets on top of each other. Since only the top one is changed, the text does not change on the bottom one. The output in the console is correct. Yet the textinput box doesnt update itself.
Can someone suggest how to get the textinput to update correctly?
Having multiple .kv files defining the root widget can produce this issue. One solution would be to drop the Builder.load_file("TestApp.kv")
class TestApp(App):
default_font_size = 15
def build(self):
pass
and rename the .kv file to the name of the App instance (test.kv in this case). In this way, kivy will only load one .kv file as the root widget.
Related
I want to be able to scroll within the buttons numbered 10-1 but it wont let me scroll. Any solutions? I was finally able to put the buttons in a scrollview but after all my effort I am not able to move it. It just crams into the space provided and doesn't move at all.
orientation: "vertical"
SongText:
size_hint: 1,0.35
PausePlay:
size_hint: 1,0.1
ScrollView:
orientation: "vertical"
PlayList:
orientation: "vertical"
AddDeleteShuffle:
size_hint: 1,0.2
<SongText>:
Label:
id: songtitle
text: "Song Title"
<PausePlay>:
Button:
id: play
text: "Play"
Button:
id: pause
text: "Pause"
This is the main area of focus I think nothing is needed here but who knows.
<PlayList>: #Main area of conceren
<AddDeleteShuffle>:
BoxLayout:
Button:
text: "Shuffle"
Button:
text: "Delete"
Button:
text: "Shuffle"
kv file ^
py file
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.stacklayout import StackLayout
from kivy.uix.gridlayout import GridLayout
from kivy.metrics import dp
from kivy.core.audio import SoundLoader
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.screenmanager import ScreenManager, Screen
class AddDeleteShuffle(BoxLayout):
pass
class PlayList(BoxLayout):
def __init__(self,**kwargs):
super().__init__(**kwargs)
for i in range(0,10):
size = dp(100)
b = Button(text=str(i+1), size_hint=(1,None), size=(size,size))
self.add_widget(b)
Class for the playlist it is inside a scroll view, but I can't move it. Maybe I have to add a layout in the kv file. I have no idea.
class PausePlay(BoxLayout):
pass
class SongText(BoxLayout):
pass
class AppLayout(BoxLayout):
pass
class Sound5App(App):
def build(self):
return AppLayout()
if __name__ == "__main__":
Sound5App().run()
it is a simple program but i can not find a way to make it work. i just want to add a widget in boxlayout2 when the user presses the button (and has not writed anything in textinput) which is located in boxlayout1 .The widget do not display in screen.What should i do?
main.py
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
class BoxLayout1(BoxLayout):
def Search(self):
if self.ids.textinput.text!='':
BoxLayout2()
class BoxLayout2(BoxLayout):
def Print(self):
self.add_widget(Button(text='hello'))
class TestApp(App):
pass
TestApp().run()
and here is my kivy code
test.kv
<BoxLayout1>:
BoxLayout:
Label:
text:'Hello'
TextInput:
id: textinput
Button:
text: 'write'
on_press: root.Search()
BoxLayout:
orientation: 'vertical'
BoxLayout1:
BoxLayout2:
I see the presentation layout i want but the button is nowhere to be found.
To make it clear let's follow the stream of the app you've written.
it creates a BoxLayout and puts BoxLayout1 and BoxLayout2 in it, the second one doesn't have any content. When you click on write, the app checks the content of the text box and if valid, calls the constructor of BoxLayout2! Now at this point it creates an instance of this class, but does not keep it's reference so it will be discarded immediately. Now what you want is to call a function of a currently existing instance, not to create another one. Here's the code:
python:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
class BoxLayout1(BoxLayout):
def Search(self):
if self.ids.textinput.text!='':
self.parent.ids.bxl2.addButton()
# BoxLayout2()
class BoxLayout2(BoxLayout):
def addButton(self):
button=Button(text='hello')
self.add_widget(button)
kivy language:
<BoxLayout1>:
BoxLayout:
Label:
text:'Hello'
TextInput:
id: textinput
Button:
text: 'write'
on_press: root.Search()
BoxLayout:
orientation: 'vertical'
BoxLayout1:
BoxLayout2:
id:bxl2
I'm new to Kivy and I would have to think this is possible, but I can't figure it out - How can I update a Kivy label when a button is pressed, but only by referencing that Kivy id within Python? (The reason I'm trying to do it this way is because in my actual application, I would like several labels to update at once, which I was hoping I could do all within the button_pressed equivalent button I have in my app).
In the simple example below, I'm just trying to have the button pressed and then have the label update to 'Updated!'
Thanks very much!
My Python code:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.properties import StringProperty
import random
class TestingWidget(BoxLayout):
# This is the kv id of the Label I would like to update
label_to_update = StringProperty('')
# This is the action I would like to happen when the button is pressed
def button_pressed(self):
label_to_update.text = 'Updated!'
class TestButtonApp(App):
def build(self):
return TestingWidget()
if __name__ == '__main__':
TestButtonApp().run()
My kv file:
<TestingWidget>:
BoxLayout:
orientation: 'horizontal'
Button:
text: 'test'
on_press: root.button_pressed()
Label:
id: label_to_update
text: 'Trying to get this to update'
You definitely update all label when you press the button. Just crate a StringProperty for each and do what you are doing now.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.properties import StringProperty
from kivy.lang import Builder #used because I didn't want to create two files
import random
Builder.load_string('''
<TestingWidget>:
BoxLayout:
orientation: 'horizontal'
Button:
text: 'test'
on_press: root.button_pressed()
Label:
id: label_to_update
text: root.label_to_update
''')
class TestingWidget(BoxLayout):
# This is the kv id of the Label I would like to update
label_to_update = StringProperty('Trying to get this to update')
#default text set
# This is the action I would like to happen when the button is pressed
def button_pressed(self):
self.label_to_update = 'Updated!'
class TestButtonApp(App):
def build(self):
return TestingWidget()
if __name__ == '__main__':
TestButtonApp().run()
I have my python code:
from kivy.app import App
from kivy.uix.scatter import Scatter
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout
class Premade(BoxLayout):pass
class MyFirstApp(App):
def build(self):
return Premade()
if __name__ == '__main__':
MyFirstApp().run()
and my .kv file:
#:kivy 1.10.0
<Premade>:
orientation: 'Verticle'
TextInput:
id: my_textinput
font_size: 150
size_hint_y: None
height: 200
text: 'default'
FloatLayout:
Scatter:
Label:
text: my_textinput.text
font_size: 150
Supposedly, when I run the python code, the .kv file would be loaded, but all I get is a black screen. I named my .kv file according to the rule, in this case, is myfirst.kv and the .kv file is also in the same directory as the python module file. I also tried to use the build function but that didn't work either. Can anyone help?
Check your .kv filename, if you want it to be loaded automatically you should name it MyFirst.kv because your app is called MyFirstApp. An alternative solution would be to load the file manually as the following:
from kivy.lang import Builder
Builder.load_file('filename.kv')
Has to be called myfirstapp.kv or the same name as the app class
kindly need to know how to change or control the size of the special buttons inside a kivy spinner. note: my spinner is in the kv language and not in python and looks like this:
Spinner:
id:some_id
text:"some text"
values:("1","2","3")
size_hint:(None,None)
size: root.width/4,root.height/12
Buttons inside of Spinner are of type passed to option_cls property. The default one is SpinnerOption class, which is actually a subclass of Button. You can change class passed to this property (it must have text property and on_release event) or modify SpinnerOption class globally:
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.base import runTouchApp
Builder.load_string('''
<SpinnerOption>:
size_hint: None, None
size: 20, 20
<MyWidget>:
Spinner:
id:some_id
text:"some text"
values:("1","2","3")
size_hint:(None,None)
size: root.width/4,root.height/12
''')
class MyWidget(BoxLayout):pass
runTouchApp(MyWidget())
Using custom buttons:
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.spinner import Spinner
from kivy.base import runTouchApp
from kivy.properties import ObjectProperty
Builder.load_string('''
<MyButton>:
size_hint: None, None
size: 20, 20
<MyWidget>:
MySpinner:
id:some_id
text:"some text"
values:("1","2","3")
size_hint:(None,None)
size: root.width/4,root.height/12
''')
class MyButton(Button):
pass
class MySpinner(Spinner):
option_cls = ObjectProperty(MyButton) # setting this property inside kv doesn't seem to work
class MyWidget(BoxLayout):
pass
runTouchApp(MyWidget())