Kivy - Two sliders in a layout - python

I am trying to use two sliders in layout. The code is given below. The problem is only the second slider responds to the mouse actions. The first slider (and also the button) does not respond at all to the mouse actions. How to make both sliders responsive?
Thanks in advance
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.slider import Slider
from kivy.uix.button import Button
def Exit(instance):
print('Exit the screen')
App.get_running_app().stop()
def MainScreen():
flt = FloatLayout()
button = Button(text='Hello Kivy World')
button.size = (200, 100)
button.size_hint = (None, None)
button.pos_hint = {'center_x': .5, 'center_y': .2}
button.bind(on_press=Exit)
flt.add_widget(button)
slid1 = Slider()
slid1.id = 'Slider 01'
slid1.size_hint_x = .75
slid1.pos_hint = {'x': .125, 'center_y': .5}
slid1.value_track = True
slid1.value_track_color = [0, 1, 0, 1]
slid1.sensitivity = 'handle'
flt.add_widget(slid1)
slid2 = Slider()
slid2.id = 'Slider 02'
slid2.size_hint_x = .75
slid2.pos_hint = {'x': .125, 'center_y': .75}
slid2.value_track = True
slid2.value_track_color = [1, 0, 0, 1]
slid2.sensitivity = 'handle'
flt.add_widget(slid2)
return flt
class MainApp(App):
def build(self):
return MainScreen()
if __name__ == "__main__":
app = MainApp()
app.run()

If you change your floatlayout to a boxlayout it works.
flt = BoxLayout(orientation='vertical')

Related

How to change a bg of ScrollView in my code and print the text on it?

My program parses the site at the click of a button and displays the text of the book on the user's screen. But since I'm a beginner, I can't find the ScrollView argument that would repaint it in the color I want. Maybe I'm doing something wrong, I would be glad if someone could tell me how to display the text on the screen ScrollView, which is not black!
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from bs4 import BeautifulSoup
from kivy.uix.scrollview import ScrollView
import requests
class MyButton(Button):
color = (0, 0, 0, 1)
valign = 'bottom'
padding_y = 10
background_color = (.93, .91, .67, 1)
background_normal = ''
class Box(BoxLayout):
orientation = "vertical"
padding = [5,5,5,5]
spacing = 10
def on_kv_post(self, widget):
self.add_widget(MyButton(text='И. С. Тургенев. «Отцы и дети»', on_press=self.btn_press))
def btn_press(self, instance):
self.clear_widgets()
sc = ScrollView()
x = 1
data = ''
while True:
if x == 1:
url = "http://loveread.ec/read_book.php?id=12021&p=1"
elif x < 4:
url = "http://loveread.ec/read_book.php?id=12021&p=" + f'{x}'
else:
break
request = requests.get(url)
soup = BeautifulSoup(request.text, "html.parser")
teme = soup.find_all("p", class_="MsoNormal")
for temes in teme:
data += temes.text
x = x + 1
sc.add_widget(Label(text=f'{data}',color = (1,1,1,1)))
self.add_widget(sc)
class MyApp(App):
def build(self):
return Box()
if __name__ == "__main__":
MyApp().run()
You need your Label to adjust according to its text. The easiest way to do that is by using the kivy language. Here is one way to do it:
Add a new class MyLabel:
class MyLabel(Label):
pass
Use the new class in your python:
sc.add_widget(MyLabel(text=f'{data}',color = (1,1,1,1)))
Add use the kivy language to define the new class:
class MyApp(App):
def build(self):
Builder.load_string('''
<MyLabel>:
size_hint: 1, None
text_size: self.width, None
height: self.texture_size[1]
''')
return Box()

Why is ScrollView text displayed only with a certain font_size value?

I have a program that parses text from a site and outputs it. But the problem is that when I put this text in ScrollView then at 4 pages of the book it is displayed, but at 57 pages it simply is not. Only if I change the value of font_size to 1, only then the entire text of the book is displayed, but obviously this is not what I need. How to solve this problem?
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from bs4 import BeautifulSoup
from kivy.uix.scrollview import ScrollView
import requests
Builder.load_string('''
# Define the scroll view
<ScrollableLabel>:
Label:
id: label
color: (1,1,1,1)
font_size: 15
text_size: self.width, None
size_hint_y: None
height: self.texture_size[1]
''')
class MyButton(Button):
color = (0, 0, 0, 1)
valign = 'bottom'
padding_y = 10
background_color = (.93, .91, .67, 1)
background_normal = ''
class ScrollableLabel(ScrollView):
pass
class Box(BoxLayout):
color = (.98, .98, .82, 1)
orientation = "vertical"
padding = [5, 5, 5, 5]
spacing = 10
def on_kv_post(self, widget):
self.add_widget(MyButton(text='И. С. Тургенев. «Отцы и дети»', on_press=self.btn_press))
def btn_press(self, instance):
self.clear_widgets()
sc = ScrollableLabel()
x = 1
data = ''
while True:
if x == 1:
url = "http://loveread.ec/read_book.php?id=12021&p=1"
elif x < 4:
url = "http://loveread.ec/read_book.php?id=12021&p=" + f'{x}'
else:
break
request = requests.get(url)
soup = BeautifulSoup(request.text, "html.parser")
teme = soup.find_all("p", class_="MsoNormal")
for temes in teme:
data += temes.text
x = x + 1
sc.ids.label.text = data
self.add_widget(sc)
class MyApp(App):
def build(self):
return Box()
if __name__ == "__main__":
MyApp().run()

How to delete a widget in python kivy

I wanted to remove the 'bl' widget by clicking the 'horny mode' button, but it is not initially on the screen. How can I make the widget be removing by clicking on the button?
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.config import Config
from kivy.core.window import Window
from kivy.uix.image import Image
from kivy.uix.widget import Widget
class ScraperApp(App, FloatLayout):
def PhotGif(self):
wentil = Image(source='img.gif', size_hint = (.5, .5), anim_loop = 99999)
photo = AnchorLayout(anchor_x='center', anchor_y='top', padding = [0, 75, 0, 0])
photo.add_widget(wentil)
return photo
def build(self):
bl = BoxLayout(orientation='horizontal', padding = [50, 100, 50, 150], spacing = 5)
bl.add_widget( Button(text = '1', on_press = self.first, font_size = 20, size_hint = (.3, .1)))
bl.add_widget( Button(text = '2', on_press = self.second, font_size = 20, size_hint = (.3, .1)))
#bl.add_widget( Button(text = 'Wallpaper mode', on_press = self.wallpaper, font_size = 20, size_hint = (.3, .1)))
wid = FloatLayout()
wid.add_widget(ScraperApp().PhotGif())
wid.add_widget(bl)
return wid
def first(self, instance):
print('Horny mode')
instance.text = 'кнопка нажата'
ScraperApp().build().remove_widget(bl)
stop()
def stop():
ScraperApp().build().remove_widget(bl)
def second(self, instance):
print('Soft mode')
instance.text = 'кнопка нажата'
if __name__ == '__main__':
ScraperApp().run()
Can you help me make so that when you click on any button, the widget with the buttons removed?
First, save a reference to the widget that you want to remove:
def build(self):
self.bl = BoxLayout(orientation='horizontal', padding=[50, 100, 50, 150], spacing=5)
self.bl.add_widget(Button(text='1', on_press=self.first, font_size=20, size_hint=(.3, .1)))
self.bl.add_widget(Button(text='2', on_press=self.second, font_size=20, size_hint=(.3, .1)))
# self.bl.add_widget( Button(text = 'Wallpaper mode', on_press = self.wallpaper, font_size = 20, size_hint = (.3, .1)))
wid = FloatLayout()
wid.add_widget(ScraperApp().PhotGif())
wid.add_widget(self.bl)
return wid
Then modify the first() method to remove it:
def first(self, instance):
print('Horny mode')
instance.text = 'кнопка нажата'
self.root.remove_widget(self.bl)
self.stop()
Note that the code:
ScraperApp().build().remove_widget(bl)
creates a new instance of the ScaperApp and tried to remove bl from that instance. Aside from other problems, nothing you do to that new instance will affect the instance that is currntly running.

How to dynamically update markup text in kivy modalview

I am trying to update a label field dynamically from the contents of a TextInput in a ModalView. The idea is that in the TextInput one enters plain text including markup formatting and you will see the results directly in the Label field with markup = True.
Unfortunately I do not know how to access the Label item in the ModalView. Who can help? See the example code below.
Thanks in advance.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.modalview import ModalView
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.properties import ObjectProperty, StringProperty
kv = """
<Test>:
canvas:
Color:
rgba: 0.4, 0.5, 0.6, 1
Rectangle:
size: self.size
pos: self.pos
Button:
size_hint: None, None
size: 3 * dp(48), dp(48)
text: 'Edit'
on_press: root.showedit()
"""
Builder.load_string(kv)
class Test(BoxLayout):
minput_text = StringProperty('Welcome')
txtresult = ObjectProperty()
def showedit(self):
mview = ModalView(id='mviewid', size_hint=(0.4, 0.6), auto_dismiss=False, background='./images/noimage.png')
mblt = BoxLayout(orientation='vertical', padding=(24))
minp = TextInput(id='inptxt', text='', hint_text='Start typing text with markup here', size_hint=(1,0.5),multiline=True)
minp.bind(text=self.on_inptext)
mtxt = Label(id='txtresult',text='displays formatted text', color=(0.3,0.3,0.3), size_hint=(1,0.5),markup=True)
mcnf = Button(text='OK', size=(144,48), size_hint=(None,None))
mcnf.bind(on_press=mview.dismiss)
mblt.add_widget(minp)
mblt.add_widget(mtxt)
mblt.add_widget(mcnf)
mview.add_widget(mblt)
mview.bind(on_dismiss=self.print_text)
mview.open()
def on_inptext(self, instance, value):
self.minput_text = value
def print_text(self, *args):
print self.minput_text
class TestApp(App):
def build(self):
return Test()
if __name__ == '__main__':
TestApp().run()
You have to make a binding between the TextIntput text and the Label, for this we can use a lambda function and setattr.
class Test(BoxLayout):
minput_text = StringProperty('Welcome')
txtresult = ObjectProperty()
def showedit(self):
mview = ModalView(id='mviewid', size_hint=(0.4, 0.6), auto_dismiss=False, background='./images/noimage.png')
mblt = BoxLayout(orientation='vertical', padding=(24))
minp = TextInput(id='inptxt', text='', hint_text='Start typing text with markup here', size_hint=(1,0.5),multiline=True)
minp.bind(text=self.on_inptext)
mtxt = Label(id='txtresult',text='displays formatted text', color=(0.3,0.3,0.3), size_hint=(1,0.5),markup=True)
mcnf = Button(text='OK', size=(144,48), size_hint=(None,None))
mcnf.bind(on_press=mview.dismiss)
mblt.add_widget(minp)
mblt.add_widget(mtxt)
mblt.add_widget(mcnf)
mview.add_widget(mblt)
mview.bind(on_dismiss=self.print_text)
# binding between TextInput text and Label text
minp.bind(text=lambda instance, value: setattr(mtxt, 'text',value))
mview.open()
def on_inptext(self, instance, value):
self.minput_text = value
def print_text(self, *args):
print(self.minput_text)

How can I make the program restart in kivy?

I am a newbie in kivy. I made a tic tac toe game, but when one of the player wins I want the game to restart so, the players can play it again. How can I make this in kivy or should I reset the buttons and lists that the game based on? I have tried many things like
self.clear_widgets()
but it didn't work
this is the main.py
from kivy.app import App
from kivy.properties import OptionProperty, ObjectProperty
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
class Option():
p1 = []
p2 = []
activeplayer = 1
class TicTable(BoxLayout):
pass
class EntryButton(Button):
opt = Option()
obj = ObjectProperty()
a = ObjectProperty()
def setButton(self, p):
self.obj.text = p
self.obj.disabled = True
def show_winner(self, win_player):
if win_player:
popup = Popup(title="There is a Winner", content=Label(text=win_player), size_hint=(None, None), size=(200, 200))
popup.open()
def check_winner(self):
p1_list = set(self.opt.p1)
p2_list = set(self.opt.p2)
winner = None
winning = [{1, 2, 3}, {4, 5, 6}, {7, 8, 9},
{1, 4, 7}, {2, 5, 8}, {3, 6, 9}]
for i in winning:
if p1_list.intersection(i) == i:
winner = "Player X is the Winner"
self.show_winner(winner)
break
elif p2_list.intersection(i) == i:
winner = "Player O is the Winner"
self.show_winner(winner)
break
def play(self):
if self.opt.activeplayer == 1:
self.setButton("X")
self.opt.p1.append(self.obj.n)
self.check_winner()
self.opt.activeplayer =2
elif self.opt.activeplayer ==2:
self.setButton("O")
self.opt.p2.append(self.obj.n)
self.check_winner()
self.opt.activeplayer = 1
class TicTacToeApp(App):
pass
if __name__ == '__main__':
TicTacToeApp().run()
and this is the tictactoe.kv
<EntryButton>:
obj: obj
id: obj
on_press: root.play()
<TicTable>:
orientation: "vertical"
BoxLayout:
EntryButton:
n:1
text: ""
EntryButton:
n:2
text: ""
EntryButton:
n:3
text:""
BoxLayout:
EntryButton:
n:4
text: ""
EntryButton:
n:5
text: ""
EntryButton:
n:6
text: ""
BoxLayout:
EntryButton:
n:7
text: ""
EntryButton:
n:8
text: ""
EntryButton:
n:9
text: ""
TicTable:
Your TicTacToeApp should have the build method that returns a widget.
I will give you an example, where it is a quiz app, when the correct button is pressed (or released, in kivy lang), the app will update its quiz.
import random
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
Q_sets = ["1+1=...","1+6=...","77-43=..."];
Opt_sets = [["2", "23"], ["4","7"], ["34","66"]];
Ans_sets = ["2","7", "34"];
class Option(Button):
def __init__(self, label):
super().__init__(self);
self.text = label;
def on_release(self):
super().on_release(self);
if self.text == self.parent.answer:
self.parent.parent.clear_widgets();
index = int(random.uniform(0, 3));
New = Quiz(Q_sets[index], Opt_sets[index][0], Opt_sets[index][1], Ans_sets[index]);
self.parent.parent.add_widget(New);
class Quiz(GridLayout):
def __init__(self, question, opt1, opt2, correct):
super().__init__(self, rows=3, cols=1);
self.question_label = Label(text=question);
self.opt1_button = Option(label=opt1);
self.opt2_button = Option(label=opt2);
self.answer=correct;
self.add_widget(self.question_label);
self.add_widget(self.opt1_button);
self.add_widget(self.opt2_button);
class QuizzesApp(App):
def build(self):
Container = GridLayout();
Container.add_widget(Quiz(Q_sets[0], Opt_sets[0][0], Opt_sets[0][1], Ans_sets[0]));
return Container
You may study this, and then improvise for your own case. Is this okay?

Categories

Resources