如何在kivy python屏幕管理器中随机化按钮的位置?

时间:2017-11-12 23:20:18

标签: python button kivy screen

对于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个位置有一个正方形,而在左下角有一个正方形。按任一方格可产生所需的结果。如何让左下角的方格消失?

2 个答案:

答案 0 :(得分:0)

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

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

<强> main.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

<强> main.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秒的延迟。

<强>输出:

enter image description here

答案 1 :(得分:0)

详情请参阅说明和完整示例。

#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和屏幕名称添加到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