Programmaticially select tabbedPanel not in view

100 views
Skip to first unread message

markR

unread,
Nov 22, 2021, 8:47:16 PM11/22/21
to Kivy users support
I have nested tabPanels in parent tabPanels. I want to select a button and through it's bind event bring the "not in view" panel into view. I do not see any "bring to front", "visible", etc options. I am new to kivy and just learning python.
Thanks for any suggestions as nothing just jumps out at me in the documentation.

Elliot Garbus

unread,
Nov 22, 2021, 9:17:24 PM11/22/21
to kivy-...@googlegroups.com

--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/ad2ccf15-f76d-4654-8678-444c1064e07bn%40googlegroups.com.

 

markR

unread,
Nov 23, 2021, 6:52:53 PM11/23/21
to Kivy users support
Could you share a little more info on how I might use the switch_to() method? I generate the tabbed panels/headers/and layouts in a class that inherits TabbedPanel. I have a function outside the class that handles the buttons down event through binding. I am thinking that in this function I would utilize the switch_to() method. Do you use the headers text to identify it or a node(which I will have to learn about)

Elliot Garbus

unread,
Nov 23, 2021, 7:38:21 PM11/23/21
to kivy-...@googlegroups.com

Here is an example.  You use the instance of the tab headers to use switch_to.

 

 

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

import itertools

kv =
"""
BoxLayout:
    orientation: 'vertical'
    MyPanel:
        id: tabbed_panel
        do_default_tab: False
        TabbedPanelItem:
            text: '1'
            Label:
                text: 'Tab One Content'
        TabbedPanelItem:
            text: '2'
            Label:
                text: 'Tab Two Content'
        TabbedPanelItem:
            text: '3'
            Label:
                text: 'Tab Three Content'
        TabbedPanelItem:
            text: '4'
            Label:
                text: 'Tab Four Content'
    BoxLayout:
        size_hint_y: None
        height: 48
        Button:
            text: 'Switch tab 1'
            on_release: tabbed_panel.tab_one()       
        Button:
            text: 'Cycle through tabs'
            on_release: tabbed_panel.cycle_tabs()       
        Button:
            text: 'Switch to tab 4'
            on_release: tabbed_panel.tab_four()       
"""

class MyPanel(TabbedPanel):
   
def __init__(self, **kwargs):
       
super().__init__(**kwargs)
       
self.tabs_cycle = None  # use to hold tabs

   
def on_kv_post(self, base_widget):
       
self.tabs_cycle = itertools.cycle(self.tab_list[::-1])  # tabs in an iterator to cycle through the tabs

   
def cycle_tabs(self):
       
self.switch_to(next(self.tabs_cycle))

   
def tab_one(self):
       
self.switch_to(self.tab_list[-1]) # widgets get added in reverse order the last in the list is the first

   
def tab_four(self):
       
self.switch_to(self.tab_list[0])


class TabExampleApp(App):
   
def build(self):
       
return Builder.load_string(kv)


TabExampleApp().run()

markR

unread,
Nov 26, 2021, 4:15:35 PM11/26/21
to Kivy users support
Thank you. I will research more on what you are actually describing as I am not advanced enough to understand it all. Looks like you are cycling through a list of tab headers. If I may,  why  cant I identify the tab header when it is created "self.ids" and then engage it through the "switch_to" method? That works for me when I "switch_to" a tab header on the main tabbed panel but does not when i try to "switch_to" a tad header on a tabbed panel which is a child of a header of the main tabbed panel.

class MyApp(TabbedPanel):
def __init__(self,data_base,myCow,myCalf,myBull):
super(MyApp, self).__init__()
self.db=data_base
self.do_default_tab=False
self.myCow=myCow
for i in opList:#add headers for Location, Add, Edit/View
myTPHM=TabbedPanelHeader()
myTPHM.text=str(i)
self.add_widget(myTPHM)

if str(i)=='Edit/View':# add new tabbed panel with headers for Cow,Calf,Bull
self.ids['E/V']=myTPHM# this one works
myTPEV=TabbedPanel()
myTPEV.do_default_tab=False
myTPHM.content=myTPEV

cowTPHEV=TabbedPanelHeader()
self.ids['cowE/V']=cowTPHEV# this one goes to the main tabbed panel but does not select down to the sub header needed
cowTPHEV.text='Cow'
myTPEV.add_widget(cowTPHEV)
cowStkLoc=StackLayout(orientation='tb-lr',spacing=4)
cowTPHEV.content=cowStkLoc

#... button creation here Cow- inherits button

Cow.bind(on_press=self.cowBtn_Press)
stkLoc.add_widget(Cow)

def cowBtn_Press(self,instance):
print (instance.text,instance.sex)
#mtp = App.get_running_app().root
#mtp.switch_to(mtp.ids['cowE/V'])
#self.switch_to(self.ids['E/V'])
self.switch_to(self.ids['cowE/V'])

Elliot Garbus

unread,
Nov 26, 2021, 5:15:00 PM11/26/21
to kivy-...@googlegroups.com

You can use the id and the switch_to method.  I have modified the example to use id at the bottom of this post.

 

I can be more helpful if you post a complete runnable example.  The id is created in kv, and when the kv code is complied an ids dictionary is created where the key is the id and the value is the widget.  Widgets created in python do not have an id, and do not populate the ids dictionary.  Try printing the ids so you can see how this works.  When you press the ‘Switch Tab 1’ button in the example, it will print out the ids in the example.

 

 

The code you have highlighted does not make sense to me:

               self.ids['E/V']=myTPHM# this one works  You are overwriting the value in the ids dictionary. 

                self.ids['cowE/V']=cowTPHEV# this one goes to the main tabbed panel but does not select down to the sub header needed  Again, this is overwriting the ids dictionary.

 

                You can save the header widget to a list or a variable name and then use it as a parameter in switch_to, you do not need to overwrite the ids dictionary.  You should treat the ids dict as read-only.

 

Example updated to use ids:

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

import itertools

kv =
"""

BoxLayout:
    orientation: 'vertical'
    MyPanel:
        id: tabbed_panel
        do_default_tab: False
        TabbedPanelItem:
            id: tab_1

            text: '1'
            Label:
                text: 'Tab One Content'
        TabbedPanelItem:
            text: '2'
            Label:
                text: 'Tab Two Content'
        TabbedPanelItem:
            text: '3'
            Label:
                text: 'Tab Three Content'
        TabbedPanelItem:
            id: tab_4

            text: '4'
            Label:
                text: 'Tab Four Content'
    BoxLayout:
        size_hint_y: None
        height: 48
        Button:
            text: 'Switch tab 1'
            on_release:
                tabbed_panel.switch_to(root.ids.tab_1)
                print(root.ids)

        Button:
            text: 'Cycle through tabs'
            on_release: tabbed_panel.cycle_tabs()       
        Button:
            text: 'Switch to tab 4'
            on_release: tabbed_panel.switch_to(root.ids.tab_4)
"""

class MyPanel(TabbedPanel):
   
def __init__(self, **kwargs):
       
super().__init__(**kwargs)
       
self.tabs_cycle = None  # use to hold tabs

   
def on_kv_post(self, base_widget):
       
self.tabs_cycle = itertools.cycle(self.tab_list[::-1])  # tabs in an iterator to cycle through the tabs

   
def cycle_tabs(self):
       
self.switch_to(next(self.tabs_cycle))


markR

unread,
Nov 26, 2021, 11:11:08 PM11/26/21
to Kivy users support
I attaced the dataBase. Select "location" tab and then "Hermas" child tab and then select a pink button(cow). It should take you to the "Cow" child tab in the "View/Edit" tab. Interestingly it displays widgets on the "Cow" header with out the "Cow" tab as if it was part
part of the "View/Edit" header.



from sqlite3 import dbapi2
from typing import final
import kivy
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanelHeader
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
import sqlite3
from kivy.clock import Clock
from functools import partial

#con=sqlite3.connect('bovine.db');
#c=con.cursor();
#c.execute(""" CREATE TABLE cattleData
# (tagNo integer,
# Loc text,
# sex text,
# type text)
# """)
#c.execute(""" CREATE TABLE locations
# (locName text)
# """);



opList=["Location","Add","Edit/View"]


class MyDataBase:
def __init__(self,db_path):
self.db_path=db_path

def connect(self):
self.con=sqlite3.connect(self.db_path)
self.c=self.con.cursor()

def insert_cattledata(self,tag,loc,sex,type):
self.c.execute("INSERT INTO cattleData VALUES(?,?,?,?)",(tag,loc,sex,type))
self.con.commit()

def insert_locations(self,locName):
self.c.execute("INSERT INTO locations VALUES(?)",(locName, ))
self.con.commit()

def listBy_Loc(self,loc):
self.c.execute("SELECT * FROM cattleData WHERE Loc = ?", (loc,))
cattle=self.c.fetchall()
return cattle

def cowsBy_Loc(self,loc):
self.c.execute("SELECT * FROM cowTbl WHERE Loc = ?", (loc,))
cattle=self.c.fetchall()
return cattle

def calvesBy_Loc(self,loc):
self.c.execute("SELECT * FROM calfTbl WHERE Loc = ?", (loc,))
cattle=self.c.fetchall()
return cattle

def bullsBy_Loc(self,loc):
self.c.execute("SELECT * FROM bullTbl WHERE Loc=?", (loc,))
bull=self.c.fetchall()
return bull
def locationList(self):
self.c.execute('''SELECT * FROM locations;''')
records=self.c.fetchall()
return records
def close_db(self):
self.c.close()


class MyApp(TabbedPanel):
def __init__(self,data_base,myCow,myCalf,myBull):
super(MyApp, self).__init__()
self.db=data_base
self.do_default_tab=False
self.myCow=myCow
for i in opList:#add headers for Location, Add, Edit/View
myTPHM=TabbedPanelHeader()
myTPHM.text=str(i)
self.add_widget(myTPHM)

if str(i)=='Edit/View':# add new tabbed panel with headers for Cow,Calf,Bull
self.ids['E/V']=myTPHM
myTPEV=TabbedPanel()
myTPEV.do_default_tab=False
myTPHM.content=myTPEV

cowTPHEV=TabbedPanelHeader()
self.ids['cowE/V']=cowTPHEV
cowTPHEV.text='Cow'
myTPEV.add_widget(cowTPHEV)
cowTPHEV.content=self.ev_cowScreen()

calfTPHEV=TabbedPanelHeader()
calfTPHEV.text='Calf'
myTPEV.add_widget(calfTPHEV)
calfStkLoc=StackLayout(orientation='tb-lr',spacing=4)
calfTPHEV.content=calfStkLoc
bullTPHEV=TabbedPanelHeader()
myTPEV.add_widget(bullTPHEV)
bullTPHEV.text='Bull'
bullStkLoc=StackLayout(orientation='tb-lr',spacing=4)
bullTPHEV.content=bullStkLoc

if str(i)=='Location':# add new tabbed panel with headers for all locations
myTPLoc=TabbedPanel()
myTPLoc.do_default_tab=False
myTPHM.content=myTPLoc
for row in self.db.locationList():
location=row[0]
myTPHL=TabbedPanelHeader()
myTPHL.text=location
myTPLoc.add_widget(myTPHL)
stkLoc=StackLayout(orientation='tb-lr',spacing=4)
myTPHL.content=stkLoc
### add animals to loc tab
for cows in self.db.cowsBy_Loc(location):
tagNo=cows[0]
tagClr=cows[1]
tagYr=cows[2]
type=cows[3]
desc=cows[4]
loc=cows[5]
locDte=cows[6]
birthDte=cows[7]
birthWt=cows[8]
weanDte=cows[9]
weanWt=cows[10]
sex=cows[11]
status=cows[12]
aquired=cows[13]
aquiredDte=cows[14]
disposition=cows[15]
dispDte=cows[16]
aquiredCst=cows[17]
soldAmt=cows[18]
bredByTag=cows[19]
bredByTagClr=cows[20]
bredByTagYr=cows[21]
bredByDes=cows[22]
actCalveDte=cows[23]
calfTagNo=cows[24]
calfTagClr=cows[25]
calfTagYr=cows[26]
Cow=myCow(tagNo,tagClr,tagYr,type,desc,loc,locDte,birthDte,birthWt,
weanDte,weanWt,sex,status,aquired,aquiredDte,disposition,
dispDte,aquiredCst,soldAmt,bredByTag,bredByTagClr,bredByTagYr,
bredByDes,actCalveDte,calfTagNo,calfTagClr,calfTagYr)
Cow.bind(on_press=self.cowBtn_Press)
stkLoc.add_widget(Cow)

for calves in self.db.calvesBy_Loc(location):
tagNo=calves [0]
tagClr=calves [1]
tagYr=calves [2]
type=calves [3]
desc=calves [4]
loc=calves [5]
locDte=calves [6]
birthDte=calves [7]
birthWt=calves [8]
weanDte=calves [9]
weanWt=calves [10]
sex=calves [11]
status=calves [12]
aquired=calves [13]
aquiredDte=calves [14]
disposition=calves [16]
dispDte=calves [17]
aquiredCst=calves [15]
soldAmt=calves[18]
damTagNo=calves[19]
damTagClr=calves[20]
damTagYr=calves[21]
sireTagNo=calves[22]
sireTagClr=calves[23]
sireTagYr=calves[24]
finishedWt=calves[25]
finishedDte=calves[26]
lbDayFeed=calves[27]
Calf=myCalf(tagNo,tagClr,tagYr,type,desc,loc,locDte,birthDte,birthWt,
weanDte,weanWt,sex,status,aquired,aquiredDte,disposition,
dispDte,aquiredCst,soldAmt,damTagNo,damTagClr,damTagYr,
sireTagNo,sireTagClr,sireTagYr,finishedWt,finishedDte,lbDayFeed)
Calf.bind(on_press=self.cowBtn_Press)

stkLoc.add_widget(Calf)

for bulls in self.db.bullsBy_Loc(location):
tagNo=bulls[0]
tagClr=bulls[1]
tagYr=bulls[2]
type=bulls[3]
desc=bulls[4]
loc=bulls[5]
locDte=bulls[6]
birthDte=bulls[7]
birthWt=bulls[8]
weanDte=bulls[9]
weanWt=bulls[10]
sex=bulls[11]
status=bulls[12]
aquired=bulls[13]
aquiredDte=bulls[14]
disposition=bulls[15]
dispDte=bulls[16]
aquiredCst=bulls[17]
soldAmt=bulls[18]
adg=bulls[19]
yw=bulls[20]
sc=bulls[21]
ced=bulls[22]
mm=bulls[23]

Bull=myBull(tagNo,tagClr,tagYr,type,desc,loc,locDte,birthDte,birthWt,
weanDte,weanWt,sex,status,aquired,aquiredDte,disposition,
dispDte,aquiredCst,soldAmt,adg,yw,sc,ced,mm)
Bull.bind(on_press=self.cowBtn_Press)
stkLoc.add_widget(Bull)

if str(i)=='Add':
myTPHM.content=self.addScreen()

#if str(i)=='Edit/View':

# pass


def cowBtn_Press(self,instance):
print (instance.text,instance.sex)
#mtp = App.get_running_app().root
#mtp.switch_to(mtp.ids['cowE/V'])
#self.switch_to(self.ids['E/V'])
self.switch_to(self.ids['cowE/V'])

def ev_cowScreen(self):
stkEnter=StackLayout(orientation='tb-lr',spacing=5)
lbl1=Label(text='Tag No',size_hint=(.15,.05))
txtTag=TextInput(text='',size_hint=(.15,.07))
lbl2=Label(text='Tag Color',size_hint=(.15,.05))
txtTagClr=TextInput(text='',size_hint=(.15,.07))
lbl3=Label(text='Tag Yr',size_hint=(.15,.05))
txtTagYr=TextInput(text='',size_hint=(.15,.07))
lbl4=Label(text='Type',size_hint=(.15,.05))
txtType=TextInput(text='',size_hint=(.15,.07))
lbl5=Label(text='Description',size_hint=(.15,.05))
txtDes=TextInput(text='',size_hint=(.15,.07))
lbl6=Label(text='Current Location',size_hint=(.15,.05))
txtLoc=TextInput(text='',size_hint=(.15,.07))
lbl7=Label(text='Location Date',size_hint=(.15,.05))
txtLocDte=TextInput(text='',size_hint=(.15,.07))
lbl8=Label(text='Birth Date',size_hint=(.15,.05))
txtBD=TextInput(text='',size_hint=(.15,.07))
lbl9=Label(text='Birth Wt',size_hint=(.15,.05))
txtBWt=TextInput(text='',size_hint=(.15,.07))
lbl10=Label(text='Wean Date',size_hint=(.15,.05))
txtWeanDte=TextInput(text='',size_hint=(.15,.07))
lbl11=Label(text='Wean Wt',size_hint=(.15,.05))
txtWeanWt=TextInput(text='',size_hint=(.15,.07))
lbl11=Label(text='Sex',size_hint=(.15,.05))
txtSex=TextInput(text='',size_hint=(.15,.07))
lbl12=Label(text='Status',size_hint=(.15,.05))
txtStatus=TextInput(text='',size_hint=(.15,.07))
lbl13=Label(text='Aquired',size_hint=(.15,.05))
txtAquired=TextInput(text='',size_hint=(.15,.07))
lbl14=Label(text='Aquired Date',size_hint=(.15,.05))
txtAquiredDte=TextInput(text='',size_hint=(.15,.07))
lbl15=Label(text='Aquired cost',size_hint=(.15,.05))
txtAquiredCst=TextInput(text='',size_hint=(.15,.07))
lbl16=Label(text='Disposition',size_hint=(.15,.05))
txtDispo=TextInput(text='',size_hint=(.15,.07))
lbl17=Label(text='Disp Date',size_hint=(.15,.05))
txtDispDte=TextInput(text='',size_hint=(.15,.07))
lbl18=Label(text='Sold Amt',size_hint=(.15,.05))
txtSold=TextInput(text='',size_hint=(.15,.07))
lbl19=Label(text='Bred date',size_hint=(.15,.05))
txtBredDte=TextInput(text='',size_hint=(.15,.07))
lbl24=Label(text='Est Calving Date',size_hint=(.15,.05))
txtEstClvDte=TextInput(text='',size_hint=(.15,.07))
lbl20=Label(text='Bred By TagNo',size_hint=(.15,.05))
txtBullTagNo=TextInput(text='',size_hint=(.15,.07))
lbl21=Label(text='Bred By Tag Color',size_hint=(.15,.05))
txtBullTagClr=TextInput(text='',size_hint=(.15,.07))
lbl22=Label(text='Bred By Tag Yr',size_hint=(.15,.05))
txtBullTagYr=TextInput(text='',size_hint=(.15,.07))
lbl23=Label(text='Actual Calving Date ',size_hint=(.15,.05))
txtActClvDte=TextInput(text='',size_hint=(.15,.07))
lbl25=Label(text='Calf TagNo',size_hint=(.15,.05))
txtCalfTagNo=TextInput(text='',size_hint=(.15,.07))
lbl26=Label(text='Calf Tag Color',size_hint=(.15,.05))
txtCalfTagClr=TextInput(text='',size_hint=(.15,.07))
lbl27=Label(text='Calf Tag Yr',size_hint=(.15,.05))
txtCalfTagYr=TextInput(text='',size_hint=(.15,.07))

btnAccept=Button(text='Add',size_hint=(.1,.05))
stkEnter.add_widget(lbl1)
stkEnter.add_widget(txtTag)
stkEnter.add_widget(lbl2)
stkEnter.add_widget(txtTagClr)
stkEnter.add_widget(lbl3)
stkEnter.add_widget(txtTagYr)
stkEnter.add_widget(lbl4)
stkEnter.add_widget(txtType)
stkEnter.add_widget(lbl5)
stkEnter.add_widget(txtDes)
stkEnter.add_widget(lbl6)
stkEnter.add_widget(txtLoc)
stkEnter.add_widget(lbl7)
stkEnter.add_widget(txtLocDte)
stkEnter.add_widget(lbl8)
stkEnter.add_widget(txtBD)
stkEnter.add_widget(lbl9)
stkEnter.add_widget(txtBWt)
stkEnter.add_widget(lbl10)
stkEnter.add_widget(txtWeanDte)
stkEnter.add_widget(lbl11)
stkEnter.add_widget(txtWeanWt)
stkEnter.add_widget(lbl12)
stkEnter.add_widget(txtStatus)
stkEnter.add_widget(lbl13)
stkEnter.add_widget(txtAquired)
stkEnter.add_widget(lbl14)
stkEnter.add_widget(txtAquiredDte)
stkEnter.add_widget(lbl15)
stkEnter.add_widget(txtAquiredCst)
stkEnter.add_widget(lbl16)
stkEnter.add_widget(txtDispo)
stkEnter.add_widget(lbl17)
stkEnter.add_widget(txtDispDte)
stkEnter.add_widget(lbl18)
stkEnter.add_widget(txtSold)
stkEnter.add_widget(lbl19)
stkEnter.add_widget(txtBredDte)
stkEnter.add_widget(lbl24)
stkEnter.add_widget(txtEstClvDte)
stkEnter.add_widget(lbl23)
stkEnter.add_widget(txtActClvDte)
stkEnter.add_widget(lbl25)
stkEnter.add_widget(txtCalfTagNo)
stkEnter.add_widget(lbl26)
stkEnter.add_widget(txtCalfTagClr)
stkEnter.add_widget(lbl27)
stkEnter.add_widget(txtCalfTagYr)
stkEnter.add_widget(lbl20)
stkEnter.add_widget(txtBullTagNo)
stkEnter.add_widget(lbl21)
stkEnter.add_widget(txtBullTagClr)
stkEnter.add_widget(lbl22)
stkEnter.add_widget(txtBullTagYr)
stkEnter.add_widget(btnAccept)

return stkEnter

def addScreen(self):
stkEnter=StackLayout(orientation='lr-tb',spacing=4)
lbl1=Label(text='Tag No',size_hint=(.1,.04))
lbl2=Label(text='Location',size_hint=(.1,.04))
lbl3=Label(text='Sex',size_hint=(.1,.04))
lbl4=Label(text='type',size_hint=(.1,.04))
txtTag=TextInput(text='',size_hint=(.1,.06))
txtLoc=TextInput(text='',size_hint=(.1,.06))
txtSex=TextInput(text='',size_hint=(.1,.06))
txtType=TextInput(text='',size_hint=(.1,.06))
btnAccept=Button(text='add',size_hint=(.1,.04))
stkEnter.add_widget(lbl1)
stkEnter.add_widget(txtTag)
stkEnter.add_widget(lbl2)
stkEnter.add_widget(txtLoc)
stkEnter.add_widget(lbl3)
stkEnter.add_widget(txtSex)
stkEnter.add_widget(lbl4)
stkEnter.add_widget(txtType)
stkEnter.add_widget(btnAccept)

btnAccept.bind(on_press=self.on_button)
return stkEnter

def on_button(self,instance):
self.db.insert_cattledata(self.txtTag.text,self.txtLoc.text,self.txtSex.text,self.txtType.text)
self.txtTag.text=''
self.txtLoc.text=''
self.txtSex.text=''
self.txtType.text=''


class Bovine(Button):
def __init__ (self,tagNo,tagClr,tagYr,type,desc,loc,locDte,birthDte,birthWt,weanDte,weanWt,sex,status,aquired,
aquiredDte,aquiredCst,disposition,dispositionDte,soldAmt):
super(Bovine, self).__init__()
self.tagNo=tagNo
self.tagClr=tagClr
self.tagYr=tagYr
self.type=type
self.desc=desc
self.loc=loc
self.locDte=locDte
self.birthDte=birthDte
self.birthWt=birthWt
self.weanDte=weanDte
self.weanWt=weanWt
self.sex=sex
self.status=status
self.aquired=aquired
self.aquiredDte=aquiredDte
self.aquiredCst=aquiredCst
self.disposition=disposition
self.dispositionDte=dispositionDte
self.soldAmt=soldAmt

self.background_normal=''
self.bold=True

if self.type=='Cow' or self.type=='Bull':
self.size_hint=(.065,.065)
else:
self.size_hint=(.05,.05)

if self.sex=='F':
self.background_color=(1,.2,.6,1)
if self.sex=='M':
self.background_color=(0,.5,1,1)
if self.sex=='Str':
self.background_color=(0,0,.8,1)

if self.tagClr=='W':
self.color==(1,1,1,1)
if self.tagClr=='R':
self.color=(.7,0,0,1)
if self.tagClr=='Y':
self.color=(.8,.8,0,1)
if self.tagClr=='Blu':
self.color=(0,0,.8,1)
if self.tagClr=='Blk':
self.color=(0,0,0,1)
if self.tagClr=='G':
self.color=(0,.4,0,1)


class Cow(Bovine):
def __init__(self,tagNo,tagClr,tagYr,type,desc,loc,locDte,birthDte,birthWt,weanDte,weanWt,sex,status,aquired,
aquiredDte,aquiredCst,disposition,dispositionDte,soldAmt,bredByTag,bredByTagClr,bredByTagYr,bredByDes,
actCalvDte,calfTagNo,calfTagClr,calfTagYr):
super().__init__(tagNo,tagClr,tagYr,type,desc,loc,locDte,birthDte,birthWt,weanDte,weanWt,sex,status,aquired,
aquiredDte,aquiredCst,disposition,dispositionDte,soldAmt)
self.bredByTag=bredByTag
self.bredByTagClr=bredByTagClr
self.bredByTagYr=bredByTagYr
self.bredByDes=bredByDes
self.actCalvDte=actCalvDte
self.calfTagNo=calfTagNo
self.calfTagClr=calfTagClr
self.calfTagYr=calfTagYr

if calfTagNo != '':
self.text=str(self.tagNo)+'/'+str(self.calfTagNo)
else:
self.text=str(self.tagNo)

class Calf(Bovine):
def __init__(self,tagNo,tagClr,tagYr,type,desc,loc,locDte,birthDte,birthWt,weanDte,weanWt,sex,status,aquired,
aquiredDte,aquiredCst,disposition,dispositionDte,soldAmt,damTagNo,damTagClr,damTagYr,sireTagNo,sireTagClr,sireTagYr,
finishedWt,finishedDte,lbDayFeed):
super().__init__(tagNo,tagClr,tagYr,type,desc,loc,locDte,birthDte,birthWt,weanDte,weanWt,sex,status,aquired,
aquiredDte,aquiredCst,disposition,dispositionDte,soldAmt)
self.damTagNo=damTagNo
self.damTagClr=damTagClr
self.damTagYr=damTagYr
self.sireTagNo=sireTagNo
self.sireTagClr=sireTagClr
self.sireTagYr=sireTagYr
self.finishedWt=finishedWt
self.finishedDte=finishedDte
self.lbDayfeed=lbDayFeed
self.text=str(self.tagNo)

class Bull(Bovine):
def __init__(self,tagNo,tagClr,tagYr,type,desc,loc,locDte,birthDte,birthWt,weanDte,weanWt,sex,status,aquired,
aquiredDte,aquiredCst,disposition,dispositionDte,soldAmt,adg,yw,sc,ced,mm):
super().__init__(tagNo,tagClr,tagYr,type,desc,loc,locDte,birthDte,birthWt,weanDte,weanWt,sex,status,aquired,
aquiredDte,aquiredCst,disposition,dispositionDte,soldAmt)
self.adg=adg
self.yw=yw
self.sc=sc
self.ced=ced
self.mm=mm

self.text=str(self.tagNo)

class CreateApp(App):
def build(self):
my_db=MyDataBase('bovine.db')
my_db.connect()
myCow=Cow
myCalf=Calf
myBull=Bull
return MyApp(my_db,myCow,myCalf,myBull)

if __name__ == '__main__':
CreateApp().run()
bovine.db

Elliot Garbus

unread,
Nov 27, 2021, 11:01:20 AM11/27/21
to kivy-...@googlegroups.com

You have nested tab panels you need to be able to select each tab panel individually.  I have highlighted the changes in the code below.

I removed the reference to ids, and created a new dictionary for storing tabs.  I used self.tabs to hold the top level tabs, and edit_view_tabs to store the tahns under edit/view.   The instance variable self.myTPEV holds the editview tabbed panel.

 

        self.tabs = {}  # A dictionary to hold the top tabs
       
self.edit_view_tabs = {} # hold the edit/view tabs
       
self.myTPEV = None # holds edit view tabbed panel

The cowBtn_Press method needs to switch each panel to get to the desired position.

 

def cowBtn_Press(self, instance):
       
print(instance.text, instance.sex)
       
self.switch_to(self.tabs['E/V'])
       
self.myTPEV.switch_to(self.edit_view_tabs['cowE/V'])

A few additional observations: 

The coding conventions for python are listed here: https://pep8.org/

While these are for library writers, you will find them helpful and it will help others that are reading your code.  Take notice of the conventions for method names and variable names.

 

It appears that you are creating new widgets for every element in the database.  If the total number of entries is small this should not be an issue.  If there are 100’s of items in the database you may end up with a performance issue at startup.  At startup the creation of 100’s of tabs and widgets will take a surprisingly long time.  If this is the case, let me know I can suggest an alternative implementation.

 

I strongly suggest learning KV, it will remove lots of tedious code, and allow you to make changes to the layouts much quicker.

 

Edited code below:

 

 

"""
Select "location" tab and then "Hermas" child tab and then select a pink button(cow).
It should take you to the "Cow" child tab in the "View/Edit" tab. Interestingly it displays widgets
on the "Cow" header  with out the "Cow" tab as if it was part part of the "View/Edit" header.
"""


from sqlite3 import dbapi2
from typing import final
import kivy
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanelHeader
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
import sqlite3
from kivy.clock import Clock
from functools import partial

# con=sqlite3.connect('bovine.db');
# c=con.cursor();
# c.execute(""" CREATE TABLE cattleData

#           (tagNo integer,
#            Loc text,
#            sex text,
#            type text)
#           """)
# c.execute(""" CREATE TABLE locations

#           (locName text)
#           """);


opList = ["Location", "Add", "Edit/View"]


.myCow = myCow
       
self.tabs = {}  # A dictionary to hold the top tabs
       
self.edit_view_tabs = {} # hold the edit/view tabs
       
self.myTPEV = None # holds edit view tabbed panel

       
for i in opList:  # add headers for Location, Add, Edit/View
           
myTPHM = TabbedPanelHeader()
            myTPHM.text =
str(i)
           
self.add_widget(myTPHM)

           
if str(i) == 'Edit/View'# add new tabbed panel with headers for Cow,Calf,Bull
                
self.tabs['E/V'] = myTPHM
               
self.myTPEV = TabbedPanel()
               
self.myTPEV.do_default_tab = False
               
myTPHM.content = self.myTPEV

                cowTPHEV = TabbedPanelHeader()
               
self.edit_view_tabs['cowE/V'] = cowTPHEV
                cowTPHEV.text =
'Cow'
               
self.myTPEV.add_widget(cowTPHEV)
                cowTPHEV.content =
self.ev_cowScreen()

                calfTPHEV = TabbedPanelHeader()
                calfTPHEV.text =
'Calf'
                
self.myTPEV.add_widget(calfTPHEV)
                calfStkLoc = StackLayout(
orientation='tb-lr', spacing=4)
                calfTPHEV.content = calfStkLoc

                bullTPHEV = TabbedPanelHeader()
               
self.myTPEV.add_widget(bullTPHEV)
                bullTPHEV.text =
'Bull'
               
bullStkLoc = StackLayout(orientation='tb-lr', spacing=4)
                bullTPHEV.content = bullStkLoc

           
if str(i) == 'Location'# add new tabbed panel with headers for all locations
               
myTPLoc = TabbedPanel()
                myTPLoc.do_default_tab =
False
               
myTPHM.content = myTPLoc
               
for row in self.db.locationList():
                    location = row[
0]
orientation='tb-lr', spacing=4)
                    myTPHL.content = stkLoc

                    
### add animals to loc tab
                   
for cows in self.db.cowsBy_Loc(location):
                        tagNo = cows[
0]
                        tagClr = cows[
1]
                        tagYr = cows[
2]
                        type = cows[
3]
                        desc = cows[
4]
                        loc = cows[
5]
                        locDte = cows[
6]
                        birthDte = cows[
7]
                        birthWt = cows[
8]
                        weanDte = cows[
9]
                        weanWt = cows[
10]
                        sex = cows[
11]
                        status = cows[
12]
                        aquired = cows[
13]
                        aquiredDte = cows[
14]
                        disposition = cows[
15]
                        dispDte = cows[
16]
                        aquiredCst = cows[
17]
                        soldAmt = cows[
18]
                        bredByTag = cows[
19]
                        bredByTagClr = cows[
20]
                        bredByTagYr = cows[
21]
                        bredByDes = cows[
22]
                        actCalveDte = cows[
23]
                        calfTagNo = cows[
24]
                        calfTagClr = cows[
25]
                        calfTagYr = cows[
26]
on_press=self.cowBtn_Press)
                        stkLoc.add_widget(Cow)

                    
for calves in self.db.calvesBy_Loc(location):
                        tagNo = calves[
0]
                        tagClr = calves[
1]
                        tagYr = calves[
2]
                        type = calves[
3]
                        desc = calves[
4]
                        loc = calves[
5]
                        locDte = calves[
6]
                        birthDte = calves[
7]
                        birthWt = calves[
8]
                        weanDte = calves[
9]
                        weanWt = calves[
10]
                        sex = calves[
11]
                        status = calves[
12]
                        aquired = calves[
13]
                        aquiredDte = calves[
14]
                        disposition = calves[
16]
                        dispDte = calves[
17]
                        aquiredCst = calves[
15]
                        soldAmt = calves[
18]
                        damTagNo = calves[
19]
                        damTagClr = calves[
20]
                        damTagYr = calves[
21]
                        sireTagNo = calves[
22]
                        sireTagClr = calves[
23]
                        sireTagYr = calves[
24]
                        finishedWt = calves[
25]
                        finishedDte = calves[
26]
                        lbDayFeed = calves[
27]
on_press=self.cowBtn_Press)

                        stkLoc.add_widget(Calf)

                   
for bulls in self.db.bullsBy_Loc(location):
                        tagNo = bulls[
0]
                        tagClr = bulls[
1]
                        tagYr = bulls[
2]
                        type = bulls[
3]
                        desc = bulls[
4]
                        loc = bulls[
5]
                        locDte = bulls[
6]
                        birthDte = bulls[
7]
                        birthWt = bulls[
8]
                        weanDte = bulls[
9]
                        weanWt = bulls[
10]
                        sex = bulls[
11]
                        status = bulls[
12]
                        aquired = bulls[
13]
                        aquiredDte = bulls[
14]
                        disposition = bulls[
15]
                        dispDte = bulls[
16]
                        aquiredCst = bulls[
17]
                        soldAmt = bulls[
18]
                        adg = bulls[
19]
                        yw = bulls[
20]
                        sc = bulls[
21]
                        ced = bulls[
22]
                        mm = bulls[
23]
on_press=self.cowBtn_Press)
                        stkLoc.add_widget(Bull)

            
if str(i) == 'Add':
                myTPHM.content =
self.addScreen()

           
# if str(i)=='Edit/View':

            #    pass

   
def cowBtn_Press(self, instance):
       
print(instance.text, instance.sex)
       
self.switch_to(self.tabs['E/V'])
       
self.myTPEV.switch_to(self.edit_view_tabs['cowE/V'])

   
def ev_cowScreen(self):
        stkEnter = StackLayout(
orientation='tb-lr', spacing=5)
        lbl1 = Label(
text='Tag No', size_hint=(.15, .05))
        txtTag = TextInput(
text='', size_hint=(.15, .07))
        lbl2 = Label(
text='Tag Color', size_hint=(.15, .05))
        txtTagClr = TextInput(
text='', size_hint=(.15, .07))
        lbl3 = Label(
text='Tag Yr', size_hint=(.15, .05))
        txtTagYr = TextInput(
text='', size_hint=(.15, .07))
        lbl4 = Label(
text='Type', size_hint=(.15, .05))
        txtType = TextInput(
text='', size_hint=(.15, .07))
        lbl5 = Label(
text='Description', size_hint=(.15, .05))
        txtDes = TextInput(
text='', size_hint=(.15, .07))
        lbl6 = Label(
text='Current Location', size_hint=(.15, .05))
        txtLoc = TextInput(
text='', size_hint=(.15, .07))
        lbl7 = Label(
text='Location Date', size_hint=(.15, .05))
        txtLocDte = TextInput(
text='', size_hint=(.15, .07))
        lbl8 = Label(
text='Birth Date', size_hint=(.15, .05))
        txtBD = TextInput(
text='', size_hint=(.15, .07))
        lbl9 = Label(
text='Birth Wt', size_hint=(.15, .05))
        txtBWt = TextInput(
text='', size_hint=(.15, .07))
        lbl10 = Label(
text='Wean Date', size_hint=(.15, .05))
        txtWeanDte = TextInput(
text='', size_hint=(.15, .07))
       
lbl11 = Label(text='Wean Wt', size_hint=(.15, .05))
        txtWeanWt = TextInput(
text='', size_hint=(.15, .07))
        lbl11 = Label(
text='Sex', size_hint=(.15, .05))
       
txtSex = TextInput(text='', size_hint=(.15, .07))
        lbl12 = Label(
text='Status', size_hint=(.15, .05))
        txtStatus = TextInput(
text='', size_hint=(.15, .07))
        lbl13 = Label(
text='Aquired', size_hint=(.15, .05))
        txtAquired = TextInput(
text='', size_hint=(.15, .07))
        lbl14 = Label(
text='Aquired Date', size_hint=(.15, .05))
        txtAquiredDte = TextInput(
text='', size_hint=(.15, .07))
        lbl15 = Label(
text='Aquired cost', size_hint=(.15, .05))
        txtAquiredCst = TextInput(
text='', size_hint=(.15, .07))
        lbl16 = Label(
text='Disposition', size_hint=(.15, .05))
        txtDispo = TextInput(
text='', size_hint=(.15, .07))
        lbl17 = Label(
text='Disp Date', size_hint=(.15, .05))
       txtDispDte = TextInput(
text='', size_hint=(.15, .07))
        lbl18 = Label(
text='Sold Amt', size_hint=(.15, .05))
        txtSold = TextInput(
text='', size_hint=(.15, .07))
        lbl19 = Label(
text='Bred date', size_hint=(.15, .05))
        txtBredDte = TextInput(
text='', size_hint=(.15, .07))
        lbl24 = Label(
text='Est Calving Date', size_hint=(.15, .05))
        txtEstClvDte = TextInput(
text='', size_hint=(.15, .07))
        lbl20 = Label(
text='Bred By TagNo', size_hint=(.15, .05))
        txtBullTagNo = TextInput(
text='', size_hint=(.15, .07))
        lbl21 = Label(
text='Bred By Tag Color', size_hint=(.15, .05))
        txtBullTagClr = TextInput(
text='', size_hint=(.15, .07))
        lbl22 = Label(
text='Bred By Tag Yr', size_hint=(.15, .05))
        txtBullTagYr = TextInput(
text='', size_hint=(.15, .07))
        lbl23 = Label(
text='Actual Calving Date ', size_hint=(.15, .05))
        txtActClvDte = TextInput(
text='', size_hint=(.15, .07))
        lbl25 = Label(
text='Calf TagNo', size_hint=(.15, .05))
        txtCalfTagNo = TextInput(
text='', size_hint=(.15, .07))
        lbl26 = Label(
text='Calf Tag Color', size_hint=(.15, .05))
        txtCalfTagClr = TextInput(
text='', size_hint=(.15, .07))
        lbl27 = Label(
text='Calf Tag Yr', size_hint=(.15, .05))
        txtCalfTagYr = TextInput(
text='', size_hint=(.15, .07))

        btnAccept = Button(
text='Add', size_hint=(.1, .05))
return stkEnter

   
def addScreen(self):
        stkEnter = StackLayout(
orientation='lr-tb', spacing=4)
        lbl1 = Label(
text='Tag No', size_hint=(.1, .04))
        lbl2 = Label(
text='Location', size_hint=(.1, .04))
        lbl3 = Label(
text='Sex', size_hint=(.1, .04))
        lbl4 = Label(
text='type', size_hint=(.1, .04))
        txtTag = TextInput(
text='', size_hint=(.1, .06))
        txtLoc = TextInput(
text='', size_hint=(.1, .06))
        txtSex = TextInput(
text='', size_hint=(.1, .06))
        txtType = TextInput(
text='', size_hint=(.1, .06))
        btnAccept = Button(
text='add', size_hint=(.1, .04))
on_press=self.on_button)
       
return stkEnter

   
def on_button(self, instance):
       
self.db.insert_cattledata(self.txtTag.text, self.txtLoc.text, self.txtSex.text, self.txtType.text)
       
self.txtTag.text = ''
       
self.txtLoc.text = ''
       
self.txtSex.text = ''
       
self.txtType.text = ''


markR

unread,
Nov 27, 2021, 10:39:01 PM11/27/21
to Kivy users support
Thanks for taking the time to go into a lot of detail with the problem I could not get around. I have not processed all yet. Just  for clarification, it appears that programmatically you have to "switch_to"  the same tabs in order as you would manually? I see what you are doing by storing a reference to the headers in a dictionary for each. Should not the ids route have done the same thing ? I think I  understand why a myTPEV placeholder name was created at the Class Level (i do not know if i said that correctly)- in order to access in the cowBtn_Press method?
To your comment on the number of widgets (cows); there could be 50-a couple thousand(ranchers out west). I would be interested even though it may be beyond my level currently.
Also concerning learning KV; thanks for the suggestion. I saw some tutorials I will try to dabble in. Is there anything I  am going to miss by not learning how to do it in python first?

Elliot Garbus

unread,
Nov 28, 2021, 8:59:56 AM11/28/21
to kivy-...@googlegroups.com

Just  for clarification, it appears that programmatically you have to "switch_to"  the same tabs in order as you would manually?

In short yes.  You have 2 TabbedPanels, one nested below the other.  You need to select both the upper tab and the lower tan to display to content you want.

 

I see what you are doing by storing a reference to the headers in a dictionary for each. Should not the ids route have done the same thing? 

The ids dictionary is populated by kv when processing the id tags in the kv language file.  It is not a dictionary for random use.  You can create your own dictionary and effectively use the same concept – a place to store widgets.

Here ore some references on the use of id and ids.

https://kivy.org/doc/master/guide/lang.html?highlight=kvlang#referencing-widgets

https://kivy.org/doc/master/api-kivy.uix.widget.html?highlight=widget#kivy.uix.widget.Widget.ids

 

I think I  understand why a myTPEV placeholder name was created at the Class Level (i do not know if i said that correctly)- in order to access in the cowBtn_Press method?

Correct.  I converted the local variable myTPEV to an instance variable self.myTPEV to it could be accessed in cowBtn_Press.

 

If you have the possibility of running a few thousand cows, you want to change your approach.  In the current approach you are creating about 50 widgets for each cow at startup.  This will take quite a lot of time with a few thousand cows.  You can create the same visual effect, by getting rid of the tabbed panel, using a set of Toggle buttons to select a cow (as you do with tabs now) but instead of populating all of the widgets at once.  Have one set of widgets and populate it with the selected cow.

 

Also concerning learning KV; thanks for the suggestion… I  am going to miss by not learning how to do it in python first?

KV brings a number of benefits.  It removes a lot of tedious coding.  You will want to learn how the kivy properties work with KV and how id/ids work.

 

Enjoy the journey.

markR

unread,
Nov 28, 2021, 9:50:26 AM11/28/21
to Kivy users support
Thank you.
In reference to creating numerous widgets, I think what you are saying is not to create all the cow objects at the beginning but only as needed for detail. Is there something besides a button that is lighter weight that takes a click event and stores text with it so i could run my database query when selected? if not i could always have a text_input to manually chink the number in but that seems like double work and clunky. Also another objective was to use multi select to transfer animals from one location to another.
Additional thoughts?

Elliot Garbus

unread,
Nov 28, 2021, 10:18:49 AM11/28/21
to kivy-...@googlegroups.com

A button is light weight.  If you are going to have lots of buttons, you can put them in a RecycleView.  The Recycleview is an efficient scrollable list.

 

My key point is when you use tabs, you put all of the content on each tab.  If you are going to have lots of tabs each with the same set of widgets, you will run into a startup time problem.  Have one way to display the data.  One set of widgets capable of displaying any cow.  Do not replicate the widgets for each cow.

markR

unread,
Nov 28, 2021, 5:58:45 PM11/28/21
to Kivy users support
Again, Thanks. I will study up on RecycleView
Reply all
Reply to author
Forward
0 new messages