简体   繁体   中英

Kivy! Loading matplot graph on multiple screens

I i am trying Load an image from the file chooser from a screen and trying to show a the matplotlib graph of the image in an other screen for which i have used Kivy_matplotlib library here is the code

import numpy as np
import matplotlib.widgets as widgets
import PIL
import matplotlib as mpl
from matplotlib import pyplot as plt
from PIL import Image
from kivy.app import App
from kivy.lang import Builder
from kivy_matplotlib import MatplotFigure, MatplotNavToolbar
from kivy.uix.screenmanager import ScreenManager, Screen

kv = """
<ScreenTwo>:
    id:sc1
    BoxLayout:
        FileChooserListView:
            id: filechooser
            on_selection: my_widget.selected(filechooser.selection)
        Button:
            text: "Go to Screen 1"
            on_press:
                root.manager.transition.direction = 'right'
                root.manager.current = 'screen_one'

<ScreenOne>
    BoxLayout:
        orientation: 'vertical'
        Button:
            text:"Choose File"
            on_press:
                root.manager.transition.direction = 'right'
                root.manager.current = 'screen_two'
        MatplotFigure:
            id: figure_wgt
            size_hint: 1, 0.9
        MatplotNavToolbar:
            id: navbar_wgt
            size_hint: 1, 0.1
            figure_widget: figure_wgt
"""

class ScreenOne(Screen):
    pass


class ScreenTwo(Screen):
    pass


# The ScreenManager controls moving between screens
screen_manager = ScreenManager()

# Add the screens to the manager and then supply a name
# that is used to switch screens
screen_manager.add_widget(ScreenOne(name="screen_one"))
screen_manager.add_widget(ScreenTwo(name="screen_two"))

class testApp(App):
    title = "Test Matplotlib"

    def build(self):

        # Matplotlib stuff, figure and plot
        fig = mpl.figure.Figure(figsize=(2, 2))

        def onselect(eclick, erelease):
            if eclick.ydata>erelease.ydata:
                eclick.ydata,erelease.ydata=erelease.ydata,eclick.ydata
            if eclick.xdata>erelease.xdata:
                eclick.xdata,erelease.xdata=erelease.xdata,eclick.xdata
            ax.set_ylim(erelease.ydata,eclick.ydata)
            ax.set_xlim(eclick.xdata,erelease.xdata)
            fig.canvas.draw()

        fig = plt.figure()
        ax = fig.add_subplot(111)
        filename="phase.jpg"
        im = Image.open(filename)
        arr = np.asarray(im)
        plt_image=plt.imshow(arr)
        rs=widgets.RectangleSelector(
            ax, onselect, drawtype='box',
            rectprops = dict(facecolor='red', edgecolor = 'black', alpha=0.5, fill=True))
        #plt.show()
        print(arr)

        # Kivy stuff
        root = Builder.load_string(kv)
        figure_wgt = ScreenOne.ids['figure_wgt']  # MatplotFigure
        figure_wgt.figure = fig

        return screen_manager

#testApp().run()

sample_app = testApp()
sample_app.run()

I am stuck as I am getting the following traceback

/home/naveen/Environments/aagnaa/bin/python "/home/naveen/Py files/tut/select and crop2 (copy).py"
[INFO              ] [Logger      ] Record log in /home/naveen/.kivy/logs/kivy_17-06-01_150.txt
[INFO              ] [Kivy        ] v1.9.1
[INFO              ] [Python      ] v3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609]
[INFO              ] [Factory     ] 179 symbols loaded
[INFO              ] [Image       ] Providers: img_tex, img_dds, img_gif, img_sdl2, img_pil (img_ffpyplayer ignored)
[INFO              ] [OSC         ] using <multiprocessing> for socket
[INFO              ] [Window      ] Provider: sdl2(['window_egl_rpi'] ignored)
[INFO              ] [GL          ] OpenGL version <b'2.1 Mesa 12.0.6'>
[INFO              ] [GL          ] OpenGL vendor <b'Intel Open Source Technology Center'>
[INFO              ] [GL          ] OpenGL renderer <b'Mesa DRI Intel(R) Ironlake Mobile '>
[INFO              ] [GL          ] OpenGL parsed version: 2, 1
[INFO              ] [GL          ] Shading version <b'1.20'>
[INFO              ] [GL          ] Texture max size <8192>
[INFO              ] [GL          ] Texture max units <16>
[INFO              ] [Window      ] auto add sdl2 input provider
[INFO              ] [Window      ] virtual keyboard allowed, single mode, docked

 Traceback (most recent call last):
   File "/home/naveen/Py files/tut/select and crop2 (copy).py", line 97, in <module>
     sample_app.run()
   File "/usr/lib/python3/dist-packages/kivy/app.py", line 802, in run
     root = self.build()
   File "/home/naveen/Py files/tut/select and crop2 (copy).py", line 89, in build
     figure_wgt = ScreenOne.ids['figure_wgt']  # MatplotFigure
 TypeError: 'kivy.properties.DictProperty' object is not subscriptable

Process finished with exit code 1

Need help Thanks in advance

You need to re-order the flow of code execution. You have to insert string into the Language Builder before adding the widgets.

kv = """
<ScreenTwo>:
    id:sc1
    BoxLayout:
        FileChooserListView:
            id: filechooser
            on_selection: my_widget.selected(filechooser.selection)
        Button:
            text: "Go to Screen 1"
            on_press:
                root.manager.transition.direction = 'right'
                root.manager.current = 'screen_one'

<ScreenOne>:
    BoxLayout:
        orientation: 'vertical'
        Button:
            text:"Choose File"
            on_press:
                root.manager.transition.direction = 'right'
                root.manager.current = 'screen_two'
        MatplotFigure:
            id: figure_wgt
            size_hint: 1, 0.9
        MatplotNavToolbar:
            id: navbar_wgt
            size_hint: 1, 0.1
            figure_widget: figure_wgt
"""
# Insert string into Language builder.
Builder.load_string(kv)

class ScreenOne(Screen):
    pass

class ScreenTwo(Screen):
    pass

# The ScreenManager controls moving between screens
screen_manager = ScreenManager()
screen_manager.add_widget(ScreenOne(name="screen_one"))
screen_manager.add_widget(ScreenTwo(name="screen_two"))

class testApp(App):
    title = "Test Matplotlib"

    def build(self):

        # ....

        # get first screen and update figure

        screen_one = screen_manager.get_screen('screen_one')

        screen_one.ids['figure_wgt'].figure = fig

        return screen_manager


sample_app = testApp()
sample_app.run()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM