【问题标题】:Kivy Image not displaying in grid layout within a toggleButtonKivy 图像未在切换按钮内的网格布局中显示
【发布时间】:2018-10-14 21:03:55
【问题描述】:

这是我的第一个 Kivy GUI 界面,所以我怀疑我做的不对。但是,我想知道为什么会发生这种情况或如何达到预期的结果。

我正在尝试在切换按钮中呈现图像。无论出于何种原因,当我运行应用程序时,只加载了第二个按钮。

我将导致问题的切换按钮涂成绿色,以便检查我的定位是否关闭。绑定到按钮的功能起作用,图像图标根本不会显示。

这是我的 .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 python-3.x kivy kivy-language


    【解决方案1】:

    如果我理解您的要求,您只需使用ToggleButtonbackground_normalbackground_down 属性即可完成此操作。此外,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)
    

    删除ToggleButtonImage 子级并删除root.attendantchange() 中试图更改Image 的代码。对另一个 ToggleButton 进行相同类型的更改。另外,请注意ToggleButton 中的background_color 只是对实际图像进行着色,因此您可能还想删除它。

    【讨论】:

    • background_normal 和 background_down 属性只有在按钮被点击和按钮处于正常状态时才会改变。在用户与按钮交互后,它不保留这些属性。当他们单击项目并按住它时,background_down 处于活动状态。当他们不与按钮交互时, background_normal 处于活动状态。我有回调来维护按钮的状态,并根据切换按钮的状态交换切换按钮中包含的图像。
    • 这就是为什么它的结构是这样的。不过,感谢您抽出宝贵时间,如果有更好的方法来完成此操作,请在下面给出我的更新和此评论,请告诉我。
    • 这很奇怪。当我执行您的代码时,使用我提到的更改,每次单击 ToggleButton 时图像都会更改并保持更改,并且按住鼠标按钮根本没有任何效果。事实上,当我运行代码时,它看起来就像你上面的答案(当然,我使用的是不同的法师)。
    【解决方案2】:

    我在 github 上打开了一个问题,我发现的行为似乎是网格布局以及它如何计算容器中第一个元素的定位的问题。

    我通过简单地提供任意大小值、pos_hint 以及第一个 Image 元素上的 x 和 x 定位来解决这个问题。

           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 是如何设计的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-01
      • 2018-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-09
      相关资源
      最近更新 更多