Overlapping TextInputs in Kivy using FloatLayout - python

Using this code:
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
class Main(App):
def build(self):
root = FloatLayout(size=(100, 100))
root.add_widget(TextInput(pos=(0, 0)))
root.add_widget(TextInput(pos=(50, 50)))
return root
if __name__ == '__main__':
Main().run()
I get two TextInputs, one on top of the other. When I click on the top TextInput (by clicking somewhere in the middle of the screen), the focus goes to the lower TextInput for some reason. In fact, the only way I can get focus on the top TextInput is by clicking entirely outside of the lower TextInput (by clicking right at the top of the screen). Why does this happen, and how can I circumvent this?

Your problem can be approached in two ways.Float layout honors the pos_hint and the size_hint properties of its children.So you need to set size_hint for textinput.
ie-
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
class Main(App):
def build(self):
root = FloatLayout(size=(100, 100))
root.add_widget(TextInput(pos=(0, 0),size_hint=(0.5,0.5)))
root.add_widget(TextInput(pos=(100, 100),size_hint=(0.5,0.5)))
return root
if __name__ == '__main__':
Main().run()
or use boxlayout instead of floatlayout
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
class Main(App):
def build(self):
root = BoxLayout(size=(100, 100))
root.add_widget(TextInput(pos=(0, 0)))
root.add_widget(TextInput(pos=(50, 50)))
return root
if __name__ == '__main__':
Main().run()

Related

How do I bind the on_press function to the button in my kv app using the python file

I have tried to create a layout with multiple rows, where you can count up and down. The count is displayed in the label next to the buttons.
It is a part of a larger layout and application.
I get the layout that I want, but nothing happens when I press the buttons.
I have watched a lot of videos and searched the internet and encountered the .bind but I still haven't fixed it. I have also tried to make changes in the 'def add' and 'def sub'. I am not sure the *args should be there, but if i remove it I get a Traceback: TypeError: Countdown.add() takes 1 positional argument but 2 were given
I hope you can help on my way :)
The python file:
from kivy.app import App
from kivy.core.window import Window
from kivy.graphics.context_instructions import Color
from kivy.graphics.vertex_instructions import Ellipse, Line, Rectangle
from kivy.metrics import dp
from kivy.uix.scrollview import ScrollView
from kivy.properties import (BooleanProperty, NumericProperty, ObjectProperty,
StringProperty)
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.stacklayout import StackLayout
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
Window.clearcolor =(1,1,1,1)
class Countdown(GridLayout):
my_text = StringProperty("0")
count = 0
def __init__(self, **kwargs):
super().__init__(**kwargs)
for i in range(0,10):
self.cols = 3
self.btn1=Button(text="+")
self.btn1.bind(on_press=self.add)
self.add_widget(self.btn1)
self.btn2=Button(text="-")
self.btn2.bind(on_press=self.sub)
self.add_widget(self.btn2)
self.lb=Label(text=self.my_text, color=[0,0,0,1])
self.add_widget(self.lb)
def add(self,*args):
self.count +=1
self.my_text = str(self.count)
def sub(self, *args):
self.count -=1
self.my_text = str(self.count)`

Kivy Read-Only TextInput, but with ability to select all (ctrl+a)

How can I make a TextInput in a python GUI app built with kivy that's read-only, but where the user can still select all of the text with crtl+a?
Consider the following simplified example program with a TextInput containing over 9000 characters
import random
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
class MyApp(App):
def build(self):
layout = BoxLayout()
# generate some random ASCII content
textinput_contents = ''.join( [chr( random.randint(32,127) ) for i in range(0,9001)] )
# add the textinput
self.textinput1 = TextInput(
text=textinput_contents,
readonly=True
)
layout.add_widget(self.textinput1)
return layout
if __name__ == "__main__":
MyApp().run()
I don't want the user to be able to edit the contents of the TextInput, but I do want them to be able to click around, select text, copy from it, etc. Unfortunaetly, in the above example, typing ctrl+a (for the Select All shortcut) does nothing.
However, if I omit the readonly attribute, then ctrl+a works again!
import random
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
class MyApp(App):
def build(self):
layout = BoxLayout()
# generate some random ASCII content
textinput_contents = ''.join( [chr( random.randint(32,127) ) for i in range(0,9001)] )
# add the textinput
self.textinput1 = TextInput(
text=textinput_contents
)
layout.add_widget(self.textinput1)
return layout
if __name__ == "__main__":
MyApp().run()
How can I make the kivy TextInput read-only without disabling Select-All (ctrl+a)?

Kivy Text Editor Input Not Showing Up

I have unfortuanlly have encourtered an error in kivy and Python 3. I have not found a soultion via Google. I wanted to get text input at the very least but it does not show up. Just the text itself. Thank you for your time!
import kivy
kivy.require('1.10.1') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
class ColdKivyApp(App):
def build(self):
f = FloatLayout()
label = Label(text="Cold") #I acutally orginally called it Zone unitil I changed it into Cold cause it's really cold now
f.add_widget(label)
txt = TextInput(text='', focus=True, multiline=True, cursor_blink=True, background_color=(1,1,1,1))
f.add_widget(txt)
return f
if __name__ == '__main__':
ColdKivyApp().run()
It seems that there is a bug in TextInput when setting the focus in the constructor, a workaround is to set the focus an instant after the window is shown through Clock:
import kivy
kivy.require('1.10.1') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.clock import Clock
class ColdKivyApp(App):
def build(self):
f = FloatLayout()
label = Label(text="Cold")
f.add_widget(label)
txt = TextInput(multiline=True, cursor_blink=True, background_color=(1,1,1,1))
f.add_widget(txt)
Clock.schedule_once(lambda *args: setattr(txt, "focus", True))
return f
if __name__ == '__main__':
ColdKivyApp().run()

kivy python widget instance or all widgets

Please help me with understanding classes/instances in python. I want to make a few buttons, and change color of the button, when it's clicked. I don't understand why on_touch_down changes the color of all the instances of the class, not the one that is touched. It's difficult for me to find answer because I don't know how to name it, I don't have much experience with objects. Please explain this. Thank you a million.
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.graphics import Color, Ellipse
class MemoWidget(Button):
def on_touch_down(self, touch):
self.background_color=[100,100,1,1]
class MyApp(App):
def build(self):
root = BoxLayout(orientation='vertical',spacing=4)
m1 = MemoWidget()
m2 = MemoWidget()
m3 = MemoWidget()
root.add_widget(m1)
root.add_widget(m2)
root.add_widget(m3)
return root
if __name__ == '__main__':
MyApp().run()
You might think that on_touch_down only affects the widget you touch. But it affects all widgets of that class.
So what you might want, is on_press or on_release, to only affect the widget itself.
class MemoWidget(Button):
def on_release(self):
self.background_color=[100,100,1,1]

Scrollview not scrolling button

I would like to create a scrollable Floatlayout with dynamically created buttons (kind of paint where I can scroll the drawing board). Unfortunately, the code that I come out doesn't work and the buttons don't move while scrolling the FloatLayout. How can I attach the button to the FloatLayout?
import kivy
kivy.require('1.0.7')
from kivy.app import App
from kivy.uix.scrollview import ScrollView
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
Builder.load_string('''
<Scroller>
view: glayout
FloatLayout:
id: glayout
width: 2000
height: 2000
size_hint: (None, None)
''')
class Main(App):
def build(self):
self.root=Scroller()
return self.root
class Scroller(ScrollView):
def __init__(self, **kwargs):
super(Scroller, self).__init__(**kwargs)
a = Button(size_hint=(None,None), width=200, height=200)
self.ids.glayout.add_widget(a)
a.bind(pos=self.ids.glayout.pos)
if __name__ in ('__main__'):
app = Main()
app.run()
The FloatLayout handle the size, not the position. The most simple solution is to replace your FloatLayout with a RelativeLayout, which handle size, and position is relative to the RelativeLayout origin.

Categories

Resources