首页 > 解决方案 > 如何随机选择一个kivy按钮位置

问题描述

我在 kivy 上有两个屏幕,当我在第二个屏幕上时有两个按钮。我希望这些按钮在两个预定义位置之间具有随机位置。例如,如果按钮“1”位于位置“2”,则按钮 2 将具有位置“1”。

我尝试了很多方法,但都没有奏效,而 Listproperty 的方法在我看来是最好的。当我尝试此方法时,出现此错误:

BuilderException: Parser: File "<inline>", line 38:
...
     36:            id :1
     37:            text:' 1'
>>   38:            pos: root.manager.pos1
     39:            size_hint: .30, .10
     40:            background_color: 0,1,0,0.75
...
ValueError: Button.pos value length is immutable
  File "C:\src2\lib\site-packages\kivy\lang\builder.py", line 696, in _apply_rule
    setattr(widget_set, key, value)
  File "kivy\weakproxy.pyx", line 35, in kivy.weakproxy.WeakProxy.__setattr__
  File "kivy\properties.pyx", line 497, in kivy.properties.Property.__set__
  File "kivy\properties.pyx", line 1356, in kivy.properties.ReferenceListProperty.set
  File "kivy\properties.pyx", line 1345, in kivy.properties.ReferenceListProperty.check

感谢愿意花时间帮助我的人

对不起,我的英语不好

这是我的代码:


import kivy
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivy.core.window import Window
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
import random
from kivy.properties import ObjectProperty
from kivy.properties import ListProperty, StringProperty
kivy.uix.screenmanager.FadeTransition
from kivy.properties import StringProperty, BooleanProperty, NumericProperty
import csv
from collections import defaultdict

kv = """


MyScreenManager:
    MenuScreen:
        name: 'menu'
    Question1:
        name: "question1"

    


<MenuScreen>:
            
    FloatLayout:
        Button: 
            text:"Commencer"
            pos: 270, 300
            size_hint : .30, .10
            background_color: 0,1,0,0.75
            on_press: 
                root.manager.current: 'question1'
                root.update_pos()
    

<Question1>:
    
    FloatLayout:
        Button:
            id:2
            text: '2'
            pos: root.manager.pos2
            size_hint: .30, .10
            background_color: 0,1,0,0.75
        Button:
            id :1
            text:' 1'
            pos: root.manager.pos1
            size_hint: .30, .10
            background_color: 0,1,0,0.75

            

            
"""

ab= 180 #hauteur des boutons
ac= 240 #hauteur des boutons
ae= 270 #abcisse des boutons

class MyScreenManager(ScreenManager):
    pos1= ListProperty()
    pos2= ListProperty()

    


class MenuScreen(Screen): 
    
    def update_pos(self):
        d= [(ae,ab),(ae,ac)]
        random.shuffle(d)
        self.pos1= d[0]
        self.pos2= d[1]
        
    pass


class Question1(Screen):  
    pass 



class Quizz(App):
    def build(self):
        self.title = 'Quizz'
        Window.clearcolor = (0, 1, 1, 0.25)
        
        return Builder.load_string(kv)


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

标签: pythonpython-3.xkivykivy-language

解决方案


错误消息是由于您使用ListProperty. ListPropertya的默认值为[],在使用时pos: root.manager.pos2试图将长度更改pos为零。因此,您的代码将进行一些小的更改。改变你的类定义:

class MyScreenManager(ScreenManager):
    pos1 = ListProperty([0,0])
    pos2 = ListProperty([0,0])


class MenuScreen(Screen):

    def update_pos(self):
        d = [(ae, ab), (ae, ac)]
        random.shuffle(d)
        self.manager.pos1 = d[0]
        self.manager.pos2 = d[1]

这会更改ListPropertyto的默认值[0,0],只是为了获得正确的长度。该update_pos()方法现在更改 中的pos1pos2ScreenManager其中ListProperties

然后在kvfor MenuScreen

<MenuScreen>:

    FloatLayout:
        Button: 
            text:"Commencer"
            pos: 270, 300
            size_hint : .30, .10
            background_color: 0,1,0,0.75
            on_press: 
                root.manager.current = 'question1'
                root.update_pos()

这里唯一的变化是使用=而不是:分配current屏幕名称。


推荐阅读