kivy bind () принимает ровно 2 позиционных аргумента (задано 0) - PullRequest
0 голосов
/ 10 мая 2018

Я строю графический интерфейс системы лифта в python () с kivy. Я пишу это так, что при нажатии кнопки «вверх» на этаже будет вызвана функция, которая сгенерирует запрос и отправит его в систему. Я сейчас пытаюсь привязать функцию к кнопке вверх, используя:

self.floor1.up_button.bind(on_press=self.up_pressed(1))

И компилятор отправляет мне ошибку:

TypeError: bind() takes exactly 2 positional arguments (0 given)

Есть ли исправление к этому? Новичок в Python, поэтому извиняюсь, если это действительно простой вопрос.

Вот соответствующие коды в .py файле:

from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.properties import ObjectProperty
from random import randint

class FloorRequestStatus:
    up = 0
    down = 1

class Request:
    def __init__(self, start, status, destination, waiting_time):
        self.start = start
        self.status = status
        self.destination = destination
        self.waiting_time = waiting_time

class Floor(GridLayout):
    up_count = NumericProperty(0)
    down_count = NumericProperty(0)
    floor_index = NumericProperty(0)

    up_button = ObjectProperty(Button)
    down_button = ObjectProperty(Button)

class FloorSystem(BoxLayout):
    floor1 = ObjectProperty(Floor)  # type:Floor
    floor2 = ObjectProperty()
    floor3 = ObjectProperty()
    floor4 = ObjectProperty()

    floors = [floor1, floor2, floor3, floor4]

    request_queue = []

    def __init__(self, **kwargs):
        super(FloorSystem, self).__init__(**kwargs)
        self.floor1.up_button.bind(on_press=self.up_pressed(1))

    def generate_destination(self, floor_index, status):
        if status == FloorRequestStatus.up:
            return randint(floor_index + 1, 20)
        if status == FloorRequestStatus.down:
            return randint(0, floor_index - 1)

    def up_pressed(self, floor_index):
        a_request = Request(floor_index, FloorRequestStatus.up,
                        self.generate_destination(floor_index,FloorRequestStatus.up), 0)
        self.request_queue.append(a_request)

А вот соответствующие коды в файле .kv:

#:kivy 1.0.9

<Floor@GridLayout>
    floor_index: 0
    pos: 200,200
    rows: 1
    spacing: 1

    GridLayout:
        size_hint_x: 35
        cols: 1

        Button:
            id: up_button
            size_hint_y: 50
            text: 'up'
            on_press: root.up_count += 1

        Button:
            id:down_button
            size_hint_y: 50
            text: 'down'
            on_press: root.down_count += 1

    Label:
        id: floor_label
        size_hint_x: 65
        text: root.label_text
        background_color: 1,1,1,1
        text: str(root.floor_index) + 'F (' + str(root.up_count) + ',' + str(root.down_count) + ')'

        canvas:
            Color:
                rgba: .3, .5, 1, .4
            Rectangle:
                size: self.size
                pos: self.pos

<FloorSystem>
    floor1: floor1
    floor2: floor2
    floor3: floor3
    floor4: floor4

    orientation: 'vertical'
    size_hint: None, None
    width: 160
    height: 700
    spacing: 2

    Floor:
        id: floor4
        floor_index: 4

    Floor:
        id: floor3
        floor_index: 3

    Floor:
        id: floor2
        floor_index: 2

    Floor:
        id: floor1
        floor_index: 1

1 Ответ

0 голосов
/ 10 мая 2018

Применительно к исходному коду вы столкнетесь со следующей ошибкой.

Ошибка

         self.floor1.up_button.bind(on_press=self.up_pressed(1))
     TypeError: descriptor 'bind' of 'kivy._event.EventDispatcher' object needs an argument

Пояснение

Вышеуказанная ошибка произошла из-за up_button подключен к классу Button и не подключен к объекту Button.Если вы вставите оператор печати print(self.floor1.up_button) в вашу программу, вы увидите разницу.

Диспетчер событий

Как правило, обратные вызовы свойств вызываются с помощью 2аргументы (объект и новое значение свойства) и обратные вызовы событий с одним аргументом (объект).

Решение

Python Script - кнопка удаления

Заменить:

up_button = ObjectProperty(Button)
down_button = ObjectProperty(Button)

С:

up_button = ObjectProperty(None)
down_button = ObjectProperty(None)

kv файл - Hookup ObjectProperties

<Floor@GridLayout>
    up_button: up_button
    down_button: down_button

    floor_index: 0
    ...

Кнопка привязки

Что касается привязки, вы можете использоватьчастичная функция.

self.floor1.up_button.bind(on_press=partial(self.up_pressed, 1))

Пример

main.py

from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.properties import ObjectProperty, NumericProperty
from random import randint
from functools import partial


class FloorRequestStatus:
    up = 0
    down = 1


class Request:
    def __init__(self, start, status, destination, waiting_time):
        self.start = start
        self.status = status
        self.destination = destination
        self.waiting_time = waiting_time


class Floor(GridLayout):
    up_count = NumericProperty(0)
    down_count = NumericProperty(0)
    floor_index = NumericProperty(0)

    up_button = ObjectProperty(None)
    down_button = ObjectProperty(None)


class FloorSystem(BoxLayout):
    floor1 = ObjectProperty(None)
    floor2 = ObjectProperty(None)
    floor3 = ObjectProperty(None)
    floor4 = ObjectProperty(None)

    floors = [floor1, floor2, floor3, floor4]

    request_queue = []

    def __init__(self, **kwargs):
        super(FloorSystem, self).__init__(**kwargs)
        self.floor1.up_button.bind(on_press=partial(self.up_pressed, 1))

    def generate_destination(self, floor_index, status):
        if status == FloorRequestStatus.up:
            return randint(floor_index + 1, 20)
        if status == FloorRequestStatus.down:
            return randint(0, floor_index - 1)

    def up_pressed(self, floor_index):
        a_request = Request(floor_index, FloorRequestStatus.up,
                            self.generate_destination(floor_index, FloorRequestStatus.up), 0)
        self.request_queue.append(a_request)


class TestApp(App):
    def build(self):
        return FloorSystem()


if __name__ == "__main__":
    TestApp().run()

test.kv

#:kivy 1.10.0

<Floor@GridLayout>
    up_button: up_button
    down_button: down_button

    floor_index: 0
    pos: 200,200
    rows: 1
    spacing: 1

    GridLayout:
        size_hint_x: 35
        cols: 1

        Button:
            id: up_button
            size_hint_y: 50
            text: 'up'
            on_press: root.up_count += 1

        Button:
            id:down_button
            size_hint_y: 50
            text: 'down'
            on_press: root.down_count += 1

    Label:
        id: floor_label
        size_hint_x: 65
        text: root.label_text
        background_color: 1,1,1,1
        text: str(root.floor_index) + 'F (' + str(root.up_count) + ',' + str(root.down_count) + ')'

        canvas:
            Color:
                rgba: .3, .5, 1, .4
            Rectangle:
                size: self.size
                pos: self.pos

<FloorSystem>
    floor1: floor1
    floor2: floor2
    floor3: floor3
    floor4: floor4

    orientation: 'vertical'
    size_hint: None, None
    width: 160
    height: 700
    spacing: 2

    Floor:
        id: floor4
        floor_index: 4

    Floor:
        id: floor3
        floor_index: 3

    Floor:
        id: floor2
        floor_index: 2

    Floor:
        id: floor1
        floor_index: 1

Выход

enter image description here

...