我正在构建一个应用程序,它有一些通过网络发送(和接收)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()
答案 0 :(得分:1)
对此抱歉,我忽略了这一行
button.bind(state=self.button_callback)
其他按钮。
我现在将此代码和回调移动到MQTTToggleButton类,因此每次创建按钮时都不需要调用它。它现在按预期工作。