2015-12-09 70 views
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() 

回答

1

對不起這個,我忽略了線

button.bind(state=self.button_callback) 

的其他按鈕。

我現在將這段代碼和回調移到了MQTTToggleButton類中,所以每次創建按鈕時都不需要調用它。它現在按預期工作。

相關問題