0
我正在構建一個應用程序,該應用程序有一些通過網絡發送(並接收)MQTT消息的按鈕。我創建了兩個GridLayouts並在它們上面放置了一些按鈕,這些按鈕可以按我的預期工作。然後我創建了一個畫有輪廓的畫布。我想將按鈕放置在導航燈的位置,以便我可以用這些按鈕控制導航燈。爲了測試目的,我在一個固定的位置添加了一個按鈕到畫布。我無法使用觸摸屏按鈕(GridLayout上的按鈕與觸摸屏一起工作)。我可以用鼠標按下按鈕,但不會觸發任何事件,也不會發送MQTT消息。我可以像我一樣直接將按鈕添加到畫布,還是需要添加另一個圖層? 如果你想測試這個,你可以用一個普通的ToggleButton代替MQTTToggleButton。Kivy Button在放置在Canvas上時無法正常工作
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()