2017-05-10 12 views
0

を削除した後に存在します。HoverBehaviorButtonはまだ のPython 3.4.4 Kivyをウィジェット

ただし、clear_widgetsで関連付けられたウィジェットを削除すると、self.parentがなくても何らかの形でHoverButtonが存在します。私はこのホバーイベントを他のウィジェットに拡張し、目に見えないウィジェットを永続させたくないので、このボタンを削除することが不可欠です。

以下を見て、わからないことを教えてください。

要するに、HoverButtonとそれに関連するすべての動作を完全に削除したいと思います。

#main.py 
 

 
from win32api import GetSystemMetrics 
 
from kivy.config import Config 
 

 
Config.set('graphics', 'position', 'custom') 
 
Config.set('graphics', 'resizable', 1) 
 

 
from kivy.app import App 
 
from kivy.clock import Clock 
 
from kivy.lang import Builder 
 
from kivy.properties import ObjectProperty 
 
from kivy.uix.boxlayout import BoxLayout 
 

 
from main_menu import MainMenu 
 
from _map import Map 
 

 
Builder.load_file('main_menu.kv') 
 

 
class HoverBehaviorPersistance(App): 
 

 
    boxlayout_main_menu = ObjectProperty(None) 
 
    hover_button = ObjectProperty(None) 
 
    
 
    def __init__(self, **kwargs): 
 
     super(HoverBehaviorPersistance, self).__init__(**kwargs) 
 
     self.content = BoxLayout() 
 
     self.main_menu = MainMenu() 
 
     self.content.add_widget(self.main_menu) 
 

 
    def build(self): 
 
     return self.content 
 
     
 
    def begin(self): 
 
     print("begin") 
 
     self.test_map = Map() 
 
     self.main_menu.boxlayout_main_menu.clear_widgets() 
 
     self.main_menu.clear_widgets() 
 
     self.content.clear_widgets() 
 
     self.content.add_widget(self.test_map) 
 
     
 
if __name__ == '__main__': 
 
    HoverBehaviorPersistance().run()

#main_menu.py 
 

 
from kivy.uix.boxlayout import BoxLayout 
 
from kivy.uix.popup import Popup 
 

 
class MainMenu(BoxLayout): 
 

 
    def __init__(self, **kwargs): 
 
     super(MainMenu, self).__init__(**kwargs) 
 
     print("Initializing MainMenu") 
 
     
 
    def open_settings(self): 
 
     settings_popup = SettingsPopup() 
 
     settings_popup.open() 
 
     
 
class SettingsPopup(Popup): 
 
    pass

#main_menu.kv 
 

 
#: import HoverButton hover_widget_behavior 
 

 
<MainMenu> 
 
    boxlayout_main_menu:_boxlayout_main_menu 
 
    hover_button:_hover_button 
 
    orientation: 'vertical' 
 
\t 
 
\t AnchorLayout: 
 
     anchor_x: 'center' 
 
\t  anchor_y: 'center' 
 
\t \t 
 
     BoxLayout: 
 
      id:_boxlayout_main_menu 
 
\t \t orientation: 'vertical' 
 
\t   spacing: 10 
 
\t \t padding: 10 
 
\t \t size_hint: .5, .8 
 
\t \t \t 
 
\t \t HoverButton: 
 
       id:_hover_button 
 
\t \t  text: 'begin' 
 
\t \t  on_release: app.begin() 
 
      HoverButton: 
 
       text: 'settings' 
 
       on_release: root.open_settings() 
 
\t \t \t \t 
 
<SettingsPopup> 
 
    id: popup_settings 
 
\t size_hint: 0.9, 0.6 
 
\t title: "Settings" 
 
\t GridLayout: 
 
\t 
 
\t  cols: 2 
 
\t \t 
 
\t  Label: 
 
\t \t text:'Settings #1' 
 
\t  Slider: 
 
\t   orientation: 'horizontal' 
 
\t \t value: 25 
 
\t \t max: 100 
 
\t \t min: 0 
 
\t  Label: 
 
\t \t text: 'Settings #2' 
 
\t  BoxLayout: 
 
\t \t orientation: 'horizontal' 
 
\t  Label: 
 
\t \t text: 'Settings #3'

#_map.py 
 

 
from kivy.uix.button import Button 
 
from kivy.uix.boxlayout import BoxLayout 
 

 
class Map(BoxLayout): 
 
    
 
    def __init__(self, **kwargs): 
 
     super(Map, self).__init__(**kwargs) 
 
     print("Map initiated.") 
 
\t \t 
 
     self.btn = Button(text="btn") 
 
     self.add_widget(self.btn)

#hover_widget_behavior.py 
 

 
from kivy.animation import Animation 
 
from kivy.core.window import Window 
 
from kivy.properties import BooleanProperty, ObjectProperty, StringProperty 
 
from kivy.uix.button import Button 
 

 

 
class HoverGUIBehavior(object): 
 
    #__author__ = 'Olivier POYEN' 
 
    """Hover behavior. 
 

 
    :Events: 
 
     `on_enter` 
 
      Fired when mouse enter the bbox of the widget. 
 
     `on_leave` 
 
      Fired when the mouse exit the widget 
 
    """ 
 

 
    hovered = BooleanProperty(False) 
 
    border_point= ObjectProperty(None) 
 
    '''Contains the last relevant point received by the Hoverable. This can 
 
    be used in `on_enter` or `on_leave` in order to know where was dispatched the event. 
 
    ''' 
 

 
    def __init__(self, **kwargs): 
 
     self.register_event_type('on_enter') 
 
     self.register_event_type('on_leave') 
 
     Window.bind(mouse_pos=self.on_mouse_pos) 
 
     super(HoverGUIBehavior, self).__init__(**kwargs) 
 

 
    def on_mouse_pos(self, *args): 
 
     pos = args[1] 
 
     inside = self.collide_point(*pos) 
 
     if self.hovered == inside: 
 
      #We have already done what was needed 
 
      return 
 
     self.border_point = pos 
 
     self.hovered = inside 
 
     if inside: 
 
      self.dispatch('on_enter') 
 
     else: 
 
      self.dispatch('on_leave') 
 

 
    def on_enter(self): 
 
     pass 
 

 
    def on_leave(self): 
 
     pass 
 
     
 
class HoverButton(Button, HoverGUIBehavior):  
 
    
 
    # TODO: HoverButton somehow still exists even after removing parent and it's children 
 
    def on_enter(self, *args, **kwargs): 
 
     print("I'm still here!") 
 
     if not self.parent: # Find someway to remove itself 
 
      print() 
 
      print('self = ' + str(self)) 
 
      print("I'm definitely still here!") 
 
      return 
 
     self.ref_x = self.x 
 
     self.ref_y = self.y 
 
     
 
     self.anim = Animation(x = self.x -10 ,y = self.y - 10, duration=1.0, t='out_bounce') + Animation(x = self.x + 10, y = self.y + 10, duration=1.0, t='out_bounce') 
 
     self.anim.repeat = True 
 
     self.anim.start(self) 
 

 
    def on_leave(self, *args): 
 
     if not self.parent: # Find someway to remove itself 
 
      print() 
 
      print('self = ' + str(self)) 
 
      print("I'm definitely still here!") 
 
      return 
 
     if self.anim: 
 
      self.anim.cancel(self) 
 
      return_anim = Animation(pos = (self.ref_x, self.ref_y), duration = 0.35, t='out_bounce') 
 
      return_anim.start(self)

答えて

0

私は私の問題を解決しました。

問題は、異なるレイアウト間で移行するときに関数のバインドを解除する必要があることを認識していないという事実でした。

hover_widget_behavior.pyするには、親(たとえば、self.parentでない場合)を削除した場合、自分自身のバインドを解除するだけです(on_mouse_posのバインドを解除してください)。

私はレイアウトを削除/再作成するたびにon_mouse_posを取得できません。

#hover_widget_behavior.py 

from kivy.animation import Animation 
from kivy.core.window import Window 
from kivy.properties import BooleanProperty, ObjectProperty, StringProperty 
from kivy.uix.button import Button 


class HoverGUIBehavior(object): 
    #__author__ = 'Olivier POYEN' 
    """Hover behavior. 

    :Events: 
     `on_enter` 
      Fired when mouse enter the bbox of the widget. 
     `on_leave` 
      Fired when the mouse exit the widget 
    """ 

    hovered = BooleanProperty(False) 
    border_point= ObjectProperty(None) 
    '''Contains the last relevant point received by the Hoverable. This can 
    be used in `on_enter` or `on_leave` in order to know where was dispatched the event. 
    ''' 

    def __init__(self, **kwargs): 
     self.register_event_type('on_enter') 
     self.register_event_type('on_leave') 
     Window.bind(mouse_pos=self.on_mouse_pos) 
     super(HoverGUIBehavior, self).__init__(**kwargs) 

    def on_mouse_pos(self, *args): 
#========================================================== 
     # Insert this statement to unbind itself its 
     # parent does not exist 
     if not self.parent: 
      print("No self.parent") 
      Window.unbind(mouse_pos=self.on_mouse_pos) 
      return 
#========================================================== 
     pos = args[1] 
     inside = self.collide_point(*pos) 
     if self.hovered == inside: 
      #We have already done what was needed 
      return 
     self.border_point = pos 
     self.hovered = inside 
     if inside: 
      self.dispatch('on_enter') 
     else: 
      self.dispatch('on_leave') 

    def on_enter(self): 
     pass 

    def on_leave(self): 
     pass 

class HoverButton(Button, HoverGUIBehavior): 

    # TODO: HoverButton somehow still exists even after removing parent and it's children 
    def on_enter(self, *args, **kwargs): 
     print("I'm still here!") 
     if not self.parent: # Find someway to remove itself 
      print() 
      print('self = ' + str(self)) 
      print("I'm definitely still here!") 
      return 
     self.ref_x = self.x 
     self.ref_y = self.y 

     self.anim = Animation(x = self.x -10 ,y = self.y - 10, duration=1.0, t='out_bounce') + Animation(x = self.x + 10, y = self.y + 10, duration=1.0, t='out_bounce') 
     self.anim.repeat = True 
     self.anim.start(self) 

    def on_leave(self, *args): 
     if not self.parent: # Find someway to remove itself 
      print() 
      print('self = ' + str(self)) 
      print("I'm definitely still here!") 
      return 
     if self.anim: 
      self.anim.cancel(self) 
      return_anim = Animation(pos = (self.ref_x, self.ref_y), duration = 0.35, t='out_bounce') 
      return_anim.start(self) 
関連する問題