• Ti Leyon

    @themusicman Maybe you should try using UniPAGE then you may write and test your codes on all major platforms without modification (MS Windows, OS X, Linux, IOS [Pythonista], Android [Pydroid recommended]). For all the desktop environment you will need to install Kivy (already preinstalled in Pydroid). All the basic UI elements (Button, Text input, label etc…) are included. You do not have to install the module you can just add your code to it. I wanted to include TKinter to make it truly universal on most versions of Python with absolutely no installation necessary but I never got the chance to do it. I probably will try to spare some time in the coming weeks to do that. You may even use an extension to UniPAGE called Graphics Agnostic Python (GAP) which provides a visual interface designer that automatically generates a “.py” file with the complete interface.

    posted in Pythonista read more
  • Ti Leyon

    Hey @JonB did not you write a graphical file manager by the name of “PhoneManager”? I adapted and use it occasionally without the need to ever download “stash”. Do not get me wrong, “stash” is probably one of the best and most useful script published in this forum (as attest by its popularity). However, if you are not entirely dedicated to a specific OS it becomes costly (in time, memorizing and touch typing) to get involve in any CLI dedicated to that OS. @adrius42 you may probably get most of what you want by using “PhoneManager” and/or @cvp’s script and modify them to your need once you become familiar with the nitty-gritty of Pythonista under IOS.

    posted in Pythonista read more
  • Ti Leyon

    @uncompleted if you want to use pandas while on the move you should get yourself an Android device if you do not already own one. It does not seem that pandas is coming to Pythonista anytime soon. Meanwhile, the recent release of Pydroid 3 on the Android platform is a free, full featured python 3.6 implementation that includes PIP, Kivy and Pyqt5. You can use PIP to download most of the modules available on desktops including Pandas, Numpy, Scipy, Matplotlib, Scikit-learn, Jupyter etc... The only interesting modules that are not yet compatible seem to be Tensorflow and OpenCV. Of course Tkinter is not included but personally I do not think it is a big loss. By the way you may buy the Huawei MediaPad M3 8.0 for about US $200.00 on Amazon. This is a 2.3 Gz Octa Core device that easily outperforms the iPad mini 4. For scripts that includes modules available in Pythonista you may even bridge the UIs so you do not have to rewrite your codes. Here is an example showing one way to go about it: https://forum.omz-software.com/topic/4307/graphics-agnostic-python-gap.

    posted in Pythonista read more
  • Ti Leyon

    @scatter it is fairly easy to write cross UI platforms applications that run unmodified at the source code level on all major GUIs using python. That is if you plan to use specific UI elements and not trying to create warpers around a platform from the standpoint of another. I have published scripts in this forum (refer to this thread) that demonstrate the matter with fully functional modules. They cover the basic UI elements that (arguably) form the basis of most applications. They cover the Pythonista UI matched with the Kivy GUI. Integrating Tkinter maybe a little more complicated since it does not closely follow the same syntax structure as the others. However, it can be done with not much pain if you really want to go that route. Here is a simple demo that covers basic geometric forms and integrates all three GUIs automatically. I also developed a graphic designer that speeds up the coding of the interface that you may find here. Hope this helps.

    posted in Pythonista read more
  • Ti Leyon

    Since I intend to include “Tkinter” in future implementation of universal codes (refer to GAP in this forum) I went to investigate the 3.xx implementation of that module. They did take out the capitalization from “Tkinter”. Change the “Tkinter” block from “getgui()” to add one more exception (as shown below) and the script should run everywhere without modification.

                try:
                    from Tkinter import Tk
                    platform = 'Tk'
                    gui = object
                except:
                    import tkinter
                    import sys
                    sys.modules['Tkinter'] = tkinter
                    platform = 'Tk'
                    gui = object
    

    posted in Pythonista read more
  • Ti Leyon

    Once I saw this thread I thought about a straight Python implementation. Since it was already done I extended @enceladus snippet into a universal Python gradient demo. I also included @Phuket2 radial takes (well sort of) and added a square gradient. A “Next” button at the bottom right of the window cycles the view between linear, radial and square gradient fills. I tried to stay as close as possible to the spirit of @enceladus code. It detects and uses the Pythonista UI, Kivy or Tkinter automatically. Therefore, it should work on any Python distribution unmodified. Come to think of it I think that they change the capitalization for Tkinter in version 3.xx. Change the name accordingly if you are using any python version higher than 2.xx This is nothing serious though just some “silly” (as @Phuket2 put it) coding for fun. Below is the script.

    def getgui():
        try:
            import ui
            platform = 'Pythonista'
            gui = ui.View
        except:
            try:
                from kivy.uix.floatlayout import FloatLayout
                platform = 'Kivy'
                gui = object
            except:
                from Tkinter import Tk
                platform = 'Tk'
                gui = object
        return platform, gui
            
    platform, gui = getgui()
    
    if platform == 'Pythonista':
        import ui
    
    class MyView(gui):                    
        def __init__(self, platform, gradient, *args, **kwargs):
            self.gradient = gradient
            self.step_size = 3
            self.gradient_type = ['linear', 'radial', 'square']
            self.current_fill = 0
            self.grads = []
            self.platform = platform
            if self.platform == 'Pythonista':
                ui.View.__init__(self, *args, **kwargs)
                self.next_button = ui.Button(frame= \
                    (330, 360, 30, 60), title = 'Next')
                self.next_button.background_color = (0.4,0.4,0.4)
                self.next_button.action = self.next_fill
                self.next_button.height = 30
                self.next_button.width = 60
                self.next_button.tint_color = 'white'
                self.next_button.font = ('<system>', 12)
                self.add_subview(self.next_button)
            
            elif self.platform == 'Kivy':
                from kivy.uix.floatlayout import FloatLayout
                from kivy.uix.button import Button
                self.root = FloatLayout()
                self.frame = kwargs['frame']
                self.next_button = Button( text = 'NEXT',
                size_hint_y = None, size_hint_x = None,
                height = 30, width = 60, font_size = 12, pos = (330, 10),
                on_press = self.next_fill )
                self.root.add_widget(self.next_button)
    
            elif self.platform == 'Tk':
                from Tkinter import Tk
                from Tkinter import Canvas
                from Tkinter import Frame
                from Tkinter import Label
                from Tkinter import NW
                self.master = Tk()
                self.root = Canvas(self.master, width=kwargs['frame'][2], \
                                   height=kwargs['frame'][3])
                self.root.pack()
                self.frame = kwargs['frame']
                contour = Frame(self.master, height=30, width=60)
                contour.pack_propagate(0) # don't shrink
                label = Label(contour, text='NEXT', fg='white', bg='#585858', \
                              height=30, width=60)
                label.bind("<Button-1>", self.tk_button_down)
                label.bind("<ButtonRelease-1>", self.tk_button_up)
                
                label.pack()
                label.config(font=('TkDefaultFont',12), padx=0,pady=0)
                contour.place(x=330, y =360, anchor=NW)
            
        def next_fill(self, sender):
            self.current_fill += 1
            if self.current_fill == 3:
                self.current_fill = 0
            if self.platform == 'Pythonista':
                self.set_needs_display()
            else:
                self.draw()
            
        def tk_button_down(self, event):
            event.widget.config(bg='#00A5D4')
          
        def tk_button_up(self, event):
            event.widget.config(bg='#585858')
            self.next_fill(self.tk_button_up)
        
        def present_all(self, mode):
            if self.platform == 'Pythonista':
                self.present(mode)
            if self.platform == 'Tk':
                self.draw()
                self.root.mainloop()
            elif self.platform == 'Kivy':
                from kivy.base import runTouchApp            
                from kivy.core.window import Window
                Window.size = self.frame[2:4]
                self.draw()
                runTouchApp(self.root)
    
        def draw(self):
            x,y,w,h = self.frame
            ((fr,fg,fb), (tr, tg, tb)) = gradient       
            num_steps = int(w/self.step_size)
            for step in range(num_steps):
                x = step*self.step_size
                t = step/(num_steps * 1.0)
                if self.platform == 'Pythonista':
                    if self.gradient_type [self.current_fill] == 'linear':
                        path = ui.Path.rect(x,0,self.step_size,h)
                    elif self.gradient_type [self.current_fill] == 'radial':
                        if w - ((2 * step) * self.step_size) >= 0:
                            path = ui.Path.oval(x, x, w - 2*x, h-2*x)
                    elif self.gradient_type [self.current_fill] == 'square':
                        if w - ((2 * step) * self.step_size) >= 0:
                            path = ui.Path.rect(x,x,w - ((2*step) * \
                                (self.step_size)),h - (2*step)*self.step_size)
                        ui.set_color((fr*(1-t)+tr*t, fg*(1-t)+tg*t, fb*(1-t)+tb*t))
                        path.fill()
                    ui.set_color((fr*(1-t)+tr*t, fg*(1-t)+tg*t, fb*(1-t)+tb*t))
                    path.fill()
    
                elif self.platform == 'Tk':
                    if step == 0:
                        self.root.create_rectangle( 0, 0, w, h, \
                                                fill='black', outline='black')                    
                    cl = '#' + '%02x' % int((fr*(1-t)+tr*t) * 255) + \
                        '%02x' % int((fg*(1-t)+tg*t) * 255) + \
                        '%02x' % int((fb*(1-t)+tb*t) * 255)
                    if self.gradient_type [self.current_fill] == 'linear':
                        self.root.create_rectangle( x, 0, self.step_size + x, h, \
                                                fill=cl, outline=cl)
                    elif self.gradient_type [self.current_fill] == 'radial':
                        if w - ((2 * step) * self.step_size) >= 0:
                            self.root.create_oval( x + self.step_size, x + \
                                self.step_size, w - ((2*step) * (self.step_size)) \
                                + x, h - (2*step)*self.step_size + x, \
                                fill=cl, outline=cl)
                    elif self.gradient_type [self.current_fill] == 'square':
                        if w - ((2 * step) * self.step_size) >= 0:
                            self.root.create_rectangle( x, x, w - ((2*step) * \
                                (self.step_size)) + x, h - (2*step)*self.step_size \
                                + x, fill=cl, outline=cl)
                        
                elif self.platform == 'Kivy':
                    if step == 0:
                        from kivy.graphics import Color
                        from kivy.graphics import Rectangle
                    self.grads.append ((fr*(1-t)+tr*t, fg*(1-t)+tg*t, \
                                                 fb*(1-t)+tb*t))
                    self.root.canvas.add(Color (fr*(1-t)+tr*t, fg*(1-t)+tg*t, \
                                                 fb*(1-t)+tb*t))
                    if self.gradient_type [self.current_fill] == 'linear':
                        self.root.canvas.add(Rectangle(pos = (x, 0), \
                                                size = (self.step_size,h)))
                    elif self.gradient_type [self.current_fill] == 'radial':
                        if w - ((2 * step) * self.step_size) >= 0:
                            if step == 0:
                                from kivy.graphics import Line
                            self.root.canvas.add(Line(circle = (w/2, h/2, w - \
                                (2*step)*self.step_size), width = self.step_size))
                    elif self.gradient_type [self.current_fill] == 'square':
                        if w - ((2 * step) * self.step_size) >= 0:
                            self.root.canvas.add(Rectangle(pos = (x, x), size = \
                                                (w - (2*step)*self.step_size, \
                                                 h - (2*step)*self.step_size)))
                    self.root.remove_widget(self.next_button)
                    self.root.add_widget(self.next_button)
    
    w,h = 400,400 
    gradient = ((1,0,0) , (0,1,0))
    v = MyView(platform,gradient, frame=(0,0,w,h))
    v.present_all('sheet')
    
    

    posted in Pythonista read more
  • Ti Leyon

    This is way cool @mikael and really good extension @enceladus. Whenever I can spare the time I will try to extend it into a basic universal animation studio on all platforms. Sounds really challenging though but isn’t challenge the cradle of creativity?.

    posted in Pythonista read more
  • Ti Leyon

    It is about time. Excellent work @ccc and well deserved kudos to @omz. I was a lost programming soul on iOS bouncing between a fairly good version of BASIC, a mediocre implementation of Python and Lua. Then I discovered Pythonista and my life on iOS has never been the same since.

    posted in Pythonista read more
  • Ti Leyon

    Major enhancements to the Visual Interface Designer’s interface. Now you can change the sizes of a selected object by dragging on it with the mouse or finger. To do so you have to toggle the newly introduced switch buttons to the on state. This will prevent the component from moving and instead its dimensions will change with the dragging according to which switch is turned on. You can also change the name of the output file directly from GAP. The interfaces of files built with GAP can now be loaded and modified. This is almost "programming for the rest of us". Programming for the non techie on the go. If I can spare the time I will try to write a MIT Scratch like Python script to make it fully so.

    Please use gap21.py to get the new features.

    Below is a screenshot with a description of the new features.

    gapinfo

    Although GAP was developed manually using UniPAGe below is a screenshot of the script reading itself in an Android phone.

    gapinfo

    In a further release I will try to introduce a help screen at the first start up in a specific directory since the space for the three lines instruction is now taken.

    posted in Pythonista read more
  • Ti Leyon

    If you are using a lower resolution device such as most iPhones the optimal mode (0, 0) may not fit in landscape orientation. It will work fine in portrait though. This is because I cannot yet locate a reliable documentation for the height of title bar in a sheet presentation at any resolution. If you do want to use that orientation change the title_bar_height factor from 50 to 90.

    posted in Pythonista read more

Internal error.

Oops! Looks like something went wrong!