简体   繁体   中英

Python-Kivy AttributeError: 'NoneType' object has no attribute 'text'

I am just getting into coding, so there are probably quite a few coding errors here. I am trying to develop an app that will help with my personal billing. I want this app to first display the text box entry for the invoice# and for(purpose) then proceed to a scrolling page where all the carrier names will be displayed for the user to pick, then the next page (with a similar layout as the first to have a text box for the cost, and a drop-down for local (lists of city names), outcal (same list of city names), Driver (list of driver names), Dispatcher (list of dispatcher names).

In the end, I want all of this information to be stored on a text document so that I could design code to interpret and place it in specified parts of an excel file. Is all this possible in Kivy Exel?

The app opens and we can enter text on the first first screen but crashes as soon as the next button is clicked. Here is the code and error codes.

Error code for database:

{
    "resource": "/c:/Users/CJ/Desktop/my app/screens/exel.py",
    "owner": "python",
    "code": "undefined-variable",
    "severity": 8,
    "message": "Undefined variable 'invoice'",
    "source": "pylint",
    "startLineNumber": 33,
    "startColumn": 56,
    "endLineNumber": 33,
    "endColumn": 56
}

Error code for main.py

{
    "resource": "/c:/Users/CJ/Desktop/my app/screens/Screens.py",
    "owner": "python",
    "code": "no-name-in-module",
    "severity": 8,
    "message": "No name 'ObjectProperty' in module 'kivy.properties'",
    "source": "pylint",
    "startLineNumber": 6,
    "startColumn": 1,
    "endLineNumber": 6,
    "endColumn": 1
}

I got this no value error for the rest of the names I haven't integrated yet:

No value for argument 'carrier' in method call
No value for argument 'carrier' in method call

Code:

# main.py
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivymd.uix.list import MDList,OneLineListItem
from kivy.uix.scrollview import ScrollView
from exel import DataBase

class TOPRIGHTINVOICE(Screen):
    invoice = ObjectProperty(None)
    For = ObjectProperty(None)

    def next(self):
        db.add_loadinfo(self.invoice.text, self.For.text)

        self.reset()
        sm.current = "CARRIERPAGE"
    
    def reset(self):
        self.invoice.text = "" 
        self.For.text = ""

    def login(self):
        self.reset()
        sm.current = "CARRIERPAGE"


class CARRIERPAGE(Screen):

    def build(self):
        screen = Screen()

        scroll = ScrollView()
        list_view= MDList()
        scroll.add_widget(list_view)

        item1 = OneLineListItem(text='Coyote')
        item2 = OneLineListItem(text='TQL')

        list_view.add_widget(item1)
        list_view.add_widget(item2)

        screen.add_widget(list_view)
     


def MissingInfo():
    pop = Popup(title= 'Missing Information',
                content=Label(text='You are missing information, are you sure you want to continue?'),
                suze_hint=(None,None), size=(400,400))
    pop.open()

class WindowManager(ScreenManager):
    pass

kv = Builder.load_file("my.kv")

sm = WindowManager()
db = DataBase("user.txt")

screens = [TOPRIGHTINVOICE(name="main"), CARRIERPAGE(name="CARRIERPAGE")]
for screen in screens:
    sm.add_widget(screen)

sm.current = "main"

class MyScreen(App):
    def build(self):
        return sm

if __name__ == "__main__":
    MyScreen().run()


#my.kv
<TOPRIGHTINVOICE>:
    name: "main"

    invoice: invoice
    purpose: purpose
        

    FloatLayout:
        cols:1

        FloatLayout:
            size: root.width, root.height/2


            Label:
                size_hint: 0.5,0.12
                pos_hint: {"x":0, "top":0.8}
                text: "Invoice #: "
                font_size: dp(20)

            TextInput:
                pos_hint: {"x":0.5, "top":0.8}
                size_hint: 0.4, 0.12
                id: invoice
                multiline: False
                font_size: dp(20)

            Label:
                size_hint: 0.5,0.12
                pos_hint: {"x":0, "top":0.8-0.13}
                text: "For: "
                font_size: dp(20)

            TextInput:
                pos_hint: {"x":0.5, "top":0.8-0.13}
                size_hint: 0.4, 0.12
                id: purpose
                multiline: False
                font_size: dp(20)

        Button:
            pos_hint:{"x":0.3,"y":0.25}
            size_hint: 0.4, 0.1
            font_size: dp(20)
            text: "Next"
            on_release:
                root.manager.transition.direction = "left"
                root.next()


            
            



<CARRIERPAGE>:
    name: "CARRIERPAGE"
    
    Button:
        id:Back
        text: "Back"
        on_release: 
            app.root.current = "main"
            root.manager.transition.direction = "right"
#exel database
import xlrd, xlwt
from xlutils.copy import copy
import datetime

class DataBase:
    def __init__(self, filename):
        self.filename = filename
        self.loadinfo = None
        self.file = None
        self.load()

    def load(self):
        self.file = open(self.filename, "r")
        self.loadinfo = {}

        for line in self.file:
            invoice, purpose, carrier, cost, local, outcal, Driver, Dispatcher = line.strip().split(";")
            self.loadinfo[invoice] = (invoice, purpose, carrier, cost, local, outcal, Driver, Dispatcher)

        self.file.close()

    def top_right(self, invoice, purpose):
        pass

    def add_loadinfo(self, invoice, purpose, carrier, cost, local, outcal, Driver, Dispatcher):
        self.loadinfo[invoice.strip()] = (invoice.strip(), purpose.strip(), carrier.strip(), cost.strip(), local.strip(), outcal.strip(), Driver.strip(), Dispatcher.strip(), DataBase.get_date())
        self.save()

    
    def save(self):
        with open(self.filename, "w") as f:
            for loadinfo in self.loadinfo:
                f.write(loadinfo + ";" + self.loadinfo[invoice][0] + ";" + self.loadinfo[invoice][1] + ";" + self.loadinfo[invoice][2] + "\n")

    @staticmethod
    def get_date():
        return str(datetime.datetime.now()).split(" ")[0]
        

#code to put it into excel

# read_book = xlrd.open_workbook("Invoice.xls", formatting_info=True) #Make Readable Copy
# write_book = copy(read_book) #Make Writeable Copy

# write_sheet1 = write_book.get_sheet(1) #Get sheet 1 in writeable copy
# write_sheet1.write(1, 11, self.invoice.text) #Write 'test' to cell (1, 11)

# write_sheet2 = write_book.get_sheet(2) #Get sheet 2 in writeable copy
# write_sheet2.write(3, 14, '135') #Write '135' to cell (3, 14)

# write_book.save("New/File/Path") #Save the newly written copy. Enter the same as the old path to write over

You are trying to get the For text but there is no object called "for" inside TOPRIGHTINVOICE . So that's where your erros are coming from. You can simply change it to:

class TOPRIGHTINVOICE(Screen):
    invoice = ObjectProperty(None)
    purpose = ObjectProperty(None)

    def next(self):
        db.add_loadinfo(self.invoice.text, self.purpose.text)
        
        self.reset()
        sm.current = "CARRIERPAGE"

    def reset(self):
        self.invoice.text = ""
        self.purpose.text = ""

    def login(self):
        self.reset()
        sm.current = "CARRIERPAGE"
...

And it will work.

But i have to say that you don't need to create a new object for every text input. This can take up memory and lead to confusions like that one. You're already passing an id to the input, so lets use it:

First delete this:

    invoice = ObjectProperty(None)
    purpose = ObjectProperty(None)

And also this on your kv file:

    invoice: invoice
    purpose: purpose

And then you can just use self.ids.yourID to referenciate the object. Like that:

    def next(self):
        db.add_loadinfo(self.ids.invoice.text, self.ids.purpose.text)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM