放置在画布上时,Kivy Button无法正常工作

时间:2015-12-09 09:15:51

标签: python python-3.x kivy

我正在构建一个应用程序,它有一些通过网络发送(和接收)MQTT消息的按钮。我已经创建了两个GridLayouts并在它们上放置了一些按预期工作的按钮。然后我创建了一个画布,上面画着一艘船的轮廓。我想在导航灯的位置上放置按钮,这样我就可以用这些按钮控制导航灯。出于测试目的,我在固定位置的画布上添加了一个按钮。我无法使用触摸屏按下按钮(GridLayout上的按钮与触摸屏一起使用)。我可以用鼠标按下按钮,但不会触发任何事件,也不会发送任何MQTT消息。我可以像我一样直接在Canvas中添加一个Button,还是需要添加另一个图层? 如果要测试它,可以用正常的ToggleButton替换MQTTToggleButton。

from collections import OrderedDict

from kivy.app import App
from kivy.core.window import Window
from kivy.graphics.context_instructions import Color
from kivy.graphics.vertex_instructions import Ellipse, Rectangle
from kivy.uix.carousel import Carousel
from kivy.uix.gridlayout import GridLayout
from kivy.uix.widget import Widget

from gui.widget.mqtttogglebutton import MQTTToggleButton
from library.mqtt.client import Client


class ButtonScreen(GridLayout):
    def __init__(self, client, buttons, **kwargs):
        super().__init__(cols=4, spacing=10, padding=10, **kwargs)
        self._client = client

        for topic, text in buttons.items():
            button = MQTTToggleButton(text=text, font_size='10dp', client=client, topic=topic)
            button.bind(state=self.button_callback)
            self.add_widget(button)

    def button_callback(self, button, state):
        if isinstance(button, MQTTToggleButton):
            self._client.publish(button.topic, button.payload)


class NavigationLightsScreen(Widget):
    def __init__(self, ship_size, client, **kwargs):
        super().__init__(**kwargs)
        self._ship_size = ship_size
        self._client = client
        self.bind(pos=self.draw_ship)
        self.bind(size=self.draw_ship)
        self.draw_ship()

    def draw_ship(self, *args):
        self.canvas.clear()
        with self.canvas:
            Color(0.3, 0.3, 0.3, 1)
            width = int(self._ship_size[1] * self.calc_pixels_per_meter())
            length_stern = int(width * 1.2 / 2)
            length_bow = int(width * 2.3 / 2)
            # stern
            Ellipse(pos=(self.x, self.y + (self.height - width) / 2), size=(length_stern * 2, width), angle_start=180,
                    angle_end=360)
            # bow
            Ellipse(pos=(self.x + self.width - length_bow * 2, self.y + (self.height - width) / 2),
                    size=(length_bow * 2, width), angle_start=0, angle_end=180)
            # midship
            Rectangle(pos=(self.x + length_stern, self.y + (self.height - width) / 2),
                      size=(self.width - length_bow - length_stern, width))

        self.add_widget(MQTTToggleButton(text='Stern light', font_size='10dp', client=self._client, topic='relay/0',
                                         pos=(100, 100)))

    def calc_pixels_per_meter(self):
        pixels_per_meter_length = self.width / self._ship_size[0]
        pixels_per_meter_width = self.height / self._ship_size[1]
        return min(pixels_per_meter_length, pixels_per_meter_width)


class ShipControlCarousel(Carousel):
    def __init__(self, client, **kwargs):
        super().__init__(**kwargs)

        self.add_widget(NavigationLightsScreen(ship_size=(28.01, 5.70), client=client))

        buttons = OrderedDict()
        buttons['relay/0'] = 'Generator machinekamer'
        buttons['relay/1'] = 'Generator achterpiek'
        buttons['relay/2'] = 'Startluchtcompressor'
        buttons['relay/3'] = 'Ruitenwissers'
        buttons['relay/4'] = 'Navigatie computer'
        buttons['relay/5'] = 'Radar'
        buttons['relay/6'] = 'Satalietkompas'
        self.add_widget(ButtonScreen(client=client, buttons=buttons))

        buttons = OrderedDict()
        buttons['relay/0'] = 'Generator machinekamer'
        buttons['relay/1'] = 'Generator achterpiek'
        buttons['relay/7'] = 'Verlichting gangboord'
        buttons['relay/8'] = 'Verlichting dekhut stuurboord'
        buttons['relay/9'] = 'Verlichting dekhut bakboord'
        self.add_widget(ButtonScreen(client=client, buttons=buttons))


class Application(App):
    def build(self):
        return ShipControlCarousel(client=Client(client_id='gui', host='127.0.0.1'), direction='right')


if __name__ == '__main__':
    #Window.fullscreen = True
    Application().run()

1 个答案:

答案 0 :(得分:1)

对此抱歉,我忽略了这一行

button.bind(state=self.button_callback)

其他按钮。

我现在将此代码和回调移动到MQTTToggleButton类,因此每次创建按钮时都不需要调用它。它现在按预期工作。