Is there a way to remove a widget if (sth)

100 views
Skip to first unread message

Martin Goumard

unread,
Jul 30, 2018, 10:00:08 AM7/30/18
to Kivy users support
Hello all,
Is there a way to remove a widget from the Box Layout ?

Here is my code and in the else statment i just want to simply remove my widget created precedently.

    def spinner(self,*args):
        spinner
= Spinner(text='Deauth')
        box
= BoxLayout()
       
def show_selected_value(spinner, text):
           
print('Choice : ', text)
           
       
if args[1]==True:
           
self.Status="I am active"
            spinner
.bind(text=show_selected_value)
            box
.add_widget(spinner)
            runTouchApp
(box)
       
else:
#Here i want to remove my spinner
           
self.Status="I am inactive"

Thx :) !

ZenCODE

unread,
Jul 31, 2018, 2:17:39 AM7/31/18
to Kivy users support
You need to save a reference to the spinner to do that . So

self.spinner = Spinner(text='Deauth')

Then to remove it,

self.spinner.parent.remove_widget(self.spinner)

Martin Goumard

unread,
Aug 3, 2018, 6:13:48 AM8/3/18
to Kivy users support
Thx a lot, I got this error at line 15 of my kv file...I tried to found why many hours but no lucky...
TypeError: 'Spinner' object is not callable

Here is my py code :https://pastebin.com/kvkAt72y
And here my kv : https://pastebin.com/PFcmNNpv

Martin Goumard

unread,
Aug 3, 2018, 9:54:04 AM8/3/18
to Kivy users support
Ok i comment line 20 (self.spinner= spinner), if i select "no" on my spin (= enter in my if statment l16 in show_selected_value) no probs, my spin dissapear, but if i deselect my checkbox (= enter i my else loop l26), i have the error 
AttributeError: 'NoneType' object has no attribute 'remove_widget'

Here is my new code with the error above now :
https://pastebin.com/b3sZcf24

Thx again.

ZenCODE

unread,
Aug 3, 2018, 1:14:51 PM8/3/18
to Kivy users support
Please could you past the complete, runnable code? Makes it much easier to help with certainty....

Martin Goumard

unread,
Aug 3, 2018, 8:40:32 PM8/3/18
to Kivy users support
No prob, here is it:

Py ->
#! /usr/bin/env python3
# -*- coding: utf-8 -*-

# ex.py

from kivy.uix.gridlayout import GridLayout
from kivy.app import App
from kivy.properties import StringProperty
from kivy.base import runTouchApp
from kivy.uix.spinner import Spinner
from kivy.uix.boxlayout import BoxLayout

class Ex(GridLayout):
   
Status=StringProperty("I am inactive")
   
Status1=StringProperty("I am the inactive member of the group")
   
Status2=StringProperty("I am the inactive member of the group")
   
def checkActive(self,*args):

       
if args[1]==True: self.Status="I am active"

       
else: self.Status="I am inactive"
   
def checkActive1(self,*args):
       
if args[1]==True: self.Status1="I am the active member of the group"
       
else: self.Status1="I am the inactive member of the group"
   
def checkActive2(self,a,b):
       
if b==True: self.Status2="I am active member of the group"
       
else: self.Status2="I am the inactive member of the group"
   
def checkActive3(self,*args):
       
if args[1]==False: self.ids['pythonLang'].active=True

   
def spinner(self,*args):
        spinner
= Spinner(
           
# default value shown
            text
='Deauth',
           
# available values
            values
=('Yes', 'No'),
           
# just for positioning in our example
            size_hint
=(None, None),
            size
=(100, 44),
           
#pos_hint={'center_x': .5, 'center_y': .5})
            pos_hint
={'right': 1, 'center_y': 0.9})
           
#pos_hint={'top': 1})

        box
= BoxLayout()
       
def show_selected_value(spinner, text):
           
print('Choice : ', text)

           
if text=="No":
                spinner
.parent.remove_widget(spinner)
               
print('Spin Dis')
       
if args[1]==True:
           
#self.spinner= spinner

           
self.Status="I am active"
            spinner
.bind(text=show_selected_value)
            box
.add_widget(spinner)
            runTouchApp
(box)

            flag_done
=1
       
else:
            spinner
.parent.remove_widget(spinner)
           
self.Status="I am inactive"


class ExApp(App):
   
def build(self):
       
self.title="Checkboxes"
       
return Ex()

if __name__=='__main__':
   
ExApp().run()

Kv ->
# ex.kv

<Ex>:
    cols
: 3
    canvas
:
       
Color:
            rgb
: .2,.2,.2
       
Rectangle:
            pos
: self.pos
            size
: self.size
   
Label:
        text
: 'A checkbox'
   
CheckBox:
       
#on_active: root.checkActive(*args)
        on_active
: root.spinner(*args)

   
Label:
        text
: root.Status
   
Label:
        text
: 'A group checkbox'
   
CheckBox:
       
group: 'my_check_group'
        on_active
: root.checkActive1(*args)

   
Label:
        text
: root.Status1
   
Label:
        text
: 'A group checkbox'
   
CheckBox:
       
group: 'my_check_group'
        on_active
: root.checkActive2(*args)
   
Label:
        text
: root.Status2

   
Label:
        text
: 'Python is the best language'
   
CheckBox:
        id
: pythonLang
        active
: True
        on_active
: root.checkActive3(*args)
   
Label:
        text
: 'Right on'


ZenCODE

unread,
Aug 4, 2018, 6:07:24 AM8/4/18
to Kivy users support
Yes, that because we are using code that removes the spinner from it's parent.

    spinner.parent.remove_widget(spinner)

Once it's removed, it has not parent and this property is  None. You can protect against the error liker so:

    if spinner.parent:
        spinner.parent.remove_widget(spinner)

But chances are you want to keep poping it in out of the same parent. So then you need a reference to the parent widget. But the code as is is not to easy to do that with, as it creates a new spinner and container each time it's called. It also simplifies the code. So see below. Note that I've used the 'id' property in the kv to reference the BoxLayout defined in the kv file in instead of creating one in code each time.

 #! /usr/bin/env python3
 
# -*- coding: utf-8 -*-
 
 
# ex.py
 
 
from kivy.uix.gridlayout import GridLayout
 
from kivy.app import App
 
from kivy.properties import StringProperty
 
from kivy.base import runTouchApp
 
from kivy.uix.spinner import Spinner
 
from kivy.uix.boxlayout import BoxLayout
 
 
 
class Ex(GridLayout):
     
Status=StringProperty("I am inactive")
     
Status1=StringProperty("I am the inactive member of the group")
     
Status2=StringProperty("I am the inactive member of the group")

 
     
def __init__(self, **kwargs):
         
super(Ex, self).__init__(**kwargs)
         
self.spinner = Spinner(

             
# default value shown
             text
='Deauth',
             
# available values
             values
=('Yes', 'No'),
             
# just for positioning in our example
             size_hint
=(None, None),
             size
=(100, 44),
             
#pos_hint={'center_x': .5, 'center_y': .5})
             pos_hint
={'right': 1, 'center_y': 0.9})
             
#pos_hint={'top': 1})

 
         
self.Status="I am active"
         
self.ids.box.add_widget(self.spinner)

 
     
def checkActive(self,*args):
 
         
if args[1]==True: self.Status="I am active"
 
         
else: self.Status="I am inactive"
     
def checkActive1(self,*args):
         
if args[1]==True: self.Status1="I am the active member of the group"
         
else: self.Status1="I am the inactive member of the group"
     
def checkActive2(self,a,b):
         
if b==True: self.Status2="I am active member of the group"
         
else: self.Status2="I am the inactive member of the group"
     
def checkActive3(self,*args):
         
if args[1]==False: self.ids['pythonLang'].active=True

 
     
def toggle_spinner(self, *args):
         
if not self.spinner.parent:
             
self.Status="I am active"
             
self.ids.box.add_widget(self.spinner)
         
else:
             
self.spinner.parent.remove_widget(self.spinner)

             
self.Status="I am inactive"
 
 
 
class ExApp(App):
     
def build(self):
         
self.title="Checkboxes"
         
return Ex()
 
 
if __name__=='__main__':
     
ExApp().run()
 
 

Then ek.kv

 # ex.kv
 
 
<Ex>:
     cols
: 3
     canvas
:
         
Color:
             rgb
: .2,.2,.2
         
Rectangle:
             pos
: self.pos
             size
: self.
size
     
BoxLayout:
         id
: box
         
Label:

             text
: 'A checkbox'
     
CheckBox:
         
#on_active: root.checkActive(*args)

         on_active
: root.toggle_spinner(*args)

Martin Goumard

unread,
Aug 4, 2018, 12:18:49 PM8/4/18
to Kivy users support
Ahh okay ! thx you so much !
Have a nice a day thx again ;) !
Message has been deleted

Martin Goumard

unread,
Aug 6, 2018, 6:56:23 AM8/6/18
to Kivy users support
I spot an issue since i ran your code. Now when the box is checked, the box is saw as unchecked and vice versa if the box is unchecked, the box is saw as active.
Do you know where is the isssue ? Thx ;) !

EDIT: It's okay simply remove in the "_init_" the last two lines.
         Sorry for this...

ZenCODE

unread,
Aug 6, 2018, 2:53:41 PM8/6/18
to Kivy users support
Then just change line 52 to

    self.Status="I am in active"

and line 56 to

            self.Status="I am active"

so they are swapped. It's not really an issue, just a matter of getting the captions right. You may also want to change the initial text to then be accurate on startup.
Reply all
Reply to author
Forward
0 new messages