示例#1
0
 def __init__(self, **kwargs):
     super(Container, self).__init__(**kwargs)
     self.previous_text = open(self.kv_file).read()
     parser = Parser(content=self.previous_text)
     widget = Factory.get(parser.root.name)()
     Builder._apply_rule(widget, parser.root, parser.root)
     self.add_widget(widget)
示例#2
0
文件: main.py 项目: tuxcanfly/kivy
    def change_kv(self, *largs):
        '''Called when the update button is clicked. Needs to update the
        interface for the currently active kv widget, if there is one based
        on the kv file the user entered. If there is an error in their kv
        syntax, show a nice popup.'''

        kv_container = self.screen_manager.current_screen.content.children[0]
        try:
            parser = Parser(content=self.language_box.text.encode('utf8'))
            kv_container.clear_widgets()
            widget = Factory.get(parser.root.name)()
            Builder._apply_rule(widget, parser.root, parser.root)
            kv_container.add_widget(widget)
        except (SyntaxError, ParserException) as e:
            self.info_label.text = str(e)
            self.anim = Animation(top=190.0, opacity=1, d=2, t='in_back') +\
                Animation(top=190.0, d=2) +\
                Animation(top=0, opacity=0, d=2)
            self.anim.start(self.info_label)
        except:
            import traceback
            traceback.print_exc()
            popup = Popup(
                title="Boom",
                content=Label(
                    text='Something horrible happened while parsing' +
                    'your Kivy Language',
                    text_size=(350, None),
                    size_hint=(None, None),
                    size=(400, 400)))
            popup.open()
示例#3
0
    def change_kv(self, *largs):
        '''Called when the update button is clicked. Needs to update the
        interface for the currently active kv widget, if there is one based
        on the kv file the user entered. If there is an error in their kv
        syntax, show a nice popup.'''

        txt = self.language_box.text
        kv_container = self.screen_manager.current_screen.children[0]
        try:
            parser = Parser(content=txt)
            kv_container.clear_widgets()
            widget = Factory.get(parser.root.name)()
            Builder._apply_rule(widget, parser.root, parser.root)
            kv_container.add_widget(widget)
        except (SyntaxError, ParserException) as e:
            self.show_error(e)
        except Exception as e:
            self.show_error(e)
示例#4
0
 def change_kv(self, *largs):
     kv_container = self.screen_manager.current_screen.content.children[0]
     try:
         parser = Parser(content=self._kv_text.encode('utf8'))
         kv_container.clear_widgets()
         widget = Factory.get(parser.root.name)()
         Builder._apply_rule(widget, parser.root, parser.root)
         kv_container.add_widget(widget)
     except (SyntaxError, ParserException) as e:
         self.info_label.text = str(e)
         self.anim = Animation(top=190.0, opacity=1, d=2, t='in_back') +\
             Animation(top=190.0, d=2) +\
             Animation(top=0, opacity=0, d=2)
         self.anim.start(self.info_label)
     except:
         import traceback
         traceback.print_exc()
         popup = Popup(title="Boom",
             content=Label(text='Something horrible happened while parsing'
                     + 'your Kivy Language', text_size=(350, None),
             size_hint=(None, None), size=(400, 400)))
         popup.open()
示例#5
0
    def change_kv_open_file(self, *largs):
        txt = self.language_box.text
        kv_container = self.screen_manager.current_screen.children[0]
        try:
            parser = Parser(content=txt)
            kv_container.clear_widgets()
            widget = Factory.get(parser.root.name)()
            Builder._apply_rule(widget, parser.root, parser.root)
            kv_container.add_widget(widget)

            name = self.ids.ui_name.text
            save_path = name
            dump = pickle.dumps(save_path)
            all = self.db.get_kvs()
            kvs = [x[0] for x in all]

            if dump not in kvs:
                self.db.add_kv(dump)

            with open(save_path, 'w') as f:
                f.write(txt)
        except:
            pass
示例#6
0
    def _build(self):
        '''
        Construct the app from KV language lines if present. (Doing so
        here and now is likely not a Kivy-like way of doing things).
        '''
        KT.indent = ""
        tabs = []
        prevIndent = None
        stack = []
        # ^ stack.append doesn't occur until the end of this method.
        # print("I am a {}.".format(str(type(self).__name__)))
        frame = inspect.stack()[2]
        cfp = frame[0].f_code.co_filename
        cf = os.path.split(cfp)[1]
        mod = importlib.import_module(os.path.splitext(cf)[0])
        # print("The file with custom widgets is \"{}\".".format(cfp))
        KT.APP = self
        self.frame = self.build()

        # ^ Ok since kivy-tkinter widget constructors always set the
        #   parent to App.ROOT by default--so no matter how the client
        #   code creates the root widget, the parent will be `App.ROOT`.
        if KT.FORM is not None:
            raise RuntimeError("kivy-tkinter built twice!")
        self.frame.pack(fill=tk.BOTH, expand=True)

        #self.frame.grid(row=0, column=0, sticky=tk.NSEW)
        #tk.Grid.rowconfigure(KT.APP, 0, weight=1)
        #tk.Grid.columnconfigure(KT.APP, 0, weight=1)

        KT.FORM = self.frame
        # self.frame.grid()
        self.frame.parent = KT.APP
        # ^ But technically, KT.APP is the root widget's
        #   (KT.APP.frame's) parent
        lineN = 0
        fn = "KV in {}".format(os.path.split(cfp)[1])
        if self.parser.filename is not None:
            fn = self.parser.filename
        for i in range(len(self.parser.sourcecode)):
            lineN += 1
            line = self.parser.sourcecode[i].rstrip()
            lineS = line.strip()
            if lineS.startswith("#"):
                continue
            # if len(stack) == 0:
            if len(lineS) == 0:
                continue
            dent = line[:(len(line) - len(lineS))]
            # print("indent: \"{}\"".format(dent))
            if len(dent) < len(KT.indent):
                while len("".join(tabs)) > len(dent):
                    if stack[-1].parent is None:
                        raise SyntaxError(dent + "Line {} of {} has more"
                                          " than one root widget near `{}`"
                                          "".format(lineN, fn, line.strip()))
                    if stack[-1].parent is not None:
                        pass
                        # add the widget AFTER setting all properties ?
                        # stack[-1].parent.add_widget(stack[-1])
                    del stack[-1]
                    del tabs[-1]
                    '''
                    print(dent + "Line {} of {} starts a new object"
                          " near `{}`.".format(lineN, fn, line.strip()))
                    '''
                if len("".join(tabs)) != len(dent):
                    raise SyntaxError(dent + "Line {} of {} doesn't"
                                      " match a previous indent near `{}`."
                                      " thisTabSize={}, dent='{}', tabs={}"
                                      "".format(lineN, fn, line.strip(),
                                                thisTabSize, dent, tabs))
            KT.indent = dent
            kvc = Parser.parserStatement(lineS)
            deeperO = None
            ThisClass = None
            # thisId = None
            # thisOr = None
            # methodName = None
            if kvc.lvalue.isCustomClass is True:
                try:
                    ThisClass = getattr(mod, kvc.lvalue.className)
                except AttributeError as ex:
                    view_traceback()
                    raise SyntaxError(dent + "Line {} of {} has a"
                                      " custom type not defined in {}"
                                      " near `{}`"
                                      "".format(lineN, fn, cf, line.strip()))
                # deeperO = ThisClass()
                # print("Creating a new (custom) {}"
                # #   "".format(ThisClass.__name__))
            elif kvc.rvalue.value is None:
                # Syntax "ThisClass:" denotes class (could be null or
                # object declaration in YAML, but is an object
                # declaration in kv)
                try:
                    ThisClass = eval(kvc.lvalue.value)
                except AttributeError as ex:
                    raise SyntaxError(dent + "Line {} of {} has a"
                                      " Kivy type not defined in"
                                      " kivy-tkinter near `{}`"
                                      "".format(lineN, fn, line.strip()))
                # deeperO = ThisClass()
                # print("Creating a new {}"
                # #     "".format(ThisClass.__name__))
            else:
                if len(stack) == 0:
                    raise SyntaxError(dent + "Line {} of {} has a"
                                      " member before an object near"
                                      " `{}`".format(lineN, fn, line.strip()))

                # Add events and properties for both KV and custom
                # classes (regardless of kvc.rvalue.className presence):
                if kvc.lvalue.value == "orientation":
                    stack[-1].orientation = kvc.rvalue.value
                    '''
                    print("[kivy-tkinter kivy app] set {} {}"
                          " orientation to {}"
                          "".format(type(stack[-1]).__name__,
                                    stack[-1].id, kvc.rvalue.value))
                    '''
                elif kvc.lvalue.value == 'id':
                    # thisId = kvc.rvalue.value
                    stack[-1].id = kvc.rvalue.value
                    self.frame.ids[kvc.rvalue.value] = stack[-1]
                elif kvc.lvalue.value == 'text':
                    # thisId = kvc.rvalue.value

                    if callable(stack[-1].text):
                        raise RuntimeError("The text override failed due to a"
                                           " programming error in kivy-tkinter"
                                           " itself.")
                        # stack[-1].text(kvc.rvalue.value)
                    stack[-1].text = kvc.rvalue.value
                elif kvc.rvalue.methodName is not None:
                    methodName = kvc.rvalue.methodName
                    if methodName.startswith("root."):
                        methodName = methodName.replace("root.", "self.frame.")
                        '''
                        print(dent + "using method `{}`"
                              "".format(methodName))
                        '''
                    elif methodName.startswith("self."):
                        methodName = methodName.replace(
                            "self.", "self.frame.ids." + stack[-1].id + ".")
                        '''
                        print(dent + "using method `{}`"
                              "".format(methodName))
                        '''
                    elif methodName.startswith("app."):
                        methodName = methodName.replace("app.", "KT.APP.")
                        '''
                        print(dent + "using method `{}`"
                              "".format(methodName))
                        '''
                    else:
                        raise NotImplementedError(
                            "The object in  the method call is not"
                            " implemented: {}".format(methodName))
                    '''
                    print(dent + "trying to add {} to {}"
                          "".format(kvc.lvalue.value,
                                    type(stack[-1]).__name__))
                    '''
                    if kvc.lvalue.value == 'on_press':
                        stack[-1].bind(on_press=eval(methodName))
                    else:
                        raise NotImplementedError(
                            "The `{}` handler is not implemented."
                            "".format(kvc.lvalue.value))

                elif kvc.rvalue.className is not None:
                    if not hasattr(stack[-1], kvc.lvalue.value):
                        warn(dent + "Line {} of {} has a KV value `{}`"
                             " for {}, which is not implemented, near"
                             " `{}`".format(lineN, fn, kvc.rvalue, kvc.lvalue,
                                            line.strip()))
                    key = kvc.lvalue.value
                    value = kvc.rvalue.value
                    # stack[-1].__dict__[key] = value
                    # ^ Using dict overwrites a property with a plain
                    # variable!
                    setattr(stack[-1], key, value)
                else:
                    key = kvc.lvalue.value
                    value = kvc.rvalue.value
                    # A literal None implies that the parser could not
                    # detect the type.
                    if not hasattr(stack[-1], kvc.lvalue.value):
                        warn(dent + "Line {} of {} has an rvalue"
                             " that will be taken literally: `{}` near"
                             " `{}`".format(lineN, fn, kvc.rvalue,
                                            line.strip()))
                    # stack[-1].__dict__[key] = value
                    # ^ Using dict overwrites a property with a plain
                    # variable!
                    setattr(stack[-1], key, value)
                    # TODO: implement KV rules such as:
                    # right: self.parent.right
                    # right: layout.right # where id of parent is layout

            if ThisClass is not None:
                if len(stack) == 0:
                    deeperO = self.frame
                    # ^ Make the child objects get appended to the frame
                    #   (root widget)
                else:
                    '''
                    if thisOr is not None:
                        deeperO = ThisClass(
                            tkinterParent=stack[-1],
                            orientation=thisOr,
                        )
                    else:
                    '''
                    deeperO = ThisClass(tkinterParent=stack[-1])
                    '''
                    print(dent + "tkinterParent is {}"
                          "".format(stack[-1]))
                    '''
                    '''
                    msgFmt = (dent + "adding {}"
                              " to {} {} with orientation {}.")
                    print(
                        msgFmt.format(
                            kvc.lvalue.value,
                            type(stack[-1]).__name__,
                            stack[-1].id,
                            stack[-1].orientation,
                        )
                    )
                    '''

                    if not hasattr(stack[-1], 'add_widget'):
                        exFmt = (dent + "Line {} of {} has a `{}`"
                                 " inside of a `{}` near `{}`.")

                        raise SyntaxError(
                            exFmt.format(lineN, fn, kvc.lvalue.value,
                                         type(stack[-1]).__name__,
                                         line.strip()))
                    stack[-1].add_widget(deeperO)
                # if thisId is not None:
                # self.frame.ids[thisId] = deeperO
                stack.append(deeperO)
            thisTabSize = len(dent) - len("".join(tabs))
            '''
            if thisTabSize < 1:
                exFmt = (dent + "[kivy-tkinter app] failed to"
                         " correctly add to the indent on line {} "
                         " of {} near `{}`. This is a failure in"
                         " kivy-tkinter itself. thisTabSize={},"
                         " dent='{}', tabs={}")

                raise RuntimeError(
                    exFmt.format(lineN, fn, line.strip(),
                                 thisTabSize, dent, tabs)
                )
            '''
            if thisTabSize > 0:
                tabs.append(dent[-thisTabSize:])
示例#7
0
 def run(self):
     self.parser = Parser(content=Builder._loadedStr)
     self._build()
     KT.APP.mainloop()
示例#8
0
    def change_kv(self, *largs):
        '''Called when the update button is clicked. Needs to update the
        interface for the currently active kv widget, if there is one based
        on the kv file the user entered. If there is an error in their kv
        syntax, show a nice popup.'''

        txt = self.language_box.text
        kv_container = self.screen_manager.current_screen.children[0]
        try:
            parser = Parser(content=txt)
            kv_container.clear_widgets()
            widget = Factory.get(parser.root.name)()
            Builder._apply_rule(widget, parser.root, parser.root)
            kv_container.add_widget(widget)

            name = self.ids.ui_name.text
            print(f'The whatever name is {name}')
            if name == 'Untitled*':
                m = ModalView(size_hint=[.6, .7])
                box = BoxLayout(orientation='vertical')
                m.add_widget(box)

                # Function to get user's current home directory
                from os.path import expanduser
                users_home = expanduser('~')
                user_home_dir = os.path.join(users_home, 'Desktop')
                try:
                    os.mkdir(os.path.join(user_home_dir, 'KivyEditor'))
                    user_home_dir = os.path.join(user_home_dir, 'KivyEditor')
                except FileExistsError:
                    # user_home_dir = os.path.join(user_home_dir, 'KivyEditor')
                    pass

                name_box = BoxLayout(size_hint_y=.1)
                fc = FileChooserListView(size_hint_y=.9,
                                         filters=['*kv'],
                                         rootpath=user_home_dir)

                box.add_widget(name_box)
                box.add_widget(fc)

                tinput = TextInput(multiline=False, size_hint_x=.8)
                submit = Button(text='Save',
                                background_color=[1, 1, 1, 1],
                                background_normal='',
                                color=[0, 0, 0, 1],
                                size_hint_x=.2)

                tinput.bind(on_text_validate=lambda x: self.update_name(
                    os.path.join(fc.path, tinput.text), m))
                submit.bind(on_release=lambda x: self.update_name(
                    os.path.join(fc.path, tinput.text), m))

                name_box.add_widget(tinput)
                name_box.add_widget(submit)
                m.open()

            else:
                save_path = name
                dump = pickle.dumps(save_path)
                all = self.db.get_kvs()
                kvs = [x[0] for x in all]

                if dump not in kvs:
                    self.db.add_kv(dump)

                with open(save_path, 'w') as f:
                    f.write(txt)

        except (SyntaxError, ParserException) as e:
            self.show_error(e)
        except Exception as e:
            self.show_error(e)
示例#9
0
文件: main.py 项目: dpkm95/DSApp
DS_ROOT = os.path.dirname(__file__)

DS_KVS = os.path.join(DS_ROOT,'ds_kvs')
DS_CLASSES = [c[:-3] for c in os.listdir(DS_KVS)

class Root(FloatLayout):
	screen_manager = ObjectProperty(None)	
	child = ObjectProperty(None) 

	def change_kv(self,*largs):
		child = self.screen_manager.current_screen.children[0]
		with open(child.kv_file, 'rb') as file:
			text = file.read().decode('utf8')
		kv_container = self.screen_manager.current_screen
		try:
			parser = Parser(content = txt)
			kv_container.clear_widgets()
			widget = Factory.get(parser.root.name)()
			Builder._apply_rule(widget,parser.root,parser.root)
			kv_container.add_widget(widget)
		except (SyntaxError, ParserException) as e:
			self.show_error(e)
		except Exception as e:
			self.show_error(e)	 

class DS(App):
	pass

Factory.register('Root', cls=Root)
	
if __name__=='__main__':