Search code examples
datatablekivypopup

how to send data or change label in popup window in kivy


I have tried many posts here in relation to my problem but nothing works for me. I am sure that i am not good enough to understand them.

I want to basically send a datatable to the popup window. I made the same program with ttk.treeview. this ttk.treeview showed me a good table. but now i want to upgrade it with kivy. hence i chose datatable. i could not find any other option to show a nice looking data table like ttk.treeview. Do you have any suggestion besides datatable?

When you run this python file, you will see popup screen. you click "Dex", then it opens a popup window. You put any data there then Click "Calculate", then i want to show the result of the calculation of those inputs into the bottom button space of this window.

I put a dummy datatable in the calculate(self) function.

Would you help me with this? My problem line is python file line 77.

Tons of thanks in advance.

Python File:

'''

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
#from kivy.uix.screenmanager import ScreenManger, Screen
'''Setting the size of first window for program'''
from kivy.config import Config                 #another way of setting size of window
Config.set('graphics', 'width', '600')         # from kivy.core.window import Window
Config.set('graphics', 'height', '750')        # Window.size = ("300dp", "100dp")

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.uix.screenmanager import ScreenManager
from kivy.properties import ObjectProperty
from kaki.app import App
from kivy.factory import Factory
import os

from kivymd.uix.datatables import MDDataTable

from kivy.uix.popup import Popup
from kivy.graphics import Rectangle, Color
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.metrics import dp


Builder.load_file('new_window_mo.kv')

class Dex(Popup):

    ptName = ObjectProperty(None)
    ptAdminWeight = ObjectProperty(None)
    ptIdealWeight = ObjectProperty(None)


    def on_open(self):
        
        #print("on_Open event")
        self.ptName.focus = True
        self.data_tables = None
    # def calculate(self):
    #     print(self.root.ids.data_scr.ids.data_layout.add_widget)

    def calculate(self):
        ptName = self.ptName.text
        ptAdminWeight = self.ptAdminWeight.text
        ptIdealWeight = self.ptIdealWeight.text

        #print("before calculate")
        #calculate(self, ptName, ptAdminWeight, ptIdealWeight)
        # print(f'calculate {ptName}')
        # print(f'calculate {ptAdminWeight}')
        # print(f'calculate {ptIdealWeight}')
        self.data_tables = MDDataTable(
            size_hint=(0.9, 0.8),
            column_data=[
                ("No.", dp(30)),
                ("User", dp(30)),
                ("Password", dp(30)),
            ],
            row_data=[
                (
                    "1",
                    "The pitonist",
                    "Strong password",
                ),
                (
                    "2",
                    "The c++ lover",
                    "Save me!!!:)",
                ),
            ]
        )
        #self.root.ids.data_scr.ids.data_layout.add_widget(self.data_tables)
        self.root.ids.dexme.ids.data_layout.add_widget(self.data_tables)

    def print(self):
        ptName = self.ptName.text
        ptAdminWeight = self.ptAdminWeight.text
        ptIdealWeight = self.ptIdealWeight.text

        printme(self, ptName, ptAdminWeight, ptIdealWeight)

    def clear(self):
        self.ptName.text =""
        self.ptAdminWeight.text =""
        self.ptIdealWeight.text = ""
    

    
class Remi(Popup):
    def build(self):
        
        return self.root

class test1(Popup):
    def build(self):
        
        return self.root

class MyLayout(Widget):
    pass
class AwesomeApp(App):
    def build(self):
        return MyLayout()

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

'''

Kv file

'''

#:import Factory kivy.factory.Factory

<Dex>:
    id: dexme
    ptName : ptName
    ptAdminWeight : ptAdminWeight
    ptIdealWeight : ptIdealWeight


    auto_dismiss: False
    size_hint: 1, 1
    #pos_hint: {"x":0.2, "top":0.9}

    title: "Dex - Weight-Based"   

    canvas.before:
        Color:
            rgba: (1,0,0,1)
        Rectangle:
            pos:self.pos
            size:self.size
        
    # BoxLayout:
    #     orientation: "vertical"
    #     size: root.width, root.height
    #     size_hint: [1, 1]
    
    MDGridLayout:  #전체 블록 1칼럼 4row

        adaptive_height: True
        md_bg_color: app.theme_cls.primary_color
        md_bd_color: app.theme_cls.accent_palette
        cols: 1
        rows: 4
        size: root.width, root.height
        size_hint:1,1

        MDBoxLayout:   #첫 번째 약 이름
            adaptive_height: True
            md_bg_color: app.theme_cls.primary_color
            size_hint: 1, .4
            orientation: "vertical"
            padding: dp(0), dp(30), dp(0), dp(10)
            spacing: dp(20)
            #MDLabel:    #empty row
            #    text:""
            #    halign: "center"
            #    font_size: self.width/50
            MDLabel:
                text:"Dex"
                halign: "center"
                #font_size: self.width/15
                #font_size: self.width * .07
                font_size: '45sp'
            MDLabel:
                text:"Pre"
                halign: "center"
                font_size: '30sp'
        #환자이름,몸무게 정보 넣기
        MDGridLayout:
            rows: 3
            adaptive_height: True
            size_hint:1, None
            height: self.minimum_height
            #spacing: dp(15)
            padding: dp(50), dp(10), dp(50), dp(20)

    #                canvas:
    #                    Color:
    #                        rgba: [.2,.24,.5,.6]  #형광색
    #                    Rectangle:
    #                        pos:self.pos
    #                        size:self.size

            MDTextField:
                id: ptName
                #input_filter: "str"
                hint_text: "Patient Name"
                line_color_focus: 0,0,0,1
                font_size: '30sp'
                focus: True
                write_tab: False
                #on_press: print("pressed name text field")
                #font_color: 1,0,1,1
                #required: True
                #mode: "rectangle"
                #font_size: self.width * .07

                
            MDTextField:
                id:ptAdminWeight
                input_filter: "float"
                hint_text: "Admission Weight"
                required: True
                font_size: '30sp'
                line_color_focus: 0.9,0.75,0,1
                write_tab: False
                #focus: True
            MDTextField:
                id:ptIdealWeight
                input_filter: "float"
                hint_text: "Idea Weight"
                required: True
                font_size: '30sp'
                line_color_focus: 0.9,0.75,0,1
                write_tab: False
        MDGridLayout:    #buttons
            cols: 4
            rows: 1
    #                canvas:
    #                    Color:
    #                        rgba: [.1,1,.1,.6]  #형광색
    #                    Rectangle:
    #                        pos:self.pos
    #                        size:self.size

            size_hint: 1, .25
            pos_hint: 1, None
            pos_hint: {'center_y':0.5}

            padding: "20dp", "0dp", "20dp", "15dp"
            spacing: "20dp"

    #on_press: root.press()
    #on_release: root.dismiss()

            MDRoundFlatIconButton:
                text: "Calculate"
                icon: "calculator"
                pos_hint: {"center_y": .5}
                font_size: '20sp'
                size_hint: .3, 1
                #theme_text_color: "Custom"
                text_color: 1,1,1,1
                icon_color: 1,1,1,1
                line_color: 1,1,1,1
                line_width: 2
                on_release: root.calculate()
                write_tab: False

            MDRoundFlatIconButton:
                text: "Print"
                icon: "printer"
                pos_hint: {"center_y": .5}
                font_size: '20sp'
                size_hint: .3, 1
                #theme_text_color: "Custom"
                text_color: 1,1,1,1
                icon_color: 1,1,1,1
                line_color: 1,1,1,1
                line_width: 2
                write_tab: False
                on_release: root.print()

            MDRoundFlatIconButton:
                text: "New"
                icon: "close-thick"
                font_size: '20sp'
                size_hint: .3, 1
                pos_hint: {'center_y': 0.5}
                text_color: 1,1,1,1
                icon_color: 1,1,1,1
                line_color: 1,1,1,1
                line_width: 2
                on_release: root.clear()
                # write_tab: True
                # focus_next: True
            # MDRoundFlatIconButton:
            #     text: "Close"
            #     icon: "close-thick"
            #     font_size: '20sp'
            #     size_hint: .3, 1
            #     pos_hint: {'center_y': 0.5}
            #     text_color: 1,1,1,1
            #     icon_color: 1,1,1,1
            #     line_color: 1,1,1,1
            #     line_width: 2
            #     on_release: root.close()

        # treeview data display
        BoxLayout:
            canvas:
                Color:
                    rgba: [1,1,.1,.6]
                Rectangle:
                    pos:self.pos
                    size:self.size
            Button:
                id: data_layout
                text: "i want to show data here when Calculate clicked"
                pos_hint: {"bottom": .2}
                size_hint: .8,.4

<Remi>:
    auto_dismiss: False
    size_hint: 1, 1
    #pos_hint: {"x":0.2, "top":0.9}

    title: "Remi Weight-Based "   
    canvas.before:
        Color:
            rgba: (0,1,0,1)
        Rectangle:
            pos:self.pos
            size:self.size
    
    BoxLayout:
        
        orientation: "vertical"
        size:root.width, root.height

        Label:
            text: "label 1" 
        Button:
            text: "Close"
            font_size: 24
            on_release: root.dismiss()
<MyLayout>
    BoxLayout:
        orientation:"vertical"
        size: root.width, root.height

        Button:
            id: data_scr
            text: "Dex"
            font_size: 32
            on_press: Factory.Dex().open()
        Button:
            text: "Remi"
            font_size: 32
            on_press: Factory.Remi().open()

'''


Solution

  • In order to get your code to run, I needed to change:

    class AwesomeApp(App):
    

    to

    class AwesomeApp(MDApp):
    

    Then, in your kv file, change the last part of the <Dex> rule from

        BoxLayout:
            canvas:
                Color:
                    rgba: [1,1,.1,.6]
                Rectangle:
                    pos:self.pos
                    size:self.size
            Button:
                id: data_layout
                text: "i want to show data here when Calculate clicked"
                pos_hint: {"bottom": .2}
                size_hint: .8,.4
    

    to

        BoxLayout:
            id: data_layout
            canvas:
                Color:
                    rgba: [1,1,.1,.6]
                Rectangle:
                    pos:self.pos
                    size:self.size
    

    And then a small change to the calculate() method, by changing:

    self.root.ids.dexme.ids.data_layout.add_widget(self.data_tables)
    

    to:

    self.ids.data_layout.add_widget(self.data_tables)
    

    Since the calculate() method is in the Dex class, you don't need to use ids to get to the Dex instance, just use self instead.