Python/Kivy : Call function from one class to anot

2019-03-17 10:10发布

问题:

I am using Python-2.7 and Kivy. When I run test.py then a show button shows. When I click on the show button then a label and value shows. I am fetching it from the database but now I defined it as a static array.

When I click on Item1 label then call def open_form and pass id 11 after calling EditPopup(self) with id and show a popup with value.

After that I change itemCode and click on the ok button then it updates data in the database.

After that I call Invoice().abc() then it prints the updated data in Pycharm console but not showing latest the data in layout.add_widget(Popup window).

Can someone tell me where am I making a mistake?

test.py

from kivy.uix.label import Label
from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.core.window import Window
from functools import partial
from kivy.uix.popup import Popup
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty, NumericProperty
import sqlite3 as lite
#con = lite.connect('test.db')

#con.text_factory = str
#cur = con.cursor()
Window.clearcolor = (0.5, 0.5, 0.5, 1)
Window.size = (600, 600)

class MyLabel(Label):
    pass


class EditPopup(Popup):
    mode = StringProperty("")
    label_rec_id = StringProperty("Id")
    col_data = ListProperty(["?", "?", "?"])
    index = NumericProperty(0)

    def __init__(self, obj, **kwargs):
        super(EditPopup, self).__init__(**kwargs)

        if obj.mode == "Update":
            #cur.execute("SELECT * FROM `item` WHERE itemId=?", (edit_id,))
            #row = cur.fetchone()
            row = (11, 'Item1', '1001')
            print(row[0])
            self.col_data[0] = str(row[0])
            self.col_data[1] = row[1]
            self.col_data[2] = row[2]

    def update(self,obj):
        #cur.execute("UPDATE `item` SET itemName=?, itemCode=? WHERE itemId=?",
                #('Item1', 9999, 11))
        #con.commit()
        Invoice().abc()

class Invoice(Screen):
    def __init__(self, **kwargs):
        super(Invoice, self).__init__(**kwargs)

    def abc(self):
        #fetching from database
        #cur.execute("SELECT * FROM `item` order by itemId asc")
        #rows = cur.fetchall()
        rows = [(11, 'Item1', '1001'), (12, 'Item2', '2001'), (13, 'Item3', '102')]
        print(rows)
        layout = self.ids['invoices']
        for row in rows:
            layout.add_widget(MyLabel(text=str('[ref=world]' + row[1]) + '[/ref]',
                                      size_hint_x=.35,
                                      halign='left',
                                      markup=True,
                                      on_ref_press=partial(self.open_form, row[0])))

    def open_form(self, id, *args):
        global edit_id
        edit_id = id
        self.mode = "Update"
        popup = EditPopup(self)
        popup.open()

class Test(App):

    def build(self):
        return Invoice()

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

test.kv

<Button@Button>:
    font_size: 15
    font_name: 'Verdana'
    size_hint_y:None
    height: 30

<MyLabel>:
    font_size: 15
    font_name: 'Verdana'
    size_hint_y:None
    height: 30
    text_size: self.size
    valign: 'middle'
    canvas.before:
        Color:
            rgb: .6, .6, .6
        Rectangle:
            pos: self.pos
            size: self.size

<EditPopup>:
    title: self.mode + " Item"
    size_hint: None, None
    title_size: 20
    title_font: "Verdana"
    size: 400, 275
    auto_dismiss: False

    BoxLayout:
        orientation: "vertical"
        GridLayout:
            cols: 2
            #backgroun_color: 0, 0.517, 0.705, 1
            spacing: 10, 10
            padding: 20, 20
            Label:
                text: root.label_rec_id
                text_size: self.size
            Label:
                id: itemId
                text: root.col_data[0]
                text_size: self.size
            Label:
                text: "Item Name"
                text_size: self.size
                valign: 'middle'
            TextInput:
                id: itemName
                text: root.col_data[1]
                text_size: self.size
            Label:
                text: "State Code"
                text_size: self.size
                valign: 'middle'
            TextInput:
                id: itemCode
                text: root.col_data[2]
                text_size: self.size

        GridLayout:
            cols: 2
            padding: 10, 0, 10, 10
            spacing: 10, 10
            row_default_height: '20dp'
            size_hint: .55, .3
            pos_hint: {'x': .25, 'y':.65}

            Button:
                size_hint_x: .5
                text: "Ok"
                on_release:
                    root.update(root)
                    root.dismiss()

            Button:
                size_hint_x: .5
                text: "Cancel"
                on_release: root.dismiss()



<Invoice>:
    BoxLayout:
        orientation: "vertical"
        padding : 15, 15

        BoxLayout:
            orientation: "vertical"
            padding : 5, 5
            size_hint: .6, None
            pos_hint: {'x': .18,}


            BoxLayout:
                orientation: "horizontal"
                padding : 5, 5
                spacing: 10, 10
                size: 800, 40
                size_hint: 1, None

                Button:
                    text: "Show"
                    size_hint_x: .05
                    spacing_x: 30
                    on_press:root.abc()

        BoxLayout:
            orientation: "horizontal"
            size_hint: 1, 1

            BoxLayout:
                orientation: "vertical"
                size_hint: .5, 1
                padding : 0, 15
                spacing: 10, 10
                size: 500, 30

                GridLayout:
                    id: invoices
                    cols: 2
                    #orientation: "horizontal"
                    padding : 5, 0
                    spacing: 10, 0
                    #size: 500, 30
                    size_hint: 1, 1
                    pos: self.pos
                    size: self.size

回答1:

You are creating a new Invoice instance instead of using the existing one.

 Invoice().abc()

try instead:

class EditPopup(Popup):
    mode = StringProperty("")
    label_rec_id = StringProperty("Id")
    col_data = ListProperty(["?", "?", "?"])
    index = NumericProperty(0)

    def __init__(self, obj, **kwargs):
        super(EditPopup, self).__init__(**kwargs)
        self.obj = obj # will need it later...

    def update(self,obj):
        #cur.execute("UPDATE `item` SET itemName=?, itemCode=? WHERE itemId=?",
                #('Item1', 9999, 11))
        #con.commit()

        self.obj.abc()  # was Invoice().abc()


回答2:

Problem

You are instanting a second instance of class Invoice by invoking Invoice().abc() at method update in class EditPopup.

Solution

1) test.py

Comment off Invoice().abc() at method update in class EditPopup and add pass.

def update(self, obj):
    #cur.execute("UPDATE `item` SET itemName=?, itemCode=? WHERE itemId=?",
            #('Item1', 9999, 11))
    #con.commit()
    # Invoice().abc()
    pass

2) test.kv

Add a call to method abc in class EditPopup after call to method update.

    Button:
        size_hint_x: .5
        text: "Ok"
        on_release:
            root.update(root)
            app.root.abc()
            root.dismiss()

Output