所以我和我的朋友正在制作应用程序:
main.py:
from kivy.app import App
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.uix.scrollview import ScrollView
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.dropdown import DropDown
from kivy.uix.textinput import TextInput
from kivy.uix.modalview import ModalView
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition
from kivy.uix.settings import SettingsWithSidebar
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.popup import Popup
from kivy.properties import ObjectProperty
from kivy.garden.navigationdrawer import NavigationDrawer
from settingsjson import general_settings
import os
Builder.load_file('main.kv') # keep main.kv in the same directory
class MyDrop(DropDown):
for i in range(5):
print i
class LoadDialog(FloatLayout):
load = ObjectProperty(None)
cancel = ObjectProperty(None)
class SaveDialog(FloatLayout):
save = ObjectProperty(None)
text_input = ObjectProperty(None)
cancel = ObjectProperty(None)
class Notes(Screen, BoxLayout):
top_layout = ObjectProperty(None)
TextSpace = ObjectProperty(None)
quick_settings = ObjectProperty(None)
loadfile = ObjectProperty(None)
savefile = ObjectProperty(None)
text_input = ObjectProperty(None)
def __init__(self, *args, **kwargs):
super(Notes, self).__init__(*args, **kwargs)
self.drop_down = MyDrop()
dropdown = DropDown()
notes = ["Notes", "Sketch", "To-do"]
for note in notes:
btn = Button(text='%r' % note, size_hint_y=None, height=40)
btn.bind(on_release=lambda btn: dropdown.select(btn.text))
dropdown.add_widget(btn)
mainbutton = Button(text='Notes', size_hint=(1, 1))
mainbutton.bind(on_release=dropdown.open)
dropdown.bind(on_select=lambda instance, x: setattr(mainbutton, 'text', x))
self.top_layout.add_widget(mainbutton)
def create_new_notebook(self):
nnotebook = ModalView(size_hint=(None, None), size=(400, 60))
box = BoxLayout(orientation='vertical')
box.add_widget(Label(text='Name Your New Notebook'))
notebookn = TextInput(focus='true', multiline='false')
box.add_widget(notebookn)
nnotebook.add_widget(box)
nnotebook.open()
nnotebook.bind(on_text_validate=self.ids.notebooks.add_widget(Button(text=str(notebookn.text)))) # declare the variable
#return new_notebook
def remove_notebook(self):
new_notebook = self.create_new_notebook()
self.ids.notebooks.remove_widget(new_notebook) # remove the bottom button
def dismiss_popup(self):
self._popup.dismiss()
def show_load(self):
content = LoadDialog(load=self.load, cancel=self.dismiss_popup)
self._popup = Popup(title="Load Note", content=content, size_hint=(0.9, 0.9))
self._popup.open()
def show_save(self):
content = SaveDialog(save=self.save, cancel=self.dismiss_popup)
self._popup = Popup(title="Save Note", content=content, size_hint=(0.9, 0.9))
self._popup.open()
def load(self, path, filename):
with open(os.path.join(path, filename[0])) as stream:
self.text_input.text = stream.read()
self.dismiss_popup()
def save(self, path, filename):
with open(os.path.join(path, filename), 'w') as stream:
stream.write(self.text_input.text)
self.dismiss_popup()
sm = ScreenManager(transition=SlideTransition(direction='up'))
sm.add_widget(Notes(name='home'))
Factory.register('LoadDialog', cls=LoadDialog)
Factory.register('SaveDialog', cls=SaveDialog)
class MyApp(App):
def build(self):
self.settings_cls = SettingsWithSidebar
return sm
def build_config(self, config):
config.setdefaults('General', {'Open_On_Startup': True})
def build_settings(self, settings):
settings.add_json_panel('General', self.config, data=general_settings)
if __name__ == '__main__':
MyApp().run()
main.kv:
<Notes@BoxLayout>:
top_layout: topLayout
space_text: spacetext
quick_settings: quicksettings
text_input: text_input
orientation: "vertical"
BoxLayout:
id: topLayout
height: "40dp"
size_hint_y: None
pos_hint: {'top': 1}
Button:
text: "Settings"
size_hint_x:0.1
on_release: app.open_settings() # root.manager.current = 'settings'
# Button:
# text: "Notes"
# size_hint_x:0.9
# on_release: root.drop_down.open(self)
BoxLayout:
padding: 0, 40
id: spacetext
NavigationDrawer:
anim_type: 'reveal_below_simple'
BoxLayout:
orientation: 'vertical'
Label:
size_hint_y: None
height: "30px"
text: 'MY NOTEBOOKS'
BoxLayout:
id: notebooks
orientation: 'vertical'
Button:
text: 'Notebook 1'
min_height: '30px' # this doesn't work but we somehow have to implement it
Button:
text: 'Notebook 2'
Button:
text: 'Notebook 3'
BoxLayout:
id: notebook_mod
size_hint_y: None
height: '30px'
Button:
id: add_notebook_button
text: '+'
size_hint_y: None
height: '30px'
on_release: root.create_new_notebook()
Button:
id: remove_notebook_button
text: '-'
size_hint_y: None
height: '30px'
on_release: root.remove_notebook()
Carousel:
loop: False
#size_hint_x: .85
ScrollView:
id: scrlv
size_hint_x: 1
TextInput:
id: text_input
on_text:
size_hint: 1, None
height: max(self.minimum_height, scrlv.height)
BoxLayout:
id: quicksettings # Quick settings menu (bold, italics, font-size, etc)
height:'40dp'
size_hint_y:None
Button:
markup: True
text: ('[b][color=000000]B[/color][/b]')
Button:
markup: True
text: ('[i][color=000000]I[/color][/i]')
Button:
markup: True
text: ('[u][color=000000]U[/color][/u]')
Button:
text: 'Load'
on_release: root.show_load()
Button:
text: 'Save'
on_release: root.show_save()
<MyDrop>:
Button:
text: 'Notes'
size_hint_y: None
height: 40
on_release: root.manager.current = 'home'
Button:
text: 'To-do'
size_hint_y: None
height: 40
on_release: root.manager.current = 'todo'
Button:
text: 'Sketch'
size_hint_y: None
height: 40
on_release: root.sm.current = 'sketch'
<LoadDialog>:
BoxLayout:
size: root.size
pos: root.pos
orientation: "vertical"
FileChooserListView:
id: filechooser
BoxLayout:
size_hint_y: None
height: 30
Button:
text: "Cancel"
on_release: root.cancel()
Button:
text: "Load"
on_release: root.load(filechooser.path, filechooser.selection)
<SaveDialog>:
text_input: text_input
BoxLayout:
size: root.size
pos: root.pos
orientation: "vertical"
FileChooserListView:
id: filechooser
on_selection: text_input.text = self.selection and self.selection[0] or ''
TextInput:
id: text_input
size_hint_y: None
height: 30
multiline: False
BoxLayout:
size_hint_y: None
height: 30
Button:
text: "Cancel"
on_release: root.cancel()
Button:
text: "Save"
on_release: root.save(filechooser.path, text_input.text)
这就是错误:
File "main.py", line 26, in <module>
Builder.load_file('main.kv') # keep main.kv in the same directory
File "/usr/lib/python2.7/site-packages/kivy/lang.py", line 1444, in load_file
return self.load_string(data, **kwargs)
File "/usr/lib/python2.7/site-packages/kivy/lang.py", line 1491, in load_string
parser = Parser(content=string, filename=fn)
File "/usr/lib/python2.7/site-packages/kivy/lang.py", line 1049, in __init__
self.parse(content)
File "/usr/lib/python2.7/site-packages/kivy/lang.py", line 1122, in parse
objects, remaining_lines = self.parse_level(0, lines)
File "/usr/lib/python2.7/site-packages/kivy/lang.py", line 1218, in parse_level
level + 1, lines[i:], spaces)
File "/usr/lib/python2.7/site-packages/kivy/lang.py", line 1218, in parse_level
level + 1, lines[i:], spaces)
File "/usr/lib/python2.7/site-packages/kivy/lang.py", line 1218, in parse_level
level + 1, lines[i:], spaces)
File "/usr/lib/python2.7/site-packages/kivy/lang.py", line 1218, in parse_level
level + 1, lines[i:], spaces)
File "/usr/lib/python2.7/site-packages/kivy/lang.py", line 1218, in parse_level
level + 1, lines[i:], spaces)
File "/usr/lib/python2.7/site-packages/kivy/lang.py", line 1271, in parse_level
if current_property[:3] == 'on_':
TypeError: 'NoneType' object has no attribute '__getitem__'
该应用程序基本上是一个笔记应用程序。 我尝试实现保存/加载对话框后出现此错误,该对话框是从文档中交叉复制的。 如果你有任何帮助, 谢谢!
答案 0 :(得分:1)
您的kv代码中存在许多缩进问题 - 尽管这些问题可能只是复制/粘贴问题。但是,你的kv也有错误:
TextInput:
id: text_input
on_text:
size_hint: 1, None
height: max(self.minimum_height, scrlv.height)
您有on_text:
,但未指定任何处理程序。
答案 1 :(得分:0)
Kivy对缩进非常严格。间距必须是第一个缩进线上使用的空格数的倍数。上面的 main.kv 中的 LoadDialog 类中忽略了此规则。
项目的属性和元素也必须放在同一级别上。但是 SaveDialog 类的属性 text_input 比其子 BoxLayout 的缩进更多。
没有错误,只是解析器。