How to get a text input box to display with Kivy? - python

I'm currently writing an app in Kivy for a school project (I have very much had to jump in the deep end with Kivy). I have written the kv code for the text input, which you can see below:
AnswerInput:
<AnswerInput#BoxLayout>:
orientation: "vertical"
BoxLayout:
height: "40dp"
size_hint_y: None
TextInput:
size_hint_x: 20
Button:
text: "Check Answer"
size_hint_x: 25
I now need to get the text box to display in the Python file; however, I am at something of a loss as to how I would do this? My Python code is below:
from kivy.app import App
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
class TextInputTest(App):
def __init__(self, *args, **kwargs):
return TextInput
if __name__ == '__main__':
TextInputTest().run()
I am almost certain that I am missing something here, probably something very simple, but I am very much a beginner with Kivy. If anyone could put me on the right track, I would be very grateful.

Firstly, this isn't clear but you need to seperate your code into a py file and a kv file. It seems like you've done this already. Your kv file also needs to be all lowercase
In your py file, you then add a class for the kivy widget. In this case:
from kivy.uix.boxlayout import BoxLayout
class AnswerInput(BoxLayout):
pass
Then in your kv file:
<AnswerInput>:
orientation: "vertical"
BoxLayout:
height: "40dp"
size_hint_y: None
TextInput:
size_hint_x: 20
Button:
text: "Check Answer"
size_hint_x: 25
AnswerInput from your py looks into your loaded kv file to see if there is a root widget with the same name as itself.
(RootWidget meaning the top widget of a bunch of kv logic encased in <>)
You have to however first know how to load a kv file, there are two ways to do this. If you're using just one kv file, you can name your app the same as your kv file.
So if your kv file is
textinputtest.kv
Your app class in py would read
TextInputTest(App):
or
TextInputTestApp(App):
You don't need to do this, you can also use the builder module to load the file itself (and in fact you will need to do this if you have more than one kv file).
To do this, you do this in your py file:
from kivy.lang.builder import Builder
Builder.load_file('textinputtest.kv')
You're also returning an object of the textinput class, what you want to do is return an object of your customized textinput class.
Your Py file would look like this:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
class AnswerInput(BoxLayout):
pass
class TextInputTest(App): # If your kv file is called textinputtest.kv
def build(self):
return AnswerInput()
if __name__ == '__main__':
TextInputTest().run()
Or you can name your app anything you want and then use builder to load the relevant kv file directly into your app.

Related

kivy file returning blank screen

Here is the kivy file code:
#:kivy
<MyGridLayout>:
GridLayout:
cols:1
GridLayout:
cols:2
Label:
text: "Name"
TextInput:
multiline:False
Label:
text: "Time"
TextInput:
multiline:False
Label:
text: "Mood"
TextInput:
multiline:False
Button:
text:"Submit"
here is the main file code:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.gridlayout import GridLayout
# from numpy import full
class MyGridLayout(Widget):
def button_pressed(self, instance):
name = self.name.text
time = self.time.text
mood = self.mood.text
self.add_widget(Label(text=f'hey, {name}\nAccording to your {mood} mood at {time}, we have some suggestions in songs: '))
self.name.text=""
self.time.text=""
self.mood.text=""
class QuizMasters(App):
def build(self):
return MyGridLayout()
if __name__=='__main__':
QuizMasters().run()
Whenever running the file facing the same issue of blank screen, i have saved the main file as QuizMasters.py and the kivy file as QuizMasters.kv , can someone please help...
You haven't specified the kivy version in .kv file. Try setting it like,
#:kivy 2.0.0 # Or replace with your installed version.
.
.
.
When I ran your code, I got an error in the .kv file. Once I deleted the #:kivy, it worked out for me.
If that doesn't work, MyGridLayout inherits from the Widget which makes it a Widget that must be added. Try switching into a screen, and tell me if that works.
Also, don't forget, the name of the .kv file must be the same as your QuizMasters main class. If your main class includes app, you should not include it. In your case, your .kv file should be named quizmasters.kv ALL LOWERCASE

Python Kivy widgets duplicated on top of each other on a custom app restart method

Basically I'm working on a Kivy app that consists of multiple screens. Recently I decided to give my app a little Refresh button that refreshes the widgets and reread the savefile for sorta debugging purpose, and then I of course stole the code from this question's answer, like how every programmer would do. It worked, but there's one slight problem: every time I press the refresh button, for whatever reason the widgets got duplicated and placed on top of each other(even though the restart function cleared the former widgets beforehand). Here's my code, simplified:
test.py
from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen
from kivy.config import Config
Config.set("kivy", "exit_on_escape", 0)
class First(Screen):
pass
class Second(Screen):
pass
class Test(MDApp):
def restart(self):
self.root.clear_widgets()
self.stop()
Test().run()
Test().run()
test.kv
ScreenManager:
First:
Second:
<First>:
MDFloatLayout:
MDTextField:
size_hint: 0.8, 0.2
pos_hint: {'center_x': 0.5, 'top': 0.9}
hint_text: 'owo uwu test im a furry yes'
MDRectangleFlatButton:
text: 'Restart'
size_hint: 0.15, 0.1
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
on_release: app.restart()
<Second>:
Also note that the reason to why I used screens in this example app although there's no way to access the Second screen, is because I did some tests and the result is that the "bug" only occurs with the ScreenManager being the root class, others like FloatLayout works properly. Secondly the reason why I used KivyMD in this example is that it's easier to detect the duplication of widgets using MDTextField because of the animation of the hint text.
Does anyone know what's the cause behind the problem, as well as the solution to this? Any help would be appreciated.
Edit: Here are images for demonstration:
Before restarting:
After restarting:
Th problem is that your test.kv file is getting loaded twice due to Kivy doing its automatic loading based on the file name. The fix is to control the kv file loading yourself. To do that, change the name of your kv file to anything other than test.kv, perhaps not_test.kv. Then create a build() method in your Test App:
class Test(MDApp):
def build(self):
from kivy.resources import resource_find
filename = 'not_test.kv'
filename = resource_find(filename) or filename
if filename in Builder.files:
Builder.unload_file(filename)
return Builder.load_file(filename)
This code unloads the kv file if it has already been loaded, then loads it again in order to get the root widget.

Display widget when the user wants to in kivy

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

Using a button to load a kv file

Hi all my question is a basic one. I'm using a .kv file in which I have defined a button that changes screens. I would like to use that button to load .kv file. I can use builder.load(kv2.kv) ?
I've tried a bunch of different ways writing it out. The stats.kv file loads all my RPG stats. If I remove the builder statement, I just get the next screen. All my widgets are in a different .kv files for ease of debugging purposes. I just need to load multiple .kv files within a .kv file.
However this error always occurs:
AttributeError: 'RevengeApp' object has no attribute 'builder'
Button in .kv file:
Button:
text: "Confirm"
on_press: app.builder.load(stats.kv)
on_release: app.root.current = "AStats"
Did you assign the Builder object to the builder attribute of your app? because that's what your kv code seems to expect.
from kivy.lang import Builder
[…]
class RevengeApp(App):
def build(self):
self.builder = Builder
should do it.
But you could also just import Builder directly in your kv code by doing
#:import builder kivy.lang.Builder
at the top of your kv file, and then replace your app.builder.load with builder.load_file in your on_press binding.

python code won't run with .kv file

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

Categories

Resources