omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Set a Gradient as a background?

    Pythonista
    5
    6
    9281
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • robertiii
      robertiii last edited by ccc

      Is there a way to set a gradient as a background?

      Phuket2 1 Reply Last reply Reply Quote 0
      • mikael
        mikael last edited by

        I think you need to use a custom View with a custom draw method for the background. Here's the code for ObjC, looks easy to convert to Python.

        1 Reply Last reply Reply Quote 0
        • enceladus
          enceladus last edited by

          May be just draw a sequence of rectangles.

          import ui
              
          class MyView(ui.View):                    
              def __init__(self, gradient, *args, **kwargs):
                  self.gradient = gradient
                  super().__init__(*args, **kwargs)
                  self.step_size = 3
                  
              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
                      path = ui.Path.rect(x,0,self.step_size,h)
                      ui.set_color((fr*(1-t)+tr*t, fg*(1-t)+tg*t, fb*(1-t)+tb*t))
                      path.fill()
                  path = ui.Path.rect(num_steps*self.step_size, 0, w-num_steps*self.step_size, h)
                  ui.set_color((tr,tg,tb))
                  path.fill()
                  
                  
          w,h = 400,400 
          gradient = ((1,0,0) , (0,1,0))  
          v = MyView(gradient, frame=(0,0,w,h))
          v.present('sheet')
          
          
          1 Reply Last reply Reply Quote 0
          • Phuket2
            Phuket2 @robertiii last edited by

            @robertiii have a look at this. Pretty silly but still illustrative. If you search the forum for blur , there are also some nice effects that can be created like frosted glass. Sorry it was a long time ago, but some impressive effects. From memory it was using objc

            1 Reply Last reply Reply Quote 0
            • Ti Leyon
              Ti Leyon last edited by 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')
              
              
              1 Reply Last reply Reply Quote 0
              • Ti Leyon
                Ti Leyon last edited by 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
                
                1 Reply Last reply Reply Quote 0
                • First post
                  Last post
                Powered by NodeBB Forums | Contributors