Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'Cannot add kivy.uix.actionbar.ActionSeparator - it already has a parent' #3737

Open
DavidA2014 opened this issue Oct 30, 2015 · 3 comments
Open

Comments

@DavidA2014
Copy link

Working with Kivy 1.9.1 on Windows 8.1, I get an exception with a certain widget tree when working with garden.matplotlib, which uses actionbar. I'm told that this is a generic Kivy issue, not an issue with garden.matplotlib.

Here are files that demo the problem. Sorry they are long but I did my best to cut them down.

main.py:

#!/usr/bin/python3

import sys
from kivy.app import App
from kivy.config import Config

Config.set('graphics', 'width', '800')
Config.set('graphics', 'height', '600')

from mygraph import CMplGraph

class GuiApp(App):

    def __init__(self, **kwargs):
        super(GuiApp, self).__init__(**kwargs)


if __name__ == '__main__':

    GuiApp().run()

mygraph.py

import matplotlib
matplotlib.use('module://kivy.garden.matplotlib.backend_kivy')
from matplotlib.figure import Figure
from numpy import arange, sin, pi
from kivy.app import App
import numpy as np
from kivy.garden.matplotlib.backend_kivyagg import FigureCanvas,\
                                                NavigationToolbar2Kivy
from matplotlib.transforms import Bbox
import matplotlib.pyplot as plt
from kivy.uix.boxlayout import BoxLayout

listA=[(0xBE14, 0x3408), (0xC65E, 0x3ABE)]

listB = [( 13322,  -16873), ( 15038,  -14751)]

def press(event):
    print('press released from test', event.x, event.y, event.button)


def release(event):
    print('release released from test', event.x, event.y, event.button)


def keypress(event):
    print('key down', event.key)


def keyup(event):
    print('key up', event.key)


def motionnotify(event):
    print('mouse move to ', event.x, event.y)


def resize(event):
    print('resize from mpl ', event)


def scroll(event):
    print('scroll event from mpl ', event.x, event.y, event.step)


def figure_enter(event):
    print('figure enter mpl')


def figure_leave(event):
    print('figure leaving mpl')


def close(event):
    print('closing figure')

def autolabel(rects):
    # attach some text labels
    for rect in rects:
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width() / 2., 1.05 * height,
                '%d' % int(height), ha='center', va='bottom')

def callback(instance):
    autolabel(rects1)
    autolabel(rects2)
    canvas.draw()

class CMplGraph(BoxLayout):
    """This class presents an example graphical plot using MatPlotLib
    """
    pass

    def __init__(self, **kwargs):
        super(CMplGraph, self).__init__(**kwargs)
        self.create_plot()

    def create_plot(self):
        N = 5
        menMeans = (20, 35, 30, 35, 27)
        menStd = (2, 3, 4, 1, 2)

        ind = np.arange(N)  # the x locations for the groups
        width = 0.35       # the width of the bars

        fig, ax = plt.subplots()

        for i in range(len(listA)):
            x = listA[i][0]
            y = listA[i][1]
            if x > 32767:
                x = x - pow(2,16)
            if y > 32767:
                y = y - pow(2,16)
            x = x / pow(2,14)
            listA[i] = (i,x)

        xCoords = [ t[0] for t in listA ]
        yCoords = [ t[1] for t in listA ]

        lineA = ax.plot(xCoords, yCoords, color='blue', marker='o', markerfacecolor='blue', markersize=6)

        for i in range(len(listB)):
            x = listB[i][0]
            y = listB[i][1]
            if x > 32767:
                x = x - pow(2,16)
            if y > 32767:
                y = y - pow(2,16)
            x = x / pow(2,14)
            listB[i] = (i,x)

        xCoords = [ t[0] for t in listB ]
        yCoords = [ t[1] for t in listB ]

        lineB = ax.plot(xCoords, yCoords, color='red', marker='o', markerfacecolor='red', markersize=6)

        ax.set_xlabel('RB')
        ax.set_ylabel('Magnitude')
        ax.set_title('Data')
        ax.set_ylim([-2, 2])
        ax.legend((lineA[0], lineB[0]), ('Real', 'Imag'))

        fig.canvas.mpl_connect('button_press_event', press)
        fig.canvas.mpl_connect('button_release_event', release)
        fig.canvas.mpl_connect('key_press_event', keypress)
        fig.canvas.mpl_connect('key_release_event', keyup)
        fig.canvas.mpl_connect('motion_notify_event', motionnotify)
        fig.canvas.mpl_connect('resize_event', resize)
        fig.canvas.mpl_connect('scroll_event', scroll)
        fig.canvas.mpl_connect('figure_enter_event', figure_enter)
        fig.canvas.mpl_connect('figure_leave_event', figure_leave)
        fig.canvas.mpl_connect('close_event', close)

        canvas = fig.canvas

        nav1 = NavigationToolbar2Kivy(canvas)

        self.add_widget(nav1.actionbar)
        self.add_widget(canvas)

gui.kv

<CMplGraph>:
    id: my_graph
    orientation: 'vertical'

TabbedPanel:
    id: tab_panel
    do_default_tab: False

    TabbedPanelItem:
        id: tab_graph
        text: 'Graph'

        BoxLayout:
            id: CalBoxLayout
            orientation: 'horizontal'

            CMplGraph:

The problem

If I run the code as is, all is fine:

python main.py

If, in gui.kv, I replace the last line ( CMplGraph: ) with:

            BoxLayout:
                id: CalButtons
                orientation: 'vertical'
                size_hint_x: .25

                Button:
                    text: '1'

            BoxLayout:
                id: MyGraph

                CMplGraph:

I get an exception:

C:\>python main.py
 Traceback (most recent call last):
   File "main.py", line 20, in <module>
     GuiApp().run()
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\app.py", line 828, in run
     runTouchApp()
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\base.py", line 487, in runTouchApp
     EventLoop.window.mainloop()
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\core\window\window_sdl2.py", line 606, in mainloo
p
     self._mainloop()
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\core\window\window_sdl2.py", line 361, in _mainlo
op
     EventLoop.idle()
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\base.py", line 336, in idle
     Clock.tick_draw()
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\clock.py", line 490, in tick_draw
     self._process_events_before_frame()
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\clock.py", line 640, in _process_events_before_fr
ame
     event.tick(self._last_tick, remove)
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\clock.py", line 374, in tick
     ret = callback(self._dt)
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\uix\boxlayout.py", line 175, in do_layout
     c.width = w
   File "kivy\properties.pyx", line 408, in kivy.properties.Property.__set__ (kivy\properties.c:4967)
   File "kivy\properties.pyx", line 446, in kivy.properties.Property.set (kivy\properties.c:5665)
   File "kivy\properties.pyx", line 501, in kivy.properties.Property.dispatch (kivy\properties.c:6314)
   File "kivy\_event.pyx", line 1223, in kivy._event.EventObservers.dispatch (kivy\_event.c:12615)
   File "kivy\_event.pyx", line 1129, in kivy._event.EventObservers._dispatch (kivy\_event.c:11914)
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\uix\actionbar.py", line 617, in on_width
     self._layout_random()
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\uix\actionbar.py", line 567, in _layout_random
     super_add(child, group_index)
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\uix\boxlayout.py", line 213, in add_widget
     return super(BoxLayout, self).add_widget(widget, index)
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\uix\layout.py", line 87, in add_widget
     return super(Layout, self).add_widget(widget, index)
   File "C:\Kivy-1.9.0-py3.4-win32-x64\Python34\lib\site-packages\kivy\uix\widget.py", line 509, in add_widget
     % (widget, parent))
 kivy.uix.widget.WidgetException: Cannot add <kivy.uix.actionbar.ActionSeparator object at 0x00000000086EF9A8>, it alrea
dy has a parent <kivy.uix.actionbar.ActionOverflow object at 0x00000000086A1708>

Workaround

A workaround is to disable the actionbar:

        # Add each navigation toolbar and canvas to our BoxLayout
        # self.add_widget(nav1.actionbar)                                                     <==========
        self.add_widget(canvas)

@kayemen
Copy link

kayemen commented Jun 22, 2017

Has any progress been made with this issue?? Is there a solution?

@stale
Copy link

stale bot commented Oct 20, 2017

Thanks for your contribution!

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs in the next 14 days.

If you would like this issue to remain open:

  1. Verify that you can still reproduce the issue with the latest development version of Kivy
  2. Comment that the issue is still reproducible and include:
    • What version of Kivy you reproduced the issue on
    • What OS and version you reproduced the issue on
    • What steps you followed to reproduce the issue (if missing or incomplete)
    • A minimal working example which reproduces the issue (if missing or incomplete)
    • Full runtime logs

Issues that are labeled as confirmed or triaged will not be automatically marked as stale. For a full list of exempt labels, see the config.

@stale stale bot added the stale label Oct 20, 2017
@razed11
Copy link

razed11 commented Apr 14, 2018

This probably should be posted against the Matplotlib Garden repository but that appears to have been abandoned a couple of years ago.

Same issue using 1.10.1.dev0. The garden examples appear to work fine--the action bars are displayed and function properly. In my case I'm building things in the constructor:

        canvas = self._figure.canvas

        navigator = NavigationToolbar2Kivy(canvas)

        self.ids.id_graph_board.add_widget(canvas)

        self.ids.id_graph_board.add_widget(navigator.actionbar)

@dessant dessant removed the stale label May 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants