Search code examples
pythonpython-3.xkivykivy-language

Image is not getting displayed from Kivy file


Here is the code along with the kv file.

The image is not getting displayed based on the spinner selection.

I need to display the image in the second screen with two-three images and on clicking the same, should give a popup with details and another image.

from kivy.app import App
from kivy.uix.behaviors import ButtonBehavior  
from kivy.uix.image import Image  
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.spinner import Spinner
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.screenmanager import SlideTransition
from kivy.lang import Builder
from kivy.config import Config
Config.set('graphics', 'resizable', True) 

kv=Builder.load_string("""
<Image1n>: 
    orientation:'vertical'
    BoxLayout: 
        padding:5
        ImageButton: 
            source: 'anorth.jpg'
            size_hint: 0.6, 0.6
            pos_hint: {'center_x':.1, 'center_y': .8}
            on_release: root.on_press()
    BoxLayout: 
        padding:5
        ImageButton: 
            source:'bnorth.jpg'
            size_hint: 0.8, 0.8
            pos_hint: {'center_x':.1, 'center_y': .2}
            on_release: root.on_press()
<Image1e>: 
    orientation:'vertical'
    BoxLayout: 
        padding:5
        ImageButton: 
            source: 'aeast.jpg'
            size_hint: 0.6, 0.6
            pos_hint: {'center_x':.1, 'center_y': .8}
            on_release: root.on_press1()
    BoxLayout: 
        padding:5
        ImageButton: 
            source:'beast.jpg'
            size_hint: 0.8, 0.8
            pos_hint: {'center_x':.1, 'center_y': .2}
            on_release: root.on_press1()
"""
)
class ImageButton(ButtonBehavior, Image):  
    pass
class Image1n(Screen,BoxLayout):
    pass
class Image1e(Screen,BoxLayout):
    pass
class Image1BHKNorth(Screen,ButtonBehavior, Image,GridLayout):
    def imagebutton1bhknorth(self):
        return kv
    def on_press(self):        
        layout = GridLayout(cols=2,rows=2) 
        popupLabel = Label(text = "         Details"
                           "\n House Type - 1BHK"
                           "\n Area - 800")
        image= Image(source='anorth1.jpg')
        closeButton = Button(text = "Close",size_hint_x=0.1,size_hint_y=0.1)  
        layout.add_widget(popupLabel) 
        layout.add_widget(image)
        layout.add_widget(closeButton)
        popup = Popup(title ='                        Details', 
                      content = layout)   
        popup.open()    
        closeButton.bind(on_press = popup.dismiss)    
class Image1BHKEast(Screen,ButtonBehavior, Image,GridLayout):
    def imagebutton1bhkeast(self):
        return kv
    def on_press1(self):        
        layout = GridLayout(cols=2,rows=2) 
        popupLabel = Label(text = "         Details"
                           "\n House Type - 1BHK"
                           "\n Area - 800\n Direction - North")
        image= Image(source='aeast1.jpg')
        closeButton = Button(text = "Close",size_hint_x=0.1,size_hint_y=0.1)  
        layout.add_widget(popupLabel) 
        layout.add_widget(image)
        layout.add_widget(closeButton)
        popup = Popup(title ='                        Details', 
                      content = layout)   
        popup.open()    
        closeButton.bind(on_press = popup.dismiss)

class CustomScreen(Screen):
    def __init__(self, **kwargs):
        super(CustomScreen, self).__init__(**kwargs)
        layout = BoxLayout(orientation='vertical')
        self.spinnerObject = Spinner(text ="House", 
              values =("1BHK", "2BHK", "3BHK"), 
              background_color =(0.784, 0.443, 0.216, 1))  

        self.spinnerObject.size_hint = (0.2, 0.2) 

        self.spinnerObject.pos_hint ={'x': .35, 'y':.40}
        layout.add_widget(self.spinnerObject)
        #spinner-selection
        self.spinnerObject.bind(text=self.spinner_select)
        self.spinnerSelection = Label(text="%s"%self.spinnerObject.text)
        layout.add_widget(self.spinnerSelection)
        self.spinnerSelection.pos_hint={'x': .1, 'y':.3}
        #second spinner
        self.spinnerObject1 = Spinner(text ="Area", 
              values =("800","1200", "1500", "1800", "2200"), 
              background_color =(0.784, 0.443, 0.216, 1))  
        self.spinnerObject1.size_hint = (0.2, 0.2) 

        self.spinnerObject1.pos_hint ={'x': .35, 'y':.40} 

        layout.add_widget(self.spinnerObject1)
        #spinner-selection
        self.spinnerObject1.bind(text=self.spinner_select)
        self.spinnerSelection1 = Label(text="%s"%self.spinnerObject1.text)
        layout.add_widget(self.spinnerSelection1)
        self.spinnerSelection1.pos_hint={'x': .1, 'y':.3}
        #third spinner
        self.spinnerObject2 = Spinner(text ="Directions", 
              values =("North","East"), 
              background_color =(0.784, 0.443, 0.216, 1))  
        self.spinnerObject2.size_hint = (0.2, 0.2)       
        self.spinnerObject2.pos_hint ={'x': .35, 'y':.20}       
        layout.add_widget(self.spinnerObject2)
        #spinner-selection
        self.spinnerObject2.bind(text=self.spinner_select)
        self.spinnerSelection2 = Label(text="%s"%self.spinnerObject2.text)
        layout.add_widget(self.spinnerSelection2)
        self.spinnerSelection2.pos_hint={'x': .1, 'y':.3}

        layout.add_widget(Label(text=self.name, font_size=30))
        navig = BoxLayout(size_hint=(0.2,0.4),pos_hint={'top': 1, 'center_x':0.5})
        next = Button(text='Search')
        next.bind(on_release=self.switch_next)
        navig.add_widget(next)
        layout.add_widget(navig)
        self.add_widget(layout)
    def spinner_select(self,spinner,text):
        self.spinnerSelection.text = "%s"%self.spinnerObject.text
        self.spinnerSelection1.text = "%s"%self.spinnerObject1.text
        self.spinnerSelection2.text = "%s"%self.spinnerObject2.text

        self.ib=Image1BHKNorth()
        self.ib1=Image1BHKEast()
        if self.spinnerSelection.text=='1BHK'and self.spinnerSelection1.text=='800' and self.spinnerSelection2.text=='North':
            self.ib.imagebutton1bhknorth()
            sm.add_widget(Image1BHKNorth(name='onebhkn'))
        if self.spinnerSelection.text=='1BHK'and self.spinnerSelection1.text=='800' and self.spinnerSelection2.text=='East':
            self.ib1.imagebutton1bhkeast()
            sm.add_widget(Image1BHKEast(name='onebhke'))


    def switch_next(self, *args):
        self.manager.transition = SlideTransition(direction="right")
        self.manager.current = self.manager.next()

sm = ScreenManager()
sm.add_widget(CustomScreen())

class SA(App):
    def build(self):
        return sm

if __name__ == '__main__':
    SA().run()  

REVISED:

The conditions are working properly as the popup shows the conditioned image. The only problem is that the images in the kv file(expected to display two images vertically) is not getting displayed(only a blank screen is what I get). The popup image is getting displayed perfectly along with the content given.


Solution

  • Here is a modified version of your code that I think will do what you want. I have added numerous comments in the code to explain the changes I made.

    I noticed that in several places you were doing multiple inheritance (and some were conflicting). You should only do subclassing when you need your subclass to be an instance of the super class. Like your ImageButton is an Image that has ButtonBehavior. But whenever you think about extending a class, consider whether it might be better to just include an instance of that class in yours. For example your Image1BHKNorth extends Image, but is that really needed? You don't need to extend Image in order to use an Image instance in your class.

    # any changes to Config should be the first thing done!!!
    from kivy.config import Config
    Config.set('graphics', 'resizable', 1)
    
    from kivy.app import App
    from kivy.uix.behaviors import ButtonBehavior
    from kivy.uix.image import Image
    from kivy.uix.gridlayout import GridLayout
    from kivy.uix.label import Label
    from kivy.uix.popup import Popup
    from kivy.uix.button import Button
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.spinner import Spinner
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.uix.screenmanager import SlideTransition
    from kivy.lang import Builder
    
    # use Builder.load_string() to tell Kivy about your rules for building Widgets
    Builder.load_string("""
    # A rule that says how a Image1BHKEast Widget should be built
    <Image1BHKEast>:
        Image1e:          # Image1e is just a BoxLayout, so this could be replaced by simply BoxLayout:
            padding:5
            orientation:'vertical'
            ImageButton: 
                source: 'anorth.jpg'
                allow_stretch: True    # allows the image to be stretched to fill the specified size
                keep_ratio: True       # keeps the aspect ratio of the image constant, to avoid distortion
                size_hint: 0.6, 0.6
                pos_hint: {'center_x':.1, 'center_y': .8}  # odd positioning (the left side of the image will likely be off screen)
                on_release: root.on_press1()
            ImageButton: 
                source:'bnorth.jpg'
                allow_stretch: True
                keep_ratio: True
                size_hint: 0.8, 0.8
                pos_hint: {'center_x':.1, 'center_y': .2}
                on_release: root.on_press1()
    
    # similar rule for Image1BHKNorth
    <Image1BHKNorth>:
        Image1n:
            padding:5
            orientation:'vertical'
            ImageButton: 
                source: 'aeast.jpg'
                allow_stretch: True
                keep_ratio: True
                size_hint: 0.6, 0.6
                pos_hint: {'center_x':.1, 'center_y': .8}
                on_release: root.on_press()
            ImageButton: 
                source:'beast.jpg'
                allow_stretch: True
                keep_ratio: True
                size_hint: 0.8, 0.8
                pos_hint: {'center_x':.1, 'center_y': .2}
                on_release: root.on_press()
    """
    )
    class ImageButton(ButtonBehavior, Image):
        pass
    
    # The two classes below extended Screen, but were never used as Screen
    # They now only extend BoxLayout
    # If there is no additional behavior required of these classes, they can be eliminated completely
    class Image1n(BoxLayout):
        pass
    class Image1e(BoxLayout):
        pass
    
    # Eliminated uneeded parent classes
    # When extending Behavior classes, The Behavior class must be listed first
    # eliminated the imagebutton1bhknorth() method as it provided no useful functionality
    class Image1BHKNorth(ButtonBehavior, Screen):
        def on_press(self):
            print(self.size)
            layout = GridLayout(cols=2,rows=2)
            popupLabel = Label(text = "         Details"
                               "\n House Type - 1BHK"
                               "\n Area - 800")
            image= Image(source='anorth1.jpg')
            closeButton = Button(text = "Close",size_hint_x=0.1,size_hint_y=0.1)
            layout.add_widget(popupLabel)
            layout.add_widget(image)
            layout.add_widget(closeButton)
            popup = Popup(title ='                        Details',
                          content = layout)
            popup.open()
            closeButton.bind(on_press = popup.dismiss)
    
    # same comments as above
    class Image1BHKEast(ButtonBehavior, Screen):
        def on_press1(self):
            layout = GridLayout(cols=2,rows=2)
            popupLabel = Label(text = "         Details"
                               "\n House Type - 1BHK"
                               "\n Area - 800\n Direction - North")
            image= Image(source='aeast1.jpg')
            closeButton = Button(text = "Close",size_hint_x=0.1,size_hint_y=0.1)
            layout.add_widget(popupLabel)
            layout.add_widget(image)
            layout.add_widget(closeButton)
            popup = Popup(title ='                        Details',
                          content = layout)
            popup.open()
            closeButton.bind(on_press = popup.dismiss)
    
    class CustomScreen(Screen):
        def __init__(self, **kwargs):
            super(CustomScreen, self).__init__(**kwargs)
            layout = BoxLayout(orientation='vertical')
            self.spinnerObject = Spinner(text ="House",
                  values =("1BHK", "2BHK", "3BHK"),
                  background_color =(0.784, 0.443, 0.216, 1))
    
            self.spinnerObject.size_hint = (0.2, 0.2)
    
            self.spinnerObject.pos_hint ={'x': .35, 'y':.40}
            layout.add_widget(self.spinnerObject)
            #spinner-selection
            self.spinnerObject.bind(text=self.spinner_select)
            self.spinnerSelection = Label(text="%s"%self.spinnerObject.text)
            layout.add_widget(self.spinnerSelection)
            self.spinnerSelection.pos_hint={'x': .1, 'y':.3}
            #second spinner
            self.spinnerObject1 = Spinner(text ="Area",
                  values =("800","1200", "1500", "1800", "2200"),
                  background_color =(0.784, 0.443, 0.216, 1))
            self.spinnerObject1.size_hint = (0.2, 0.2)
    
            self.spinnerObject1.pos_hint ={'x': .35, 'y':.40}
    
            layout.add_widget(self.spinnerObject1)
            #spinner-selection
            self.spinnerObject1.bind(text=self.spinner_select)
            self.spinnerSelection1 = Label(text="%s"%self.spinnerObject1.text)
            layout.add_widget(self.spinnerSelection1)
            self.spinnerSelection1.pos_hint={'x': .1, 'y':.3}
            #third spinner
            self.spinnerObject2 = Spinner(text ="Directions",
                  values =("North","East"),
                  background_color =(0.784, 0.443, 0.216, 1))
            self.spinnerObject2.size_hint = (0.2, 0.2)
            self.spinnerObject2.pos_hint ={'x': .35, 'y':.20}
            layout.add_widget(self.spinnerObject2)
            #spinner-selection
            self.spinnerObject2.bind(text=self.spinner_select)
            self.spinnerSelection2 = Label(text="%s"%self.spinnerObject2.text)
            layout.add_widget(self.spinnerSelection2)
            self.spinnerSelection2.pos_hint={'x': .1, 'y':.3}
    
            layout.add_widget(Label(text=self.name, font_size=30))
            navig = BoxLayout(size_hint=(0.2,0.4),pos_hint={'top': 1, 'center_x':0.5})
            next = Button(text='Search')
            next.bind(on_release=self.switch_next)
            navig.add_widget(next)
            layout.add_widget(navig)
            self.add_widget(layout)
    
        def spinner_select(self,spinner,text):
            self.spinnerSelection.text = "%s"%self.spinnerObject.text
            self.spinnerSelection1.text = "%s"%self.spinnerObject1.text
            self.spinnerSelection2.text = "%s"%self.spinnerObject2.text
    
            # Eliminated ineffective Widget creation and method calls
            if self.spinnerSelection.text=='1BHK'and self.spinnerSelection1.text=='800' and self.spinnerSelection2.text=='North':
                sm.add_widget(Image1BHKNorth(name='onebhkn'))
            if self.spinnerSelection.text=='1BHK'and self.spinnerSelection1.text=='800' and self.spinnerSelection2.text=='East':
                sm.add_widget(Image1BHKEast(name='onebhke'))
    
    
        def switch_next(self, *args):
            self.manager.transition = SlideTransition(direction="right")
            self.manager.current = self.manager.next()
    
    sm = ScreenManager()
    sm.add_widget(CustomScreen(name='main'))    # All Screens need a name
    
    class SA(App):
        def build(self):
            return sm
    
    if __name__ == '__main__':
        SA().run()