How to share input between popup and screen in Kivy? - python

I would like to "send" input2 from class Create to class(screen) All. For example I could method which add label with text = input2. How to do it?
My .py:
from kivy.app import App
import sys
from kivy.clock import Clock
from kivy.core.clipboard import Clipboard
from tinydb import TinyDB, Query
from kivy.storage.jsonstore import JsonStore
from kivy.graphics import RoundedRectangle, Color
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.uix.floatlayout import FloatLayout
from kivy.lang.builder import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.core.window import Window
Window.size=(400,600)
Window.clearcolor = (214/255, 201/255, 78/255, 1)
#TODO:JSONSTORE,LAYOUT,IF TIME:GRAPHICAL NOTES
#FIX SIZE_HINT AND POS_HINT
class MainWindow(Screen, FloatLayout):
def submit(self):
self.manager.current = "all"
class Create(Popup):
input1 = ObjectProperty(None)
input2 = ObjectProperty(None)
def clear(self):
self.input1.text = ""
self.input2.text = ""
def give(self, *args):
name = (self.input2.text + ".json")
if self.input2.text:
with open(name, 'w') as fp:
store = JsonStore(name)
store['001'] = {self.input2.text:self.input1.text}
class All(Screen,FloatLayout):
def opening(self):
crt = Create()
crt.open()
def test(self):
print("Worked")
def closing(self):
crt = Create()
crt.dismiss()
def __init__(self, **kwargs):
super(All, self).__init__(**kwargs)
class Note(Screen, FloatLayout):
pass
class Notes(App):
title = "NOTES"
def build(self):
Builder.load_file("001.kv")
sm = ScreenManager()
sm.add_widget(MainWindow(name="main"))
sm.add_widget(All(name="all"))
sm.add_widget(Note(name="note"))
return sm
if __name__ == "__main__":
Notes().run()
My .kv:
<MainWindow>:
name:"main"
canvas:
Color:
rgba : 255,255,255,1
RoundedRectangle:
pos:(95, 450)
size : 210,120
radius: [30, 30, 30, 30]
FloatLayout:
Label:
text:"NOTES"
pos:(100,450)
size_hint:(.5,.2)
color:0,0,0,1
Label:
text: "simple"
pos:(100,425)
size_hint:(.5,.2)
color:0,0,0,1
Button:
text:"ALL NOTES"
pos :(100, 180)
size_hint : (.5,.2)
on_release:app.root.current="all"
Button:
text:"EXIT"
pos :(100, 60)
size_hint : (.5,.2)
on_release:app.stop()
<Create>:
title:"ADD"
input1:input1
input2:input2
size_hint: .5,.8
auto_dismiss:True
BoxLayout:
orientation:"vertical"
pos:self.pos
size:root.size
TextInput:
id:input2
size_hint: 1,.1
multiline: False
hint_text:"Your note name here"
TextInput:
id:input1
multiline: True
hint_text:"Your note here"
Button:
id:save
text:"SAVE"
size_hint:1,.2
on_release:root.give()
<All>:
FloatLayout:
Button:
text:"back"
size_hint:(1,.2)
pos_hint:{"x":0,"top":.2}
on_release:app.root.current="main"
Button:
background_color: (214/255, 201/255, 78/255, 0)
text: '+'
on_release:root.opening()
size_hint:(.2,.1)
pos_hint:{"x":.8,"top":1}
Button:
background_color: (214/255, 201/255, 78/255, 0)
text: 'INFO'
size_hint:(.2,.1)
pos_hint:{"x":.6,"top":1}
<Note>:
name:"note"
input3 : input3
input4 : input4
FloatLayout:
Label:
text:"NOTE NAME:"
pos_hint:{"x":0.07,"top":.95}
size_hint : (.1,0.05)
TextInput:
id : input3
multiline:True
pos_hint :{"x":.1,"top":.8}
size_hint : (.8,.4)
TextInput:
id:input4
multiline : False
pos_hint:{"x":.25,"top":.95}
size_hint:(.4,0.05)
Button:
id:"submit"
text:"SAVE"
pos_hint :{"x":.25,"top":.4}
size_hint : (.5,.2)
on_release:
app.root.current="all"
root.manager.get_screen("All").test()
root.manager.get_screen("All").closing()
Button:
id:"back"
text:"BACK"
pos_hint :{"x":.25,"top":.2}
size_hint : (.5,.2)
on_release:app.root.current="main"

class All(Screen,FloatLayout):
def __init__(self, **kwargs):
super(All, self).__init__(**kwargs)
self.crt = Create()
def opening(self):
self.crt.open()
def test(self):
print(self.crt.input2.text)
def closing(self):
self.crt.dismiss()

Related

Kivy - Calling a pulsing method from one class to another

I have the following classes in my kivy app, and i would like to call the blink method in my mainApp class. The start pulsing and blink methods enable the MainWindow background to pulse. However it's not working inside the MainWindow class and i need to call it in my mainApp class. Commented out (build method in mainApp) is what i tried, which results to the error Exception: Invalid instance in App.root. My python file:
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivy.core.window import Window
from kivymd.app import MDApp
from kivy.uix.image import Image
from kivy.animation import Animation
from kivy.clock import Clock
from kivy.properties import ColorProperty
from kivy.uix.popup import Popup
from kivy.uix.floatlayout import FloatLayout
from plyer import filechooser
data = ""
class MainWindow(Screen):
def analyze_data(self):
global data
data = self.ids.user_input.text
data = analyze(data)
animated_color = ColorProperty()
pulse_interval = 4
def blink(self):
x = Clock.schedule_once(self.start_pulsing, 5)
return x
def start_pulsing(self, *args):
d = self.pulse_interval / 2
anim = Animation(animated_color=(69/255, 114/255, 147/255, 1), duration=d) + Animation(animated_color=(1, 1, 1, 1), duration=d)
anim.repeat = True
anim.start(self)
class OutputScreen(Screen):
def on_enter(self, *args):
self.ids.output_label.text = data
class mainApp(MDApp):
def __init__(self):
super().__init__()
def choose_file(self):
try:
filechooser.open_file(on_selection = self.handle_selection)
except:
pass
def handle_selection(self,selection):
global path
selection_ls = selection[0]
path = selection_ls
#print(path)
def change_screen(self,screen):
screemanager = self.root.ids['screenmanager']
screemanager.current = screen
def change(self):
self.change_screen('output')
def back(self):
self.change_screen('main')
'''
def build(self):
x = MainWindow().blink()
return x'''
and my kv file:
#:import utils kivy.utils
GridLayout:
cols:1
ScreenManager:
id: screenmanager
MainWindow:
id: main
name: 'main'
OutputScreen:
id: output
name: 'output'
<MainWindow>:
BoxLayout:
orientation:'vertical'
MDBottomNavigation:
panel_color: utils.get_color_from_hex("#ffffff")
MDBottomNavigationItem:
name:'analytics'
text:'analytics'
icon:'account-circle'
FloatLayout:
size: root.width, root.height
canvas.before:
Color:
rgba: root.animated_color
Rectangle:
pos:self.pos
size:self.size
TextInput:
multiline:True
id: user_input1
pos_hint:{"x" : 0.05, "top" : 0.9}
size_hint: 0.9, 0.37
Label:
markup: True
id:input_label
pos_hint:{"x" : 0, "top":1}
size_hint: 1 ,0.08
font_size : 32
bold: True
canvas.before:
Color:
rgb: utils.get_color_from_hex("01121c")
Rectangle:
size: self.size
pos: self.pos
Button:
pos_hint:{"top" : 0.51, "x" : 0.05}
size_hint: (None,None)
width : 150
height : 40
font_size : 23
text:'Submit'
on_press: root.analyze_data()
on_release: app.change()
Button:
pos_hint:{"top":0.42, "x":0.05}
size_hint: (None,None)
width : 150
height : 40
font_size : 23
text:'Upload'
on_release:app.choose_file()
Button:
id:'info_button'
pos_hint:{"top":0.47, "x":0.8}
size_hint: (None,None)
width : 50
height : 22
font_size : 23
text:'i'
on_release:root.analytics_info()
<OutputScreen>:
ScrollView:
GridLayout:
cols:1
MDIconButton:
icon:'arrow-left'
pos_hint:{'top':1,'left':1}
size_hint: 0.1,0.1
user_font_size : '64sp'
on_release: app.back()
Label:
id: output_label
multiline:True
text_size: self.width, None
size_hint: 1, None
height: self.texture_size[1]
color: 0,0,0,1
padding_x: 15
Any help will be much appreciated.
The build() method of an App should return a Widget that will become the root of the App. But your build() method returns a ClockEvent (the return from Clock.schedule_once()). Try changing your build() method to:
def build(self):
x = MainWindow()
x.blink()
return x
Since you do not call Builder.load_file(), I assume that your kv file is named main.kv, and therefore will get loaded automatically. If that is true, then you do not need a build() method at all. Instead add an on_start() method to your mainApp class, like this:
def on_start(self):
self.root.ids.main.blink()

How could I make text input screen after changing the text is automatically deleted, when I go back to login screen

imports:
from kivy.lang import Builder
from kivy.uix.textinput import TextInput
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import StringProperty
from kivy.properties import ObjectProperty
from kivy.uix.label import Label
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
kv = '''
<Login>
name:'Login'
ben: benName.text
pw: passwort.text
knopf: btn
knopff: btnn
GridLayout:
cols: 1
size: root.width,root.height
GridLayout:
cols: 2
Label:
text: "Username"
font_size: 25
TextInput:
id: benName
multiline: False
font_size: 30
Label:
text: "Password"
font_size: 25
bold: True
TextInput:
password: True
id: passwort
multiline: False
font_size: 40
Button:
size_hint: (1.,1.10)
text:" Start "
id: btn
font_size: 40
on_release:
root.manager.current = "data" if passwort.text == "1" and benName.text == "1" else "Login"
root.manager.transition.direction = "down"
Button:
size_hint: (1.,1.10)
text: " Exit "
id: btnn
font_size: 40
on_release: app.stop()
<data>
BoxLayout:
orientation: "vertical"
Label:
text:
"hallo"
Button:
text: " back "
on_press:
root.clear_inputs()
root.manager.current = "Login"
'''
MyApp class:
class Login(Screen):
ben = StringProperty()
pw = StringProperty()
knopf = ObjectProperty()
class MyApp(App):
Builder.load_string(kv)
def build(self):
ms = ScreenManager()
ms.add_widget(Login(name='Login'))
ms.add_widget(data(name='data'))
self.title = "MyApp"
return ms
class data(Screen):
def clear_inputs(self):
login = self.manager.get_screen('Login')
for child in reversed(login.ids.container.children):
if isinstance(child, TextInput):
child.text = ''
if __name__ == '__main__':
MyApp().run()
Just access their IDs in a method and then set their text to "" when entering screen, by using on_pre_enter, this method is fired whenever u enter the screen, even if you leave and enter again, it will run
class Login (Screen):
def on_pre_enter(self):
self.ids['benName'].text = ""
self.ids['passwort'].text = ""

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:

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