【问题标题】:How to randomize the location of a button in kivy python screen manager?如何在 kivy python 屏幕管理器中随机化按钮的位置?
【发布时间】:2017-11-12 23:20:18
【问题描述】:

我是 python 和 kivy 的新手,我一直在研究这个问题,但一无所获,因此非常感谢任何帮助。我正在为老鼠做一项行为任务,他们需要按下屏幕上的一个白色方形按钮来获得奖励。每次出现刺激屏幕时,我希望白色方块出现在三个位置之一。这是我到目前为止的相关代码:

main.kv:

<Stimulus>:
    on_pre_enter: self.update_pos()
    FloatLayout:
        StimButton:
            id: stimbutton
            on_press: root.manager.current = 'screen1'

<StimButton>
    background_normal: ''
    color: 1,1,1,1
    size_hint: 0.2, 0.3

在 python main.py 中:

class Stimulus(Screen):
    a = ObjectProperty(None)
    def update_pos(self):
        b = randint(1,3)
        if b==1:
            a = {'x':0.1,'y':0.33}
        elif b==2:
            a = {'x':0.4,'y':0.33}
        elif b==3:
            a = {'x':0.7,'y':0.33}
        self.ids.stimbutton.pos_hint = a

class StimButton(Button):
    def on_press(self):
        deliver_pellet()

应该会出现一个白色方块,当老鼠按下它时,它们会得到奖励,然后它会切换到黑屏。延迟一段时间后,一个白色方块出现在 3 个可能位置中的另一个位置,然后它们再次出现。最终发生的是,我在左下角得到一个白色方块,下次屏幕出现时,我在随机 3 个位置之一有一个方块,左下角有一个。按下任一方格都会产生所需的结果。如何让左下角的那个方块消失?

【问题讨论】:

    标签: python button kivy screen


    【解决方案1】:

    您没有展示如何实现 screen1 类,但似乎您创建了另一个按钮实例。

    一个基于您的代码的简单且可重现的示例是:

    ma​​in.kv:

    <ScreenManagement>:
        Stimulus:
        BlackScreen:
    
    <BlackScreen>
        name: "black_screen"
        on_pre_enter: self._sleep()
    
    <Stimulus>:
        name: "stimulus_screen"
        stimButton_pos: self._random_pos()
        on_pre_enter: self._update_pos()
    
        FloatLayout:
            StimButton:
                id: stimbutton
                pos_hint: root.stimButton_pos
                on_press: root.manager.current = 'black_screen'
    
    <StimButton>
        background_normal: ''
        color: 1,1,1,1
        size_hint: 0.2, 0.3
    

    ma​​in.py:

    import kivy
    kivy.require('1.0.5')
    
    import random
    from kivy.app import App
    from kivy.clock import Clock
    from kivy.properties import ObjectProperty
    from kivy.uix.button import Button
    from kivy.uix.screenmanager import ScreenManager, Screen
    
    
    class ScreenManagement(ScreenManager):
        pass
    
    
    class BlackScreen(Screen):
        def _sleep(self):
            Clock.schedule_once(self._change_screen, 3)
    
        def _change_screen(self,  dt):
            self.manager.current = "stimulus_screen"
    
    
    class Stimulus(Screen):
        stimButton_pos = ObjectProperty(None)
    
        def _update_pos(self):
            self.stimButton_pos = self._random_pos()
    
        def _random_pos(self):
            pos = random.choice(({'x':0.1,'y':0.33},
                                 {'x':0.4,'y':0.33},
                                 {'x':0.7,'y':0.33}))
    
            return pos
    
    
    class StimButton(Button):
        def on_press(self):
            #deliver_pellet()
            pass
    
    
    class MainApp(App):
        def build(self):
            return ScreenManagement()
    
    
    if __name__ == '__main__':
        MainApp().run()
    

    我使用kivy.clock.Clock.schedule_once 在屏幕之间提供 3 秒的延迟。

    输出:

    【讨论】:

      【解决方案2】:

      详情请参考解释和完整示例。

      #1。在 Python 脚本中添加方法

      我们将在 Stimulus 类中添加一个方法“display_stimulus_screen”。当老鼠按下刺激按钮时,该方法将被调度一次。

      class Stimulus(Screen):
      ...
          # dt means delta time
          def display_stimulus_screen(self, dt):
              self.manager.current = "stimulus"
      

      #2。将 id 和 screen 名称添加到 kv 文件中

      我们将为 Stimulus 屏幕提供一个 id,以便我们可以引用我们刚刚在 Python 脚本中添加的新方法。

      <ScreenManagement>:
          Stimulus:
              id: stimulus
              name: "stimulus"
          Screen1:
              name: "screen1"
      

      #3。制造延迟

      我们将导入 Kivy Clock 并使用 Clock.schedule_once 方法以特定的时间间隔调用名为“display_stimulus_screen”的新方法。在本例中,我们使用 0.5 秒。将以下内容添加到 kv 文件中。

      #:import Clock kivy.clock.Clock
      ...
                  on_press:
                      root.manager.current = 'screen1'    # display black screen
                      Clock.schedule_once(root.manager.ids.stimulus.display_stimulus_screen, 0.5)
      

      示例

      main.py

      ​​>
      from kivy.app import App
      from kivy.uix.screenmanager import ScreenManager, Screen
      from kivy.uix.button import Button
      from kivy.properties import ObjectProperty
      
      from random import randint
      
      
      def deliver_pellet():
          print("deliver pellet")
      
      
      class ScreenManagement(ScreenManager):
          pass
      
      
      class Screen1(Screen):
          pass
      
      
      class Stimulus(Screen):
          a = ObjectProperty(None)
      
          def update_pos(self):
              b = randint(1, 3)
              if b == 1:
                  a = {'x': 0.1, 'y': 0.33}
              elif b == 2:
                  a = {'x': 0.4, 'y': 0.33}
              elif b == 3:
                  a = {'x': 0.7, 'y': 0.33}
              self.ids.stimbutton.pos_hint = a
      
          # dt means delta time
          def display_stimulus_screen(self, dt):
              self.manager.current = "stimulus"   # name of Stimulus Screen
      
      
      class StimButton(Button):
          def on_press(self):
              deliver_pellet()
      
      
      class TestApp(App):
          def build(self):
              return ScreenManagement()
      
      
      if __name__ == "__main__":
          TestApp().run()
      

      test.kv

      #:kivy 1.10.0
      #:import Clock kivy.clock.Clock
      
      <ScreenManagement>:
          Stimulus:
              id: stimulus
              name: "stimulus"
          Screen1:
              name: "screen1"
      
      <Screen1>:
      
      
      <Stimulus>:
          on_pre_enter: self.update_pos()
      
          FloatLayout:
              StimButton:
                  id: stimbutton
                  on_press:
                      root.manager.current = 'screen1'    # display black screen
                      Clock.schedule_once(root.manager.ids.stimulus.display_stimulus_screen, 0.5)
      
      <StimButton>
          background_normal: ''
          color: 1,1,1,1
          size_hint: 0.2, 0.3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        • 1970-01-01
        • 2021-09-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多