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.