sh37211
sh37211

Reputation: 1523

Kivy (Python) TabbedPanel - different (dynamic) sized tabs?

Kivy seems to want to make all tabs the same size. What if I want to make one tab wider than others? Adjusting tab_width for a TabbedPanelItem seems to have no effect, and as such the longer text is getting cut off.

Example modified slightly from Kivy TabbedPanel docs, where I changed the first tab's heading to "Long Text for a Tab":

from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.lang import Builder

Builder.load_string("""

<Test>:
    #size_hint: .5, .5
    pos_hint: {'center_x': .5, 'center_y': .5}
    do_default_tab: False

    TabbedPanelItem:
        text: 'Long Text for a Tab'
        tab_width: self.texture_size[0]
        Label:
            text: 'First tab content area'
    TabbedPanelItem:
        text: 'tab2'
        BoxLayout:
            Label:
                text: 'Second tab content area'
            Button:
                text: 'Button that does nothing'
    TabbedPanelItem:
        text: 'tab3'
        RstDocument:
            text:
                '\\n'.join(("Hello world", "-----------",
                "You are in the third tab."))

""")


class Test(TabbedPanel):
    pass


class TabbedPanelApp(App):
    def build(self):
        return Test()


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

...so the "Long Text" gets chopped up because all 3 tabs get the same width. Even setting the first tab's tab_width to a constant (e.g. 300) gets ignored.

Seems that you can supply tab_width to the TabbedPanel and it makes all tabs the same, but how do you make individual tabs (TabbedPanelItems) to have different (even dynamic) widths, i.e. so that some tabs are wider than others?

Upvotes: 1

Views: 1320

Answers (1)

FJSevilla
FJSevilla

Reputation: 4513

tab_width is a TabbedPanel property, not a TabbedPanelItem property and is applied to all tabs.

To set a different size to each tab you can set tab_widht to None and then use TabbedPanelItem properties properly (it is based on Togglebutton, so you can use size_hint_x and size properties):

<Test>:
    pos_hint: {'center_x': .5, 'center_y': .5}
    do_default_tab: False
    tab_width: None

    TabbedPanelItem:
        text: 'Long Text for a Tab'
        size_hint_x: None
        width: self.texture_size[0]
        padding: 10, 0

        Label:
            text: 'First tab content area'

Edit:

Apparently it is necessary to explicitly update the width of the tabs after the initialization of TabbedPanel, you can use Clock.schedule_once and on_tab_width method to do this:

from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelItem
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
from kivy.lang import Builder

Builder.load_string("""

<CustomWidthTabb@TabbedPanelItem>
    width: self.texture_size[0]
    padding: 10, 0
    size_hint_x: None

<Test>:
    size_hint: 1,1
    do_default_tab: False
    tab_width: None

    CustomWidthTabb:
        text: "This is a Long Tab"
        Label:
            text: 'First tab content area'

    CustomWidthTabb:
        text: "This is a Long Tab"
        Label:
            text: 'Second tab content area'

    CustomWidthTabb:
        text: "Short Tab"     
        Label:
            text: 'Third tab content area'

    CustomWidthTabb:
        text: "Short Tab#2"   
        Label:
            text: 'Fourth tab content area'

""")



class Test(TabbedPanel):
    def __init__(self, *args, **kwargs):
        super(Test, self).__init__(*args, **kwargs)
        Clock.schedule_once(self.on_tab_width, 0.1)

class TabbedPanelApp(App):
    def build(self):
        return Test()


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

enter image description here

Upvotes: 1

Related Questions