Kivy изображение не отображается в сетке внутри кнопки toggleButton

1

Это мой первый интерфейс Kivy GUI, поэтому я подозреваю, что не делаю что-то правильно. Тем не менее, я хотел бы знать, почему это происходит или как достичь желаемого результата.

Я пытаюсь сделать изображение в Toggle Button. По какой-то причине при запуске приложения загружается только вторая кнопка.

Я покрасил кнопку переключения, которая создает проблему зеленым цветом, поэтому я могу проверить, было ли мое позиционирование выключено. Функции, которые связаны с кнопками, значок изображения вообще не отображается.

Изображение 174551

Вот мой.kv файл:

<Controller>:
lbl: my_label
tbl: my_other_label
atl: attendant_label
timg: my_test_img
aimage: attendant_img

BoxLayout:
    canvas.before:
        Color:
            rgba: 0.137, 0.149, 0.161, 1
        Rectangle:
            # self here refers to the widget i.e BoxLayout
            pos: self.pos
            size: self.size
    orientation:'horizontal'

    GridLayout:
        cols:1
        rows:2

        ##THIS DOES NOT DISPLAY
        ToggleButton:
            id:attendant_label
            group: 'g2'
            border:0,0,0,0          
            background_color:(0, 1, 0, 1.0)
            background_normal:''
            background_down: ''
            on_press: root.attendantchange(*args)

            Image:
                id:attendant_img
                source: 'attendantoff.png'
                size: self.parent.width, self.parent.height
        ##THIS DISPLAYS..
        ToggleButton:
            id:my_other_label
            group: 'g1'
            border:0,0,0,0          
            background_color:(0.137, 0.149, 0.161, 1.0)
            background_normal:''
            background_down: ''
            on_press: root.buttonchange(*args)

            Image:
                id:my_test_img
                source: 'bulb1.png'
                size: self.parent.width, self.parent.height

    Slider:
        canvas:
            Color:
                rgb: 0.89,0.694,0
            BorderImage:
                border: (0, 18, 0, 18) if self.orientation == 'horizontal' else (18, 0, 18, 0)
                pos: (self.x + self.padding, self.center_y - sp(18)) if self.orientation == 'horizontal' else (self.center_x - 35, self.y + self.padding)
                size: (max(self.value_pos[0] - self.padding * 2 - sp(16), 0), sp(36)) if self.orientation == 'horizontal' else (sp(36), max(self.value_pos[1] - self.padding * 2, 0))
                source: 'atlas://data/images/defaulttheme/slider{}_background{}'.format(self.orientation[0], '_disabled' if self.disabled else '')
        id:my_label
        size_hint:.25,1
        min: 0
        max: 100
        enabled: False
        disabled: True
        orientation:'vertical'
        value_track_color: [0, 1, 0, 1]
        on_value: root.new_brightness(*args)

Вот код Python:

import paho.mqtt.client as mqtt

import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout

kivy.require('1.10.1') # replace with your current kivy version !


class Controller(BoxLayout):

    def __init__(self):
        self.buttonState = 0;
        self.attendantState = 0;
        self.oldBrightness = '0';
        self.client = mqtt.Client();

        super(Controller,self).__init__()

    def new_brightness(self,*args):
        if(self.buttonState == 0):
            print('light is off');
        else:
            #self.lbl.text = str(int(args[1]))
            #self.tbl.text = str(int(args[1]))
            self.oldBrightness = str(int(args[1]))
            if(int(args[1]) <= 10):
                self.timg.source = "bulb2.png"
            elif (int(args[1]) <= 50):
                self.timg.source = "bulb2.png"
            else:
                self.timg.source = "bulb2.png"

            self.publish(self.oldBrightness)

    def buttonchange(self,*args):
        if(self.buttonState == 0):
            self.buttonState = 1;
            self.lbl.enabled = True;
            self.lbl.disabled = False;
            self.timg.source='bulb2.png'
            self.publish(1)
        else:
            self.buttonState = 0;
            self.timg.source='bulb1.png'
            self.lbl.enabled = False;
            self.lbl.disabled = True;
            self.publish(0)

        #self.tbl.text = str(self.buttonState)
        print(str(self.__class__) + ": " + str(self.__dict__))

    def attendantchange(self,*args):
        if(self.attendantState == 0):
            self.attendantState = 1;
            self.aimage.source='attendanton.png'
        else:
            self.attendantState = 0;
            self.aimage.source='attendantoff.png'

        print(str(self.__class__) + ": " + str(self.__dict__))

    def __str__(self):
        return str(self.__class__) + ": " + str(self.__dict__)

    def publish(self,value):
        # When I manually send a message from the command line, there is a connect, send, disconnect process
        #  I am recreating that process here as opposed to connecting once and leaving the connection open.
        #  If there is only a single connection attempt which fails because the receiver is powered off, etc
        #  that would leave us with no way to reestablish communications
        # connect to broker
        Broker = "192.168.1.21"
        pub_topic = "RL"
        #self.client.connect(Broker, 1883, 60)
        # I need this for message subscriptions; not sure about publising
        #self.client.loop_start()
        # send updated value to reading light
        #self.client.publish(pub_topic, value)
        # close everything down after sending a message
        #self.client.loop_stop()
        #self.client.disconnect()

class MyApp(App):

    def build(self):
        return Controller()

window = MyApp()
window.run()
Теги:
python-3.x
kivy
kivy-language

2 ответа

0

Я открыл проблему в github, поведение, которое я обнаружил, похоже, является проблемой с компоновкой сетки и как она вычисляет позиционирование для первого элемента в контейнере.

Я решил это, просто предоставив произвольное значение размера, pos_hint и x и x позиционирование на первом элементе Image.

       ToggleButton:
            id:my_other_label
            group: 'light'
            border:1,1,1,1
            background_color:(0.137, 0.149, 0.161, 1.0)
            background_normal:''
            background_down: ''
            on_press: root.buttonchange(*args)
            Image:
                id:my_test_img
                source: 'bulb1.png'
                size: 250,250
                allow_stretch: True
                pos_hint: {'center_x': .5, 'center_y': .5}
                y: self.parent.y + self.parent.height - 350
                x: self.parent.width/2 - self.width/2


        ToggleButton:
            id:attendant_label
            group: 'gatt'
            background_color:(0.137, 0.149, 0.161, 1.0)
            background_normal:''
            background_down: ''
            on_press: root.attendantchange(*args)
            Image:
                id:attendant_img
                source: 'attendantoff.png'
                size: self.parent.width, self.parent.height

Из того, что я могу сказать, сетка не знает его размеров, пока первый элемент не будет помещен внутри него. Таким образом, второе добавленное ToggleButton Image понимает, где оно относится только после того, как первый элемент указан с большей детализацией.

Опять же, я не уверен, является ли это ошибкой или как разработан GridLayout.

Изображение 174551

0

Если я понимаю, что вы просите, вы можете это сделать, просто используя свойства background_normal и background_down для ToggleButton. Кроме того, ToggleButton не является контейнером, поэтому попытка использовать Image в качестве дочернего элемента ToggleButton самом деле не имеет смысла. Поэтому в вашем файле Kivy попробуйте настроить ToggleButton следующим образом:

        ##THIS DOES NOT DISPLAY
        ToggleButton:
            id:attendant_label
            group: 'g2'
            border:0,0,0,0 
            background_normal:'attendantoff.png'
            background_down: 'attendanton.png'
            on_press: root.attendantchange(*args)

Устраните дочерний ToggleButton Image ToggleButton и удалите код в root.attendantchange() который пытается изменить Image. Сделайте те же самые изменения для другого ToggleButton. Также обратите внимание, что background_color в ToggleButton просто отображает фактическое изображение, поэтому вы также можете удалить его.

  • 0
    Атрибуты background_normal и background_down изменяются только при нажатии кнопки и когда кнопка находится в нормальном состоянии. он не содержит эти атрибуты после того, как пользователь взаимодействует с кнопкой. background_down активен, когда они щелкают по элементу и удерживают его. background_normal активен, когда они не взаимодействуют с кнопкой. У меня есть обратные вызовы для поддержания состояния кнопки и замены изображения, содержащегося в кнопке переключения, в зависимости от состояния кнопки переключения.
  • 0
    Вот почему он так структурирован. Спасибо за ваше время, хотя, если есть лучший способ сделать это, учитывая мое обновление ниже и этот комментарий, пожалуйста, дайте мне знать.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню