2015-12-09 1 views
0

Я создаю приложение, в котором есть несколько кнопок, которые отправляют (и получают) сообщения MQTT по сети. Я создал два GridLayouts и поместил на них несколько кнопок, которые работают так, как я ожидал. Затем я создал холст с контурами нарисованного на нем корабля. Я хочу разместить кнопки на позициях навигационных огней, чтобы я мог управлять навигационными огнями с помощью этих кнопок. Для целей тестирования я добавил одну кнопку на холст в фиксированной позиции. Я не могу нажать кнопку с помощью сенсорного экрана (кнопки на GridLayout работают с сенсорным экраном). Я могу нажать кнопку с помощью мыши, но затем никакое событие не будет запущено, и сообщение MQTT не будет отправлено. Могу ли я добавить кнопку непосредственно на холст, как я, или мне нужно добавить еще один слой? Если вы хотите проверить это, вы можете заменить MQTTToggleButton обычным ToggleButton.Kivy Button не работает так, как показано на холсте

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

К сожалению об этом, я проглядел линию

button.bind(state=self.button_callback) 

для других кнопок.

Теперь я переместил этот код и обратный вызов в класс MQTTToggleButton, поэтому мне не нужно вызывать его каждый раз, когда я создаю кнопку. Он работает так, как ожидалось.

Смежные вопросы