Can't get ObjectProperty to work with Kivy in python - python

I've been trying to fine a solution for a while. I rather not create the button in python, as I'm trying to keep the style away from the functionality. It reports this error every time I try to use Object Property. I've scoured all over trying a bunch of solutions on stackoverflow, so I'm hoping someone can help me out.
TypeError: bind() takes exactly 2 positional arguments (0 given)
As for the actual code, here is the python:
# Function import libraries
import sys
import json
import googlemaps
import pygatt
import time
import asyncio
from bleak import discover
from urllib.request import urlopen
from twilio.rest import Client
import asynckivy as ak
from asynckivy.process_and_thread import \
thread as ak_thread, process as ak_processt
# UI import libraries
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.label import Label
from kivy.uix.image import Image
from functools import partial
from kivy.event import EventDispatcher
class Screen1(Screen):
def __init__ (self,**kwargs):
super (Screen1, self).__init__(**kwargs)
pairbtn = ObjectProperty(None)
pairbtn.bind(on_press=self.pair_pressed)
# self.add_widget(pairbtn)
def pair_pressed(self, event):
async def run():
devices = await discover()
for d in devices:
print(d)
if (str(d).find('DSD TECH') != -1):
address = str(d)[0:17]
print("Device Discovered" + address)
exit()
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
class Screen2(Screen):
pass
class esosApp(App):
def build(self):
screen_manager = ScreenManager()
screenone = Screen1(name='s1')
screentwo = Screen2(name='s2')
screen_manager.add_widget(screenone)
screen_manager.add_widget(screentwo)
return screen_manager
if __name__ == '__main__':
esosApp().run()
And here is the kv file (screen2 omitted):
#:kivy 1.11.1
<Screen1>:
orientation: "vertical"
pairbtn: pairbtn
canvas.before:
Color:
rgb: 0.965,0.965, 0.965
Rectangle:
pos: self.pos
size: self.size
Image:
source: 'icon.png'
size: self.texture_size
AnchorLayout:
anchor_y: 'top'
BoxLayout:
size_hint: 1,.07
canvas.before:
Color:
rgb: 0.6745 , 0.8353 , 0.8784
Rectangle:
pos: self.pos
size: self.size
Image:
source: 'Logo.PNG'
size: self.texture_size
AnchorLayout:
anchor_x: 'center'
anchor_y: 'bottom'
padding: (0, 10, 0, 10)
Button:
id: pairbtn
text: "Pair Device"
background_normal: ''
background_color: 0.6745 , 0.8353 , 0.8784, 1
size_hint: (.8, .1)

A property should not and cannot be declared within a method of the class but at the same level of a method, something like:
class Foo(Base):
prop = XProperty(default_value)
def __init__(self, **kwargs):
super().__init__(self, **kwargs)
# ...
And clearly your code does not meet that condition, also with your logic pairbtn is None so you cannot make the binding with on_press, and finally the easiest thing is to make the connection in kv:
# ...
Button:
id: pairbtn
text: "Pair Device"
background_normal: ''
background_color: 0.6745 , 0.8353 , 0.8784, 1
size_hint: (.8, .1)
on_press: root.pair_pressed()

Related

Kivy with asyncio. Error when changing screen in .kv file

I have cut down my code to focus on only the problem I have.
The asyncio part of my code is working -I have left stubs for these procs.
When I incorporated my user interface kivy code and my asyncio kivy code, I get the above error on a screen change.
I think I need to get an "App" setup with Builder.load_file() inside it ??, but my attempts to do so have failed.
Hope someone can help ?
On clicking the "Post a Photo!" button I get this error...
File "C:\TEMP\kivy1\kivy_venv\src\screens.kv", line 31, in <module>
on_press: app.switch_screen='TakePhotoScreen'
File "C:\TEMP\kivy1\kivy_venv\lib\site-packages\kivy\lang\parser.py", line 83, in __setattr__
object.__getattribute__(self, '_ensure_app')()
File "C:\TEMP\kivy1\kivy_venv\lib\site-packages\kivy\lang\parser.py", line 70, in _ensure_app
app.bind(on_stop=lambda instance:
AttributeError: 'NoneType' object has no attribute 'bind'
Code: screen.kv
Manager:
TestMyFeedScreen3:
TakePhotoScreen:
#:import ScrollEffect kivy.effects.scroll.ScrollEffect
#:import Window kivy.core.window.Window
<TestMyFeedScreen3>:
name:'TestMyFeedScreen3'
id:TestMyFeedScreen3
orientation: 'vertical'
GridLayout:
cols:1
rows:2
height: 50
Label:
text: 'My Story'
size_hint_y: None
height: 50
GridLayout:
cols:2
rows:1
height: 50
Button:
text: 'Post a Photo!'
size_hint_y: None
height: '48dp'
# ERROR HERE >>>>>>>>>>>>>>>>>>>>>>>>>>>>
#on_press: app.root.current='TakePhotoScreen'
on_press: app.switch_screen='TakePhotoScreen'
Button:
text: 'Back'
size_hint_y: None
height: '48dp'
on_release:
app.root.current='TestMyFeedScreen3'
root.manager.transition.direction = "left"
ScrollView:
effect_cls: ScrollEffect
size_hint: 1, None
size: Window.width, (Window.height -100)
bar_width: 5
bar_color: 1, 0, 0, 1 # red
bar_inactive_color: 0, 0, 1, 1 # blue
scroll_type: ['bars','content'] # move scrool by bar or photos
GridLayout:
id:picsx
do_scroll_x: False
height: self.minimum_height
size_hint_y: None
spacing: 3, 3
cols: 3
Button:
#text:'Pic'
background_normal: "Image1.PNG"
background_down: 'Click.PNG'
size_hint_y:None
height:100
<TakePhotoScreen>:
name:'TakePhotoScreen'
orientation: 'vertical'
GridLayout:
cols:1
rows:3
Button:
text: 'Take Photo and Post It !'
size_hint_y: None
height: '48dp'
Button:
text: 'Back'
size_hint_y: None
height: '48dp'
Image:
id: imageView
source: 'mob_photo.jpg'
allow_stretch: True
Code: mainx.py
# This code has been cut down to focus on the error
from __future__ import print_function
import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.lang import Builder
from kivy.config import Config
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
import asyncio
from kivy.app import async_runTouchApp
from kivy.cache import Cache
import aioconsole
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
images = 1
#client_number = sys.argv[1]
client_number = "0"
print("This is client " + client_number)
Config.set('graphics', 'width', '380')
Config.set('graphics', 'height', '700')
async def send_messages(writer, stdin):
print("In send_messages stub")
async def receive_messages(reader, stdout):
print("In receive_messages stub")
async def run_client():
print("In run_client")
Code
# This code has been cut down to focus on the error
from __future__ import print_function
import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.lang import Builder
from kivy.config import Config
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
import asyncio
from kivy.app import async_runTouchApp
from kivy.cache import Cache
import aioconsole
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
images = 1
#client_number = sys.argv[1]
client_number = "0"
print("This is client " + client_number)
Config.set('graphics', 'width', '380')
Config.set('graphics', 'height', '700')
async def send_messages(writer, stdin):
print("In send_messages stub")
async def receive_messages(reader, stdout):
print("In receive_messages stub")
async def run_client():
print("In run_client")
# Screen code
class TestMyFeedScreen3(Screen):
pass
class TakePhotoScreen(Screen):
pass
class Manager(ScreenManager):
pass
kv=Builder.load_file('screens.kv')
root = kv
async def run_app_happily(root, other_task):
# This method, which runs Kivy, is run by the asyncio loop as one of the coroutines.
# we don't actually need to set asyncio as the lib because it is the
# default, but it doesn't hurt to be explicit
await async_runTouchApp(root, async_lib='asyncio') # run Kivy
print('App done')
# now cancel all the other tasks that may be running
other_task.cancel()
if __name__ == '__main__':
def root_func():
while True:
print("In __main__")
other_task = asyncio.ensure_future(run_client())
return asyncio.gather(run_app_happily(kv, other_task), other_task)
loop = asyncio.get_event_loop()
loop.run_until_complete(root_func())
loop.close()
Since you don't have an actual App in your code, you cannot reference it in the line:
on_press: app.switch_screen='TakePhotoScreen'
but you can reference the ScreenManager and change the current Screen like this:
Button:
text: 'Post a Photo!'
size_hint_y: None
height: '48dp'
# ERROR HERE >>>>>>>>>>>>>>>>>>>>>>>>>>>>
on_press: root.manager.current='TakePhotoScreen'
You have a similar situation elsewhere in your code.

How to run a function several times but run the instruction list only once?

I made a program with several buttons and I wish that when I press the button several times, the list of instructions only launches once.
I tried to do it with a global variable but when I want to use the same variable for both screens, I can’t do it.
I know I can do it using two global variables but I would like to use the same one in both screens.
How, when we get to the second screen, u takes the value "True"? Or is there a simpler solution with a decorator?
Here is my code:
import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
import random
from kivy.properties import ObjectProperty
from kivy.properties import ListProperty, StringProperty
kivy.uix.screenmanager.FadeTransition
kv = """
#: import NoTransition kivy.uix.screenmanager.NoTransition
#:import Clock kivy.clock.Clock
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
#: import RiseInTransition kivy.uix.screenmanager.RiseInTransition
#: import CardTransition kivy.uix.screenmanager.CardTransition
MyScreenManager:
transition: RiseInTransition()
Question1:
name: "question1"
Question2:
name: "question2"
<Question1>:
label_wid : ratio
FloatLayout:
Button:
text: "+1"
pos: 270, 300
size_hint: .30, .10
background_color: 0,1,0,0.75
on_press:
root.mauvais()
Button:
text: "following"
pos: 270, 240
size_hint: .30, .10
background_color: 0,1,0,0.75
on_press:
Clock.schedule_once(root.suite, 0.75)
Label:
id: ratio
text: root.manager.theText
pos: 280,270
font_size: 17
color: 0,0,1,0.65
<Question2>:
label_wid2: ratio
FloatLayout:
Button:
text: "+1"
pos: 270, 300
size_hint: .30, .10
background_color: 0,1,0,0.75
on_press:
root.mauvais()
Label:
id: ratio
text: root.manager.theText
pos: 280,270
font_size: 17
color: 0,0,1,0.65
"""
t=0
m=True
class MyScreenManager(ScreenManager):
theText = StringProperty('')
class Question1(Screen):
m= True
def mauvais(self):
global m
if m==True:
global t
t=t+1
self.manager.theText = str(t)
m=False
def suite(root,text):
root.manager.current = "question2"
pass
class Question2(Screen):
global m
m= True
def mauvais(self):
global m
if m==True:
global t
t=t+1
self.manager.theText = t
m=False
pass
class Quizz(App):
def build(self):
self.title = 'Quizz'
Window.clearcolor = (0, 1, 1, 0.25)
return Builder.load_string(kv)
if __name__ == '__main__':
Quizz().run()
So, since I didn't get an answer to my question, I have a proposed solution that does both possibilities:
import kivy
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import StringProperty, BooleanProperty, NumericProperty
kivy.uix.screenmanager.FadeTransition
kv = """
#: import NoTransition kivy.uix.screenmanager.NoTransition
#:import Clock kivy.clock.Clock
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
#: import RiseInTransition kivy.uix.screenmanager.RiseInTransition
#: import CardTransition kivy.uix.screenmanager.CardTransition
MyScreenManager:
transition: RiseInTransition()
Question1:
name: "question1"
Question2:
name: "question2"
<Question1>:
label_wid : ratio
FloatLayout:
Button:
text: "+1"
pos: 270, 300
size_hint: .30, .10
background_color: 0,1,0,0.75
on_press:
root.manager.mauvais() # method is now in MyScreenManager
Button:
text: "following"
pos: 270, 240
size_hint: .30, .10
background_color: 0,1,0,0.75
on_press:
Clock.schedule_once(root.suite, 0.75)
Label:
id: ratio
text: root.manager.theText
pos: 280,270
font_size: 17
color: 0,0,1,0.65
<Question2>:
label_wid2: ratio
FloatLayout:
Button:
text: "+1"
pos: 270, 300
size_hint: .30, .10
background_color: 0,1,0,0.75
on_press:
root.manager.mauvais() # method is now in MyScreenManager
Label:
id: ratio
text: root.manager.theText
pos: 280,270
font_size: 17
color: 0,0,1,0.65
"""
# time to ignore additional clicks
# if this is zero, ignore all additional clicks
CLICK_IGNORE_TIME = 3
class MyScreenManager(ScreenManager):
theText = StringProperty('')
m = BooleanProperty(True)
t = NumericProperty(0)
def mauvais(self):
if self.m==True:
self.t += 1
self.theText = str(self.t)
self.m=False
if CLICK_IGNORE_TIME > 0:
Clock.schedule_once(self.reset_m, CLICK_IGNORE_TIME)
else:
print('ignored click')
def reset_m(self, dt):
print('reset m')
self.m = True
class Question1(Screen):
def suite(root,text):
root.manager.current = "question2"
class Question2(Screen):
pass
class Quizz(App):
def build(self):
self.title = 'Quizz'
Window.clearcolor = (0, 1, 1, 0.25)
return Builder.load_string(kv)
if __name__ == '__main__':
Quizz().run()
This code moves the mauvais() method to the MyScreenManager class, since both versions were identical.
The CLICK_IGNORE_TIME is how long to ignore additional clicks. If it is zero all additional clicks will be ignored

How to Change BG Color of Dynamically Created Widget with On_Press and Save with Pickle? (Python with Kivy)

Goal:
Change background color of dynamically created widget with on-press.
Save this state with pickle such that when I open the program back up, the new color change is preserved
Note: You'll see in my code that I haven't made an attempt on saving the button bg color state to a file yet, as I'm still trying to get the on-press event to function.
I get the following error:
File "C:/Users/phili/scrollablelabelexample.py", line 45, in create_button
button_share.bind(on_press = self.update_buttons_departoverride(self))
TypeError: update_buttons_departoverride() takes 1 positional argument but 2 were given
Python code:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.textinput import TextInput
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.scrollview import ScrollView
from kivy.properties import StringProperty, ObjectProperty, NumericProperty
from kivy.clock import Clock
import pandas as pd
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
class AnotherScreen(Screen):
pass
class BackHomeWidget(Widget):
pass
class Sequence(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class MainScreen(Screen):
pass
class CleanScreen(BoxLayout):
def __init__(self, **kwargs):
super(CleanScreen, self).__init__(**kwargs)
self.orientation = "vertical"
Clock.schedule_once(lambda *args:self.create_button(self.ids.box_share))
def create_button(self, box_share):
top_button_share = 1.1
color = [.48,.72,.23,1]
for i in range(len(parts)):
top_button_share -= .4
button_share = Button(background_normal = '', background_color = color, id = "part"+str(i+1),pos_hint={"x": 0, "top": top_button_share}, size_hint_y=None, height=60, text=str(i))
button_share.bind(on_press = self.update_buttons_departoverride(self))
box_share.add_widget(button_share)
def update_buttons_departoverride(self):
self.background_color = 1.0, 0.0, 0.0, 1.0
presentation = Builder.load_file("garagemainexample.kv")
class MainApp(App):
def build(self):
return presentation
if __name__ == "__main__":
MainApp().run()
Kv Code:
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManagement:
transition: FadeTransition()
MainScreen:
Sequence:
<BigButton#Button>:
font_size: 40
size_hint: 0.5, 0.15
color: 0,1,0,1
<SmallNavButton#Button>:
font_size: 32
size: 125, 50
color: 0,1,0,1
<BackHomeWidget>:
SmallNavButton:
on_release: app.root.current = "main"
text: "Home"
pos: root.x, root.top - self.height
<MainScreen>:
name: "main"
FloatLayout:
BigButton:
on_release: app.root.current = "sequence"
text: "Sequence"
pos_hint: {"x":0.25, "top": 0.4}
<CleanScreen>:
ScrollView:
GridLayout:
id: box_share
cols: 1
size_hint_y: None
size_hint_x: 0.5
spacing: 5
padding: 90
height: self.minimum_height
canvas:
Color:
rgb: 0, 0, 0
Rectangle:
pos: self.pos
size: self.size
<Sequence>:
name: "sequence"
CleanScreen:
id: cleanscreen
BackHomeWidget:
With button_share.bind (on_press = self.update_buttons_departoverride (self)) you're calling the method, so you're trying to bind on_press with None (self.update_buttons_departoverride return None). If you want to pass arguments, use lambda or functools.partial:
from functools import partial
button_share.bind(on_press=partial(self.update_buttons_departoverride, arg1,...))
However, if you need to pass only the button's reference, it is already passed automatically. You just have to do:
button_share.bind(on_press=self.update_buttons_departoverride)
and:
def update_buttons_departoverride(self, button):
To store the configuration of your widgets you can use Storage. A simplified example using DictStore:
main.py:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.widget import Widget
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.properties import ObjectProperty
from kivy.storage.dictstore import DictStore
class AnotherScreen(Screen):
pass
class BackHomeWidget(Widget):
pass
class Sequence(Screen):
pass
class ScreenManagement(ScreenManager):
pass
class MainScreen(Screen):
pass
class CleanScreen(BoxLayout):
box_share = ObjectProperty()
config_file = DictStore('conf.dat')
def __init__(self, **kwargs):
super(CleanScreen, self).__init__(**kwargs)
self.orientation = "vertical"
Clock.schedule_once(self.create_button)
def create_button(self, *args):
top_button_share = 1.1
color = (.48, .72, .23, 1)
for i in range(5):
top_button_share -= .4
id_ = "part" + str(i + 1)
if self.config_file.exists(id_):
btn_color = self.config_file[id_]["background_color"]
else:
self.config_file.put(id_, background_color=color)
btn_color = color
button_share = Button(background_normal='',
background_color=btn_color,
id=id_,
pos_hint={"x": 0, "top": top_button_share},
size_hint_y=None,
height=60,
text=str(i))
button_share.bind(on_press=self.update_buttons_departoverride)
self.box_share.add_widget(button_share)
def update_buttons_departoverride(self, button):
button.background_color = 1.0, 0.0, 0.0, 1.0
self.config_file.put(button.id, background_color=(1.0, 0.0, 0.0, 1.0))
presentation = Builder.load_file("garagemainexample.kv")
class MainApp(App):
def build(self):
return presentation
if __name__ == "__main__":
MainApp().run()
garagemainexample.kv:
#: import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManagement:
transition: FadeTransition()
MainScreen:
Sequence:
<BigButton#Button>:
font_size: 40
size_hint: 0.5, 0.15
color: 0,1,0,1
<SmallNavButton#Button>:
font_size: 32
size: 125, 50
color: 0,1,0,1
<BackHomeWidget>:
SmallNavButton:
on_release: app.root.current = "main"
text: "Home"
pos: root.x, root.top - self.height
<MainScreen>:
name: "main"
FloatLayout:
BigButton:
on_release: app.root.current = "sequence"
text: "Sequence"
pos_hint: {"x":0.25, "top": 0.4}
<CleanScreen>:
box_share: box_share
ScrollView:
GridLayout:
id: box_share
cols: 1
size_hint_y: None
size_hint_x: 0.5
spacing: 5
padding: 90
height: self.minimum_height
canvas:
Color:
rgb: 0, 0, 0
Rectangle:
pos: self.pos
size: self.size
<Sequence>:
name: "sequence"
CleanScreen:
id: cleanscreen
BackHomeWidget:

Scrollview to display different videos in kivy lags after a while

I'm a beginner in kivy and python. I've been trying to create a scrollview in a page that displays selected video on the screen. But after a while when i selected 5-6 videos to display even though i delete the video widget it starts to lag. And i'm open to any suggestions to better way to handle this kind of application.
from kivy.config import Config
Config.set('graphics', 'width', '1920')
Config.set('graphics', 'height', '1080')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.properties import StringProperty
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.uix.button import Button
import os
from kivy.uix.video import Video
from kivy.uix.videoplayer import VideoPlayer
from kivy.clock import mainthread
from functools import partial
from kivy.core.window import Window
Window.clearcolor = (0, 0, 0, 0)
isThereVideo=False
picture_path="/home/linux/kivyFiles/kivyLogin/assets"
video_path="/home/linux/kivyFiles/kivyLogin/videoAssets/"
class Image(Image):
pass
class MainScreen(Screen):
pass
class AnotherScreen(Screen):
pass
class Selfie(Screen):
pass
class RootWidget(Widget):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
Clock.schedule_once(self.createMultipleButton)
#mainthread
def createMultipleButton(self, dt):
self.root = Widget()
size_y=150;
size_x=150;
for i in range(1):
folderList = os.listdir(picture_path)
if len(folderList)==0:
time.sleep(1)
break
fileList = os.listdir(picture_path)
print fileList
for file in fileList:
x = (picture_path+"/"+file)
button = Button(id=str(file),text="" + str(file),size_hint=(None, None),height=size_y,width=size_x, pos_hint={'x': 0, 'y': 1},background_normal=x)
button.bind(on_release=partial(self.VideoContainer, file))
print file
self.scrollview.content_layout.add_widget(button)
print button.id
print("Parent of ScreenTwo: {}".format(self.parent))
#print(button.pos)
def VideoContainer(self,name,btn):
global isThereVideo
if isThereVideo==True:
#self.videocontainer.video_layout.unload()
self.videocontainer.clear_widgets()
mylist=name.split('.')
emailButton = Button(id='email')
video = Video(source="/home/linux/kivyFiles/kivyLogin/videoAssets/"+mylist[0]+".mp4", state='play',options={'eos': 'loop'})
video.size=(self.parent.width,self.parent.height)
video_pos=(self.parent.x,self.parent.y)
#video.pos_hint={'x': self.parent.width /2, 'y': self.parent.height/2}
video.play=True
#video.pos=(self.parent.width /2 , self.parent.height/2)
#self.videocontainer.video_layout.add_widget(emailButton)
self.videocontainer.add_widget(emailButton)
emailButton.add_widget(video)
isThereVideo=True
print("Parent of ScreenTwo: {}".format(self.parent))
return 0
class ScreenManagement(ScreenManager):
pass
class VideoContain(Widget):
pass
class ScrollableContainer(ScrollView):
pass
presentation = Builder.load_file("login.kv")
class MainApp(App):
def build(self):
return presentation
if __name__ == '__main__':
Window.fullscreen = True
app=MainApp()
app.run()
And my Kv file
ScreenManagement:
MainScreen:
Selfie:
<MainScreen>:
name: 'main'
Button:
on_release: app.root.current = 'selfie'
text: 'Another Screen'
font_size: 50
<Selfie>:
name: 'selfie'
Button:
on_release: app.root.current = 'login'
text: 'Selfie Screen'
font_size: 10
pos_hint: {"right": 1, 'top':1}
size_hint: (0.1, 0.1)
RootWidget:
<RootWidget>
size_hint: (0.1, None)
scrollview: scrollview
videocontainer:videocontainer
size:(self.parent.width, self.parent.height)
VideoContain:
id:videocontainer
##size:(self.parent.width, self.parent.height)
size:(root.width, root.height)
ScrollableContainer:
id: scrollview
size: root.size
pos: root.pos
<VideoContain>
video_layout:video_layout
FloatLayout:
cols:1
id: video_layout
<ScrollableContainer>:
scroll_timeout: 75
scroll_distance: 10
app: app
content_layout: content_layout
GridLayout:
id: content_layout
cols: 1
size_hint: (0.1, None)
pos: root.pos
height: self.minimum_height
padding: 25
spacing: 25
I posted all my code since i don't know which part may causing the problem i'm facing.
Solved it.
def VideoContainer(self,name,btn):
global isThereVideo
if isThereVideo:
# self.videocontainer.video_layout.unload()
self.videocontainer.clear_widgets()
In this part i'm clearing the widgets but i also need to unload the video somehow.
self.video.unload() solved my problem

Custom Closable Tab in Kivy

I am trying to implement a custom closable tab header in kivy.
What I did was combine a class:TabbedPanelHeader object with a custom class:CloseButton object. Both of these widgets are inside a class:BoxLayout, side-by-side.
However, once I add this into a class:TabbedPanel object, nothing shows up..
I am not sure how to move forward and would greatly appreciate all the help!
Below is the relevant part of the code.
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.graphics import *
from kivy.uix.tabbedpanel import TabbedPanelHeader
class CloseButton(ButtonBehavior, Image):
def __init__(self, **kwargs):
super(CloseButton, self).__init__(**kwargs)
self.source = 'atlas://data/images/defaulttheme/close'
self.size_hint_x = .2
def on_press(self):
self.source = 'atlas://data/images/defaulttheme/checkbox_radio_off'
def on_release(self):
self.source = 'atlas://data/images/defaulttheme/checkbox_radio_off'
## do the actual closing of the tab
class ClosableTabHeader(BoxLayout):
def __init__(self, **kwargs):
super(ClosableTabHeader, self).__init__(**kwargs)
self.size = (100, 30)
self.size_hint = (None, None)
self.canvas.before.add(Color(.25, .25, .25))
self.canvas.before.add(Rectangle(size=(105, 30)))
self.add_widget(TabbedPanelHeader(background_color=(.65, .65, .65, 0), text='testing'))
self.add_widget(CloseButton())
if __name__ == '__main__':
from kivy.app import App
class TestApp(App):
def build(self):
return ClosableTabHeader()
TestApp().run()
Here is some code which comes close to achieve what you are trying to achieve
from kivy.app import App
from kivy.animation import Animation
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelHeader
from kivy.factory import Factory
from kivy.lang import Builder
class CloseableHeader(TabbedPanelHeader):
pass
class TestTabApp(App):
def build(self):
return Builder.load_string('''
TabbedPanel:
do_default_tab: False
FloatLayout:
BoxLayout:
id: tab_1_content
Label:
text: 'Palim 1'
BoxLayout:
id: tab_2_content
Label:
text: 'Palim 2'
BoxLayout:
id: tab_3_content
Label:
text: 'Palim 3'
CloseableHeader:
text: 'tab1'
panel: root
content: tab_1_content.__self__
CloseableHeader:
text: 'tab2'
panel: root
content: tab_2_content.__self__
CloseableHeader:
text: 'tab3'
panel: root
content: tab_3_content.__self__
<CloseableHeader>
color: 0,0,0,0
disabled_color: self.color
# variable tab_width
text: 'tabx'
size_hint_x: None
width: self.texture_size[0] + 40
BoxLayout:
pos: root.pos
size_hint: None, None
size: root.size
padding: 3
Label:
id: lbl
text: root.text
BoxLayout:
size_hint: None, 1
orientation: 'vertical'
width: 22
Image:
source: 'tools/theming/defaulttheme/close.png'
on_touch_down:
if self.collide_point(*args[1].pos) :\
root.panel.remove_widget(root); \
''')
if __name__ == '__main__':
TestTabApp().run()
It is based on https://github.com/kivy/kivy/blob/master/examples/widgets/tabbed_panel_showcase.py

Categories