Enable\Disable widget not correct working

1,234 views
Skip to first unread message

Vladimir Lukovnikov

unread,
Sep 1, 2015, 1:28:36 PM9/1/15
to Kivy users support
I am new user in a kivy world, and have some issue when i ma try to make my first application in a kivy.

I try to make base class to comman widgetes, for exemple this is my base class:

from kivy.logger import Logger
from kivy.uix.widget import Widget




class BaseUI(Widget):


    is_active
= True


   
def hide(self):
       
if self.is_show():
           
Logger.debug("BaseUI: id=%s is hide()" % self.id)
           
self.is_active = False
           
self.disabled = True
           
self.opacity = 0.0


   
def show(self):
       
if not self.is_show():
           
Logger.debug("BaseUI: id=%s is show()" % self.id)
           
self.is_active = True
           
self.disabled = False
           
self.opacity = 1.0


   
def is_show(self):
       
return not self.disabled and self.opacity == 1.0


   
def update(self):
       
if self.is_active:
           
self.show()
       
else:
           
self.hide()
       
print(self, end=" ")
       
print(self.is_active, end=" ")
       
print(self.disabled, end=" ")
       
print(self.opacity)



#output:
#<core.game.MainGame object at 0x7fb92a140b88> False 1.0
#<core.ui.field.GameField object at 0x7fb929ea0468> False True 0.0
#<core.ui.menu.Menu object at 0x7fb92a150d08> True False 1.0

---------------------------

I am using then in two widgetes:
from core.ui.base import BaseUI




class GameField(BaseUI):


   
pass


and:

from kivy.logger import Logger
from core.ui.base import BaseUI




class Menu(BaseUI):


    player_number
= 0


   
def start_by_player(self, player_number):
       
if player_number not in [1, 2]:
           
raise Exception("Menu: player_number should be 1 or 2. player_number = %s" % player_number)
       
self.player_number = int(player_number)


       
Logger.debug("Menu: Start with: player_number=%s" % int(player_number))


   
def bnt_exit(self):
       
Logger.debug("Menu: Exit from app. Call system exit()")
       
exit()


And have a simple "controller" for show\hide items on the screeen.



from kivy.logger import Logger
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.uix.widget import Widget


from core.ui.base import BaseUI
from core.ui.menu import Menu
from core.ui.field import GameField




class MainGame(Widget):
    menu
= ObjectProperty(None)
    field
= ObjectProperty(None)


   
def __init__(self, **kwargs):
       
super(MainGame, self).__init__(**kwargs)
       
self._keyboard = Window.request_keyboard(self._keyboard_closed, self, 'text')
       
if self._keyboard.widget:
           
# If it exists, this widget is a VKeyboard object which you can use
           
# to change the keyboard layout.
           
pass
       
self._keyboard.bind(on_key_down=self._on_keyboard_down)


   
def update(self, dt):
       
self.update_ui()
       
if self.menu.player_number == 1:
           
pass
       
elif self.menu.player_number == 2:
           
pass


   
def update_ui(self):
       
for name, widget in self.ids.items():
            widget
.update()


   
def _keyboard_closed(self):
       
Logger.debug('MainGame: Keyboard have been closed!')
       
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
       
self._keyboard = None


   
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
       
Logger.debug('MainGame: The key code: %s  key: %s have been pressed' % (keycode[0], keycode[1]))
       
Logger.debug('MainGame: text is %r' % text)
       
Logger.debug('MainGame: modifiers are %r' % modifiers)


       
# Keycode is composed of an integer + a string
       
# If we hit escape, release the keyboard
       
if keycode[1] == 'escape':
           
self.menu.is_active = not self.menu.is_active
           
self.field.is_active = not self.menu.is_active


       
# Return True to accept the key. Otherwise, it will be used by
       
# the system.
       
return True



When i switch any widgetes  to hide\show state(see function hide in the base class) and set widget property back, from other widget not showing correctly although judging by the state of the properties should be displayed on the screen. 
In other words, when I put back the object properties self.disabled = False and  self.opacity = 1.0 and the second object self.disabled = True and  self.opacity = 0.0, the main object still looking ind render like a disabled, cannot click for him. 


Full project file in attachement, i set top update sceen 1 sec for not spaing message in output, a key escape using between switch widgets stats.

kivy 1.9.1
python 3.4


thanks.
            
example.tar

ZenCODE

unread,
Sep 2, 2015, 5:17:26 AM9/2/15
to Kivy users support
Sorry, but you don't actually mention a problem. Why exactly do you think it's not working correctly?

Vladimir Lukovnikov

unread,
Sep 2, 2015, 5:53:46 AM9/2/15
to Kivy users support
Because I can not understand why the widget is not enabled although the properties suggest that it should be active.

For example:

        print(self, end=" ")
        
print(self.is_active, end=" ")
        
print(self.disabled, end=" ")
        
print(self.opacity)

<core.game.MainGame object at 0x7fb92a140b88> False 1.0
<core.ui.field.GameField object at 0x7fb929ea0468> False True 0.0
<core.ui.menu.Menu object at 0x7fb92a150d08> True False 1.0

Menu object have a disabled = False and opacity = 1.0
But I cannot click to him, after i disabled\enable then before


среда, 2 сентября 2015 г., 12:17:26 UTC+3 пользователь ZenCODE написал:

ZenCODE

unread,
Sep 2, 2015, 4:56:25 PM9/2/15
to Kivy users support
Sorry, I'm trying. After changing it to Python 2.7 compatible code, I get the buttons but in a language I don't understand. And I don't see  a menu? I can click buttons but they seem to work and I can't guess what they are support to do?

But disabling does work. Test it like this. Does that help?

from kivy.app import App
from kivy.clock import Clock
from kivy.uix.button import Button


class MainApp(App):

    def disable_button(self, disable=True):
        self.button.disabled = disable
        if disable:
            # If we have disabled it, re-enable it in 5 seconds
            Clock.schedule_once(lambda dt: self.disable_button(False), 5)

    def build(self):
        self.button = Button(text="Hello")
        self.button.bind(on_release=lambda but: self.disable_button())       
        return self.button


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


Reply all
Reply to author
Forward
0 new messages