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.


    Interactive test

    Pythonista
    5
    15
    6398
    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.
    • RoninSage
      RoninSage last edited by

      I would like to create an interactive quiz using Pythonista. I was trying to learn how to use the scene kit but I was having trouble doing even basic operations based on the limited examples in the documentation. I would like the questions to pop up and to tap the answers. At the end of the test, all the selected answers would be saved to a .csv file and sent to an email address for further analysis. It seems like a fairly simple task and I am hoping someone has done something like this before and can help or point me in a direction where I can start. Thanks in advance.

      cvp mikael 2 Replies Last reply Reply Quote 0
      • cvp
        cvp @RoninSage last edited by

        @RoninSage Why do you need a Scene?

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

          It seemed the best way to use the touch screen interface of the iPad. I am open to other suggestions.

          cvp 1 Reply Last reply Reply Quote 0
          • cvp
            cvp @RoninSage last edited by

            @RoninSage Check this
            Marvelous help

            mikael 1 Reply Last reply Reply Quote 1
            • mikael
              mikael @cvp last edited by

              @cvp, while I appreciate the shout-out for Gestures, it seems truly an overkill for this use case, as is Scene.

              Quickest way to get this going would probably be console.alert, which lets you show a title (e.g. ”Question #1”), the question, and three options for answers.

              If you want more fancy graphics, a custom ui.View with a TextView and Buttons is quite straightforward as well. You can use the UI designer to create the layout.

              Let us know what you need to get forward.

              1 Reply Last reply Reply Quote 0
              • mikael
                mikael @RoninSage last edited by

                ... and if you decide to go with the custom UI.View and want to get really fancy, with questions and answers flying in and out or other effects like that, then I would recommend Scripter to make managing the animations easier.

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

                  Here is an example implementation and I hope it helps
                  https://gist.github.com/4e520ac2104b902b7a2394d4e7855fa3

                  1 Reply Last reply Reply Quote 1
                  • ellie_ff1493
                    ellie_ff1493 last edited by ellie_ff1493

                    I tried it with scene

                    from scene import Scene, Node, LabelNode, run
                    
                    
                    class quiz(Scene):
                        def __init__(self):
                            super().__init__()
                            self.pages = []
                            
                        def setup(self):
                            self.page_now = -1
                            self.buttons = Node()
                            self.add_child(self.buttons)
                            temp = LabelNode("start quiz?")
                            temp.position = self.size/2
                            self.buttons.add_child(temp)
                    
                        def touch_began(self, touch):
                            for i in self.buttons.children:
                                if touch.location in i.bbox:
                                    if self.page_now < len(self.pages)-1:
                                        self.next_page()
                                        print("userer picked:", i.text)
                                    else:
                                        print("end of quiz")
                    
                        def next_page(self):
                            self.buttons.remove_from_parent()
                            self.page_now += 1
                            question, values = self.pages[self.page_now]
                            page = Node()
                            num_of_nodes = len(values) + 1
                            h = self.size.h / num_of_nodes
                            w = self.size.w
                            x = self.size.w * 0.5
                            but = LabelNode(question, font=('Helvetica', 40))
                            values.append("")
                            for i in range(len(values)):
                                but.anchor_point = (0.5, 1)
                                but.position = (x, self.size.y - (h*i))
                                but.y_scale = min(w / but.size.x, h/but.size.y)
                                but.x_scale = min(w / but.size.x, h/but.size.y)
                                page.add_child(but)
                                but = LabelNode(values[i], font=('Helvetica', 40))
                    
                            self.buttons = page
                            self.add_child(page)
                    
                        def add_page(self, question, values):
                            self.pages.insert(-2, (question, values))
                    if __name__ == "__main__":
                        app = quiz()
                        app.add_page("do you like this code", ["yes", "no"])
                        app.add_page("do you understand this code", ["yes", "no", "whats code lol"])
                        app.add_page("if you add lots of text it gets smallergggggggggggggggggggggggggggggggggggggggg", ["oh ok, cool"])
                        run(app)
                    
                    1 Reply Last reply Reply Quote 1
                    • RoninSage
                      RoninSage last edited by RoninSage

                      @enceladus & @ellie_ff1493 thanks for the suggestions but it is not really where I wanted to go with this. Below is code that is starting to get there, however, I want all of the question boxes to move onto the next question whenever one of them is selected. I am sure how to do that. Also, I have included code at the bottom that will record the answers selected into a csv file for later use, I just need help with the code that records the selections into a list. Finally, to complete everything, I would like to start the test off with the participant entering Name, Surname, phone number and email, again something I haven’t figured out yet but I am guessing will need access to the soft keyboard. The code probably needs some cleaning up as I just started working with the code that @cvp linked to earlier.

                      
                      import itertools, ui, uuid
                      from objc_util import *
                      
                      # Generate list of all fonts
                      def get_font_list():
                        UIFont = ObjCClass('UIFont')
                        return list(itertools.chain(*[UIFont.fontNamesForFamilyName_(str(x))
                              for x in UIFont.familyNames()]))
                      font_list = get_font_list()
                      for i in range(len(font_list)):
                        font_list[i]=str(font_list[i])
                      
                      UILayoutContainerView = ObjCClass('UILayoutContainerView')
                      UISwipeGestureRecognizer = ObjCClass('UISwipeGestureRecognizer')
                      
                      def disable_swipe_to_close(view):
                        v = view.objc_instance
                        while not v.isKindOfClass_(UILayoutContainerView.ptr):
                          v = v.superview()
                        for gr in v.gestureRecognizers():
                          if gr.isKindOfClass_(UISwipeGestureRecognizer.ptr):
                            gr.setEnabled(False)
                      
                      class Gestures():
                      
                        TYPE_REGULAR = 0
                        TYPE_FORCE = 1
                        TYPE_STYLUS = 4
                        TYPE_ANY = 8. 
                      
                        TAP = b'UITapGestureRecognizer'
                        PINCH = b'UIPinchGestureRecognizer'
                        ROTATION = b'UIRotationGestureRecognizer'
                        SWIPE = b'UISwipeGestureRecognizer'
                        PAN = b'UIPanGestureRecognizer'
                        SCREEN_EDGE_PAN = b'UIScreenEdgePanGestureRecognizer'
                        LONG_PRESS = b'UILongPressGestureRecognizer'
                      
                        CHANGED = 2
                        ENDED = 3
                      
                        RIGHT = 1; LEFT = 2; UP = 4; DOWN = 8
                      
                        EDGE_NONE = 0; EDGE_TOP = 1; EDGE_LEFT = 2; EDGE_BOTTOM = 4; EDGE_RIGHT = 8; EDGE_ALL = 15
                      
                        def __init__(self, touch_type=TYPE_REGULAR, force_threshold=0.4, retain_global_reference = True):
                          self.buttons = {}
                          self.views = {}
                          self.recognizers = {}
                          self.actions = {}
                          self.touches = {}
                          self.touch_type = touch_type
                          self.force_threshold = force_threshold
                          if retain_global_reference:
                            retain_global(self)
                      
                          # Friendly delegate functions
                      
                          def recognize_simultaneously_default(gr_name, other_gr_name):
                            return False    
                          self.recognize_simultaneously = recognize_simultaneously_default
                          
                          def fail_default(gr_name, other_gr_name):
                            return False    
                          self.fail = fail_default
                          
                          def fail_other_default(gr_name, other_gr_name):
                            return False    
                          self.fail_other = fail_other_default
                      
                          # ObjC delegate functions
                          
                          def simplify(func, gr, other_gr):
                            gr_o = ObjCInstance(gr)
                            other_gr_o = ObjCInstance(other_gr)
                            if (gr_o.view() != other_gr_o.view()):
                              return False
                            gr_name = gr_o._get_objc_classname()
                            other_gr_name = other_gr_o._get_objc_classname()
                            return func(gr_name, other_gr_name)
                          
                          # Recognize simultaneously
                      
                          def gestureRecognizer_shouldRecognizeSimultaneouslyWithGestureRecognizer_(_self, _sel, gr, other_gr):
                            return self.objc_should_recognize_simultaneously(self.recognize_simultaneously, gr, other_gr)
                      
                          def objc_should_recognize_simultaneously_default(func, gr, other_gr):
                            return simplify(func, gr, other_gr)
                            
                          self.objc_should_recognize_simultaneously = objc_should_recognize_simultaneously_default
                          
                          # Fail other
                          
                          def gestureRecognizer_shouldRequireFailureOfGestureRecognizer_(_self, _sel, gr, other_gr):
                            return self.objc_should_require_failure(self.fail_other, gr, other_gr)
                      
                          def objc_should_require_failure_default(func, gr, other_gr):
                            return simplify(func, gr, other_gr)
                            
                          self.objc_should_require_failure = objc_should_require_failure_default
                          
                          # Fail
                          
                          def gestureRecognizer_shouldBeRequiredToFailByGestureRecognizer_(_self, _sel, gr, other_gr):
                            return self.objc_should_fail(self.fail, gr, other_gr)
                      
                          def objc_should_fail_default(func, gr, other_gr):
                            return simplify(func, gr, other_gr)
                            
                          self.objc_should_fail = objc_should_fail_default
                          
                          # Delegate
                          
                          try:
                            PythonistaGestureDelegate = ObjCClass('PythonistaGestureDelegate')
                          except:
                            PythonistaGestureDelegate = create_objc_class('PythonistaGestureDelegate',
                            superclass=NSObject,
                            methods=[
                              gestureRecognizer_shouldRecognizeSimultaneouslyWithGestureRecognizer_,
                              gestureRecognizer_shouldRequireFailureOfGestureRecognizer_,
                              gestureRecognizer_shouldBeRequiredToFailByGestureRecognizer_],
                            classmethods=[],
                            protocols=['UIGestureRecognizerDelegate'],
                            debug=True)
                          self._delegate = PythonistaGestureDelegate.new()
                      
                        @on_main_thread
                        def add_tap(self, view, action, number_of_taps_required = None, number_of_touches_required = None):
                          ''' Call `action` when a tap gesture is recognized for the `view`.
                          
                          Additional parameters:
                            
                          * `number_of_taps_required` - Set if more than one tap is required for the gesture to be recognized.
                          * `number_of_touches_required` - Set if more than one finger is required for the gesture to be recognized.
                          '''
                          recog = self._get_recog('UITapGestureRecognizer', view, self._general_action, action)
                      
                          if number_of_taps_required:
                            recog.numberOfTapsRequired = number_of_taps_required
                          if number_of_touches_required:
                            recog.numberOfTouchesRequired = number_of_touches_required
                          return recog
                      
                        @on_main_thread
                        def add_screen_edge_pan(self, view, action, edges):
                          ''' Call `action` when a pan gesture starting from the edge is recognized for the `view`. This is a continuous gesture.
                          
                          `edges` must be set to one of `Gestures.EDGE_NONE/EDGE_TOP/EDGE_LEFT/EDGE_BOTTOM/EDGE_RIGHT/EDGE_ALL`. If you want to recognize pans from different edges, you have to set up separate recognizers with separate calls to this method.
                          
                          Handler `action` receives the same gesture-specific attributes in the `data` argument as pan gestures, see `add_pan`.
                          '''
                          recog = self._get_recog('UIScreenEdgePanGestureRecognizer', view, self._pan_action, action)
                      
                          recog.edges = edges
                      
                          return recog
                      
                        def _get_recog(self, recog_name, view, internal_action, final_handler):
                          view.touch_enabled = True
                          button = ui.Button()
                          key = str(uuid.uuid4())
                          button.name = key
                          button.action = internal_action
                          self.buttons[key] = button
                          self.views[key] = view
                          recognizer = ObjCClass(recog_name).alloc().initWithTarget_action_(button, sel('invokeAction:')).autorelease()
                          self.recognizers[key] = recognizer
                          self.actions[key] = final_handler
                          ObjCInstance(view).addGestureRecognizer_(recognizer)
                          recognizer.delegate = self._delegate
                          return recognizer
                      
                        class Data():
                          def __init__(self):
                            self.recognizer = self.view = self.location = self.state = self.number_of_touches = self.scale = self.rotation = self.velocity = None
                      
                        def _context(self, button):
                          key = button.name
                          (view, recog, action) = (self.views[key], self.recognizers[key], self.actions[key])
                          data = Gestures.Data()
                          data.recognizer = recog
                          data.view = view
                          data.location = self._location(view, recog)
                          data.state = recog.state()
                          data.number_of_touches = recog.numberOfTouches()
                          #data.additional_touch_data = self.touches[recog]
                          return (data, action)
                      
                        def _location(self, view, recog):
                          loc = recog.locationInView_(ObjCInstance(view))
                          return ui.Point(loc.x, loc.y)
                      
                        def _general_action(self, sender):
                          (data, action) = self._context(sender)
                          action(data)
                      
                        def _pan_action(self, sender):
                          (data, action) = self._context(sender)
                          trans = data.recognizer.translationInView_(ObjCInstance(data.view))
                          vel = data.recognizer.velocityInView_(ObjCInstance(data.view))
                          data.translation = ui.Point(trans.x, trans.y)
                          data.velocity = ui.Point(vel.x, vel.y)
                      
                          action(data)
                      
                          action(data)
                      
                      # TESTING AND DEMONSTRATION
                      
                      if __name__ == "__main__":
                        
                        import math, random
                        
                        g = Gestures()
                        
                        def random_background(view):
                          colors = [(0.3,0.31,0.32), (0.25,0.26,0.27), (0.2,0.21,0.22), (0.15,0.16,0.17), (0.35,0.36,0.37), (0.4,0.41,0.42), (0.45,0.46,0.47), (0.5,0.51,0.52)]
                          view.background_color = random.choice(colors)
                          view.text_color = (0,0,0) if sum(view.background_color[:3]) > 1.5 else (1,1,1) # colour of font after press button
                      
                        def update_text(l, text):
                          l.text = text
                      
                        q1_count=-1
                        def generic_handler1(data):
                          random_background(data.view)
                          global q1_count
                          q1_count+=1
                          if q1_count<=len(Questions1)-1:
                            update_text(data.view,Questions1[q1_count])
                          else:
                            update_text(data.view,'done')
                      
                        q2_count=-1
                        def generic_handler2(data):
                          random_background(data.view)
                          global q2_count
                          q2_count+=1
                          if q2_count<=len(Questions2)-1:
                            update_text(data.view,Questions2[q2_count])
                          else:
                            update_text(data.view,'done')
                      
                        q3_count=-1
                        def generic_handler3(data):
                          random_background(data.view)
                          global q3_count
                          q3_count+=1
                          if q3_count<=len(Questions3)-1:
                            update_text(data.view,Questions3[q3_count])
                          else:
                            update_text(data.view,'done')
                      
                        q4_count=-1
                        def generic_handler4(data):
                          random_background(data.view)
                          global q4_count
                          q4_count+=1
                          if q4_count<=len(Questions4)-1:
                            update_text(data.view,Questions4[q4_count])
                          else:
                            update_text(data.view,'done')
                      
                        def pan_handler(data):
                          update_text(data.view, 'done')
                          random_background(data.view)
                          bg.close()
                      
                        Questions1=['What are my strengths?','What frustrates me?','What do I prefer to wear?','What does my desk look like?','When making a large purchase I prioritise:','Who inspires you;']
                        Questions2=['ohW','nehW','erehW','yhW','tahw','woH']
                        Questions3=['1st ?','2nd ?','3rd ?','4th ?','5th ?','6th ?']
                        Questions4=['Question 1','Question 2','Question 3','Question 4','Question 5','Question 6']
                      
                        bg = ui.View()
                        bg.present(style='default',hide_title_bar=True,title_bar_color=(198/255,50/255,108/255), title_color='Green')
                        disable_swipe_to_close(bg) # Use to limit access to code
                        bg.background_color=(198/255,50/255,108/255) # set background color to pink
                        edge_l = ui.Label(
                          text='Complete as quickly as possible', 
                          background_color='grey',
                          text_color='white',
                          alignment=ui.ALIGN_CENTER,
                          number_of_lines=0,
                          frame=(
                            0, 0, bg.width, 136 # position of top box (0 in, 0 down, bg.width wide, 136 high)
                        ))
                        edge_l.font=(font_list[71], 40) # font type and size
                        bg.add_subview(edge_l)
                        g.add_screen_edge_pan(edge_l, pan_handler, edges=Gestures.EDGE_RIGHT)
                      
                        v = ui.ScrollView(frame=(0, 95, bg.width, bg.height))  # where grid of boxes are placed 
                        bg.add_subview(v)
                        
                        label_count = -1
                        
                        def create_label(title):
                          global label_count
                          label_count += 1
                          label_w = 443
                          label_h = 300
                          gap = 120
                          label_w_with_gap = label_w + gap
                          label_h_with_gap = label_h + gap
                          labels_per_line = math.floor((v.width-2*gap)/(label_w+gap))
                          left_margin = (v.width - labels_per_line*label_w_with_gap + gap)/2
                          line = math.floor(label_count/labels_per_line)
                          column = label_count - line*labels_per_line
                          
                          l = ui.Label(
                            text=title, 
                            background_color=(95/255,96/255,98/255), # box colour
                            text_color=(141/255,198/255,63/255), # text colour
                            alignment=ui.ALIGN_CENTER,
                            number_of_lines=0,
                            frame=(
                              left_margin+column * label_w_with_gap,
                              gap+line * label_h_with_gap,
                              label_w, label_h
                          ))
                          l.font=(font_list[32], 40) # font type and size
                          v.add_subview(l)
                          return l
                      
                        tap_1 = create_label("What is included in your perfect night in? \n \n Nailing a DYI project")
                        tap_2 = create_label("What is included in your perfect night in? \n \n Bath, bed and a good book?")
                        tap_3 = create_label("What is included in your perfect night in? \n \n Doonah, snacks, movie and someone to cuddle?")
                        tap_4 = create_label("What is included in your perfect night in? \n \n It does'nt matter as long as the house is clean!")
                        g.add_tap(tap_1, generic_handler1)
                        g.add_tap(tap_2, generic_handler2)
                        g.add_tap(tap_3, generic_handler3)
                        g.add_tap(tap_4, generic_handler4)
                      
                      # code to export results to csv file once it is the same for as res given below
                      import csv
                      res = ['x', '2', 4.7]
                      csvfile = 'data.csv'
                      
                      with open(csvfile, "w") as output:
                          writer = csv.writer(output, lineterminator='\n')
                          for val in res:
                              writer.writerow([val])
                      
                      
                      mikael 1 Reply Last reply Reply Quote 0
                      • mikael
                        mikael @RoninSage last edited by

                        @RoninSage, some suggestions:

                        • You do not need to compile the whole list of fonts every time - you can just set the font by the name you find in the font picker ('+' above the keyboard, on the right).
                        • You do not need to include the whole code for gestures, you can just import it.
                        • Again, you do not really need gestures for the most part, just for the edge swipe to proceed. For tapping the answers I would simplify the code a lot by just using ui.Buttons, all with action set to the same handler function that distinguishes which button was tapped by the name of the center.
                        • For saving the answers, do you have a distinct need for CSV, instead of something slighly more robust?
                        1 Reply Last reply Reply Quote 0
                        • RoninSage
                          RoninSage last edited by RoninSage

                          I have created code that works and does what I want it to do, however, I feel like there is a more condensed way to do this. By creating my own keyboard I can limit the inputs that are available, I can also stop that annoying little bar coming up at the bottom of the screen.

                          Below the comment

                          # functions that define key button actions

                          I feel there is a lot of repetition that could be done more efficiently. Also, below the comment

                          # Create key buttons

                          again, there is also a lot of repetition. I am sure there is a simple iterative way to approach this, but I am at a loss as to how to do it.

                          Thanks for you help.

                          
                          import ui, itertools
                          import numpy as np
                          from objc_util import *
                          
                          # Define variables
                          # Create display, further details see theBackground.py
                          view=ui.View()
                          view.present('fullscreen', hide_title_bar=True)
                          view.background_color = ('lightgreen')
                          answers=[]
                          
                          # Counters
                          ent_count=0
                          
                          # Define functions
                          # function that allows you to define font as a number using font_list[]
                          def get_font_list():
                            UIFont = ObjCClass('UIFont')
                            return list(itertools.chain(*[UIFont.fontNamesForFamilyName_(str(x))
                                  for x in UIFont.familyNames()]))
                          font_list = get_font_list()
                          for i in range(len(font_list)):
                            font_list[i]=str(font_list[i])
                          
                          # function that adds all keys to the screen
                          def add_keyboard1(some_list):
                            for key in some_list:
                              view.add_subview(some_list[key])
                          
                          # function that removes all keys from the screen
                          def remove_keyboard1(some_list):
                            for key in range(0,len(some_list)):
                              view.remove_subview(some_list[key])
                          
                          # function to create key buttons
                          def create_btn(btn_label,btn_name,btn_x,btn_y,btn_width):
                            btn_name.bg_color = (95/255,96/255,98/255,0.8) # button colour
                            btn_name.tint_color=(141/255,198/255,63/255) # button font colour
                            btn_name.center = (btn_x+view.width*0.215, btn_y-view.height*0.1) # button position
                            btn_name.border_width = .5 # add border to button
                            btn_name.width = btn_width # button width
                            btn_name.height = view.width*0.04 # button height
                            btn_name.font = (font_list[7], 20) # button font type and size
                            btn_name.corner_radius = view.width * 0.002 # rounds button corners
                            view.add_subview(btn_name) # draw button
                          
                          # functions that define key button actions
                          def btn1_tap(sender):
                            txt_fld.text=txt_fld.text +'1'
                          def btn2_tap(sender):
                            txt_fld.text=txt_fld.text +'2'
                          def btn3_tap(sender):
                            txt_fld.text=txt_fld.text +'3'
                          def btn4_tap(sender):
                            txt_fld.text=txt_fld.text +'4'
                          def btn5_tap(sender):
                            txt_fld.text=txt_fld.text +'5'
                          def btn6_tap(sender):
                            txt_fld.text=txt_fld.text +'6'
                          def btn7_tap(sender):
                            txt_fld.text=txt_fld.text +'7'
                          def btn8_tap(sender):
                            txt_fld.text=txt_fld.text +'8'
                          def btn9_tap(sender):
                            txt_fld.text=txt_fld.text +'9'
                          def btn0_tap(sender):
                            txt_fld.text=txt_fld.text +'0'
                          def btndel_tap(sender):
                            txt_fld.text=txt_fld.text[:-1]
                          def btnq_tap(sender):
                            txt_fld.text=txt_fld.text +'q'
                          def btnw_tap(sender):
                            txt_fld.text=txt_fld.text +'w'
                          def btne_tap(sender):
                            txt_fld.text=txt_fld.text +'e'
                          def btnr_tap(sender):
                            txt_fld.text=txt_fld.text +'r'
                          def btnt_tap(sender):
                            txt_fld.text=txt_fld.text +'t'
                          def btny_tap(sender):
                            txt_fld.text=txt_fld.text +'y'
                          def btnu_tap(sender):
                            txt_fld.text=txt_fld.text +'u'
                          def btni_tap(sender):
                            txt_fld.text=txt_fld.text +'i'
                          def btno_tap(sender):
                            txt_fld.text=txt_fld.text +'o'
                          def btnp_tap(sender):
                            txt_fld.text=txt_fld.text +'p'
                          def btnsf_tap(sender):
                            txt_fld.text=txt_fld.text +'🙁'
                          def btna_tap(sender):
                            txt_fld.text=txt_fld.text +'a'
                          def btns_tap(sender):
                            txt_fld.text=txt_fld.text +'s'
                          def btnd_tap(sender):
                            txt_fld.text=txt_fld.text +'d'
                          def btnf_tap(sender):
                            txt_fld.text=txt_fld.text +'f'
                          def btng_tap(sender):
                            txt_fld.text=txt_fld.text +'g'
                          def btnh_tap(sender):
                            txt_fld.text=txt_fld.text +'h'
                          def btnj_tap(sender):
                            txt_fld.text=txt_fld.text +'j'
                          def btnk_tap(sender):
                            txt_fld.text=txt_fld.text +'k'
                          def btnl_tap(sender):
                            txt_fld.text=txt_fld.text +'l'
                          def btnhf_tap(sender):
                            txt_fld.text=txt_fld.text +'🙂'
                          def btnz_tap(sender):
                            txt_fld.text=txt_fld.text +'z'
                          def btnx_tap(sender):
                            txt_fld.text=txt_fld.text +'x'
                          def btnc_tap(sender):
                            txt_fld.text=txt_fld.text +'c'
                          def btnv_tap(sender):
                            txt_fld.text=txt_fld.text +'v'
                          def btnb_tap(sender):
                            txt_fld.text=txt_fld.text +'b'
                          def btnn_tap(sender):
                            txt_fld.text=txt_fld.text +'n'
                          def btnm_tap(sender):
                            txt_fld.text=txt_fld.text +'m'
                          def btnm_tap(sender):
                            txt_fld.text=txt_fld.text +'m'
                          def btnenter_tap(sender):
                            global ent_count
                            if len(txt_fld.text)!=0:
                              ent_count+=1
                              if ent_count<3: # after 3rd entry stops input
                                answers.append(txt_fld.text) # records all inputs
                                txt_fld.text='' # clears entry after enter is pressed
                              else:
                                answers.append(txt_fld.text) # records last input
                                view.remove_subview(txt_fld) # clears textfield
                                some_box.text='My time is a valuable thing' # changes box text
                                remove_keyboard1(all_btns) # clears all keys
                                view.close()
                          
                          # Create key buttons
                          btn1 = ui.Button(title='1')
                          create_btn('1',btn1,view.width*0.0,view.height*0.66,view.width*0.04)
                          btn1.action = btn1_tap
                          btn2 = ui.Button(title='2')
                          create_btn('2',btn2,view.width*0.05,view.height*0.66,view.width*0.04)
                          btn2.action = btn2_tap
                          btn3 = ui.Button(title='3')
                          create_btn('3',btn3,view.width*0.1,view.height*0.66,view.width*0.04)
                          btn3.action = btn3_tap
                          btn4 = ui.Button(title='4')
                          create_btn('4',btn4,view.width*0.15,view.height*0.66,view.width*0.04)
                          btn4.action = btn4_tap
                          btn5 = ui.Button(title='5')
                          create_btn('5',btn5,view.width*0.2,view.height*0.66,view.width*0.04)
                          btn5.action = btn5_tap
                          btn6 = ui.Button(title='6')
                          create_btn('6',btn6,view.width*0.25,view.height*0.66,view.width*0.04)
                          btn6.action = btn6_tap
                          btn7 = ui.Button(title='7')
                          create_btn('7',btn7,view.width*0.3,view.height*0.66,view.width*0.04)
                          btn7.action = btn7_tap
                          btn8 = ui.Button(title='8')
                          create_btn('8',btn8,view.width*0.35,view.height*0.66,view.width*0.04)
                          btn8.action = btn8_tap
                          btn9 = ui.Button(title='9')
                          create_btn('9',btn9,view.width*0.4,view.height*0.66,view.width*0.04)
                          btn9.action = btn9_tap
                          btn0 = ui.Button(title='0')
                          create_btn('0',btn0,view.width*0.45,view.height*0.66,view.width*0.04)
                          btn0.action = btn0_tap
                          btndel = ui.Button(title='delete')
                          create_btn('delete',btndel,view.width*0.505,view.height*0.66,view.width*0.09)
                          btndel.action = btndel_tap
                          btnq = ui.Button(title='q')
                          create_btn('q',btnq,view.width*0.025,view.height*0.73,view.width*0.04)
                          btnq.action = btnq_tap
                          btnw = ui.Button(title='w')
                          create_btn('w',btnw,view.width*0.075,view.height*0.73,view.width*0.04)
                          btnw.action = btnw_tap
                          btne = ui.Button(title='e')
                          create_btn('e',btne,view.width*0.125,view.height*0.73,view.width*0.04)
                          btne.action = btne_tap
                          btnr = ui.Button(title='r')
                          create_btn('r',btnr,view.width*0.175,view.height*0.73,view.width*0.04)
                          btnr.action = btnr_tap
                          btnt = ui.Button(title='t')
                          create_btn('t',btnt,view.width*0.225,view.height*0.73,view.width*0.04)
                          btnt.action = btnt_tap
                          btny = ui.Button(title='y')
                          create_btn('y',btny,view.width*0.275,view.height*0.73,view.width*0.04)
                          btny.action = btny_tap
                          btnu = ui.Button(title='u')
                          create_btn('u',btnu,view.width*0.325,view.height*0.73,view.width*0.04)
                          btnu.action = btnu_tap
                          btni = ui.Button(title='i')
                          create_btn('i',btni,view.width*0.375,view.height*0.73,view.width*0.04)
                          btni.action = btni_tap
                          btno = ui.Button(title='o')
                          create_btn('o',btno,view.width*0.425,view.height*0.73,view.width*0.04)
                          btno.action = btno_tap
                          btnp = ui.Button(title='p')
                          create_btn('p',btnp,view.width*0.475,view.height*0.73,view.width*0.04)
                          btnp.action = btnp_tap
                          btnsf = ui.Button(title='🙁')
                          create_btn('🙁',btnsf,view.width*0.525,view.height*0.73,view.width*0.04)
                          btnsf.action = btnsf_tap
                          btna = ui.Button(title='a')
                          create_btn('a',btna,view.width*0.05,view.height*0.8,view.width*0.04)
                          btna.action = btna_tap
                          btns = ui.Button(title='s')
                          create_btn('s',btns,view.width*0.1,view.height*0.8,view.width*0.04)
                          btns.action = btns_tap
                          btnd = ui.Button(title='d')
                          create_btn('d',btnd,view.width*0.15,view.height*0.8,view.width*0.04)
                          btnd.action = btnd_tap
                          btnf = ui.Button(title='f')
                          create_btn('f',btnf,view.width*0.2,view.height*0.8,view.width*0.04)
                          btnf.action = btnf_tap
                          btng = ui.Button(title='g')
                          create_btn('g',btng,view.width*0.25,view.height*0.8,view.width*0.04)
                          btng.action = btng_tap
                          btnh = ui.Button(title='h')
                          create_btn('h',btnh,view.width*0.3,view.height*0.8,view.width*0.04)
                          btnh.action = btnh_tap
                          btnj = ui.Button(title='j')
                          create_btn('j',btnj,view.width*0.35,view.height*0.8,view.width*0.04)
                          btnj.action = btnj_tap
                          btnk = ui.Button(title='k')
                          create_btn('k',btnk,view.width*0.4,view.height*0.8,view.width*0.04)
                          btnk.action = btnk_tap
                          btnl = ui.Button(title='l')
                          create_btn('l',btnl,view.width*0.45,view.height*0.8,view.width*0.04)
                          btnl.action = btnl_tap
                          btnhf = ui.Button(title='🙂')
                          create_btn('🙂',btnhf,view.width*0.5,view.height*0.8,view.width*0.04)
                          btnhf.action = btnhf_tap
                          btnz = ui.Button(title='z')
                          create_btn('z',btnz,view.width*0.075,view.height*0.87,view.width*0.04)
                          btnz.action = btnz_tap
                          btnx = ui.Button(title='x')
                          create_btn('x',btnx,view.width*0.125,view.height*0.87,view.width*0.04)
                          btnx.action = btnx_tap
                          btnc = ui.Button(title='c')
                          create_btn('c',btnc,view.width*0.175,view.height*0.87,view.width*0.04)
                          btnc.action = btnc_tap
                          btnv = ui.Button(title='v')
                          create_btn('v',btnv,view.width*0.225,view.height*0.87,view.width*0.04)
                          btnv.action = btnv_tap
                          btnb = ui.Button(title='b')
                          create_btn('b',btnb,view.width*0.275,view.height*0.87,view.width*0.04)
                          btnb.action = btnb_tap
                          btnn = ui.Button(title='n')
                          create_btn('n',btnn,view.width*0.325,view.height*0.87,view.width*0.04)
                          btnn.action = btnn_tap
                          btnm = ui.Button(title='m')
                          create_btn('m',btnm,view.width*0.375,view.height*0.87,view.width*0.04)
                          btnm.action = btnm_tap
                          btnenter = ui.Button(title='enter')
                          create_btn('enter',btnenter,view.width*0.425,view.height*0.87,view.width*0.09)
                          btnenter.action = btnenter_tap
                          
                          # List of all button names
                          all_btns=(btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8,btn9,btn0,btndel,
                          btnq,btnw,btne,btnr,btnt,btny,btnu,btni,btno,btnp,btnsf,
                          btna,btns,btnd,btnf,btng,btnh,btnj,btnk,btnl,btnhf,
                          btnz,btnx,btnc,btnv,btnb,btnn,btnm,btnenter)
                          
                          # Include non-interactive box
                          some_box = ui.Label(
                            text='This is where you can ask some questions', # box text
                            background_color=(95/255,96/255,98/255), # box colour
                            text_color='white', # box text colour
                            alignment=ui.ALIGN_CENTER, # text alignment in box
                            number_of_lines=0, # number of lines used in box
                            frame=(0, 0, view.width, 100)) # position of top box (0 in, 0 down, view.width wide, 100 high)
                          some_box.font=('HoeflerText-BlackItalic', 40) # box font type and size
                          view.add_subview(some_box) # create box
                          
                          txt_fld=ui.TextField(frame=(view.width*0.275, view.height*0.34,view.width*0.45, view.height*0.1)) # defines textfield dimensions
                          txt_fld.alignment=ui.ALIGN_CENTER # places text in center of the box
                          txt_fld.font = ('Chalkduster', 30) # change textfield font
                          txt_fld.text_color='hotpink' # text colour
                          txt_fld.enabled = False # cannot click in textfield
                          view.add_subview(txt_fld) # create textfield
                          
                          
                          cvp 3 Replies Last reply Reply Quote 0
                          • cvp
                            cvp @RoninSage last edited by

                            @RoninSage already shorter 😀

                            import ui, itertools
                            import numpy as np
                            from objc_util import *
                            
                            # Define variables
                            # Create display, further details see theBackground.py
                            view=ui.View()
                            view.present('fullscreen', hide_title_bar=True)
                            view.background_color = ('lightgreen')
                            answers=[]
                            
                            # Counters
                            ent_count=0
                            
                            # Define functions
                            # function that allows you to define font as a number using font_list[]
                            def get_font_list():
                              UIFont = ObjCClass('UIFont')
                              return list(itertools.chain(*[UIFont.fontNamesForFamilyName_(str(x))
                                    for x in UIFont.familyNames()]))
                            font_list = get_font_list()
                            for i in range(len(font_list)):
                              font_list[i]=str(font_list[i])
                            
                            # function to create key buttons
                            def create_btn(btn_label,btn_name,btn_x,btn_y,btn_width):
                              btn_name = ui.Button(title=btn_label,name=btn_name)
                              if btn_label == 'delete':
                                btn_name.action = btndel_tap
                              elif btn_label == 'enter':
                                btn_name.action = btnenter_tap
                              else:
                                btn_name.action = btn_tap
                              btn_name.bg_color = (95/255,96/255,98/255,0.8) # button colour
                              btn_name.tint_color=(141/255,198/255,63/255) # button font colour
                              btn_name.center = (btn_x+view.width*0.215, btn_y-view.height*0.1) # button position
                              btn_name.border_width = .5 # add border to button
                              btn_name.width = btn_width # button width
                              btn_name.height = view.width*0.04 # button height
                              btn_name.font = (font_list[7], 20) # button font type and size
                              btn_name.corner_radius = view.width * 0.002 # rounds button corners
                              view.add_subview(btn_name) # draw button
                            
                            # functions that define key button actions
                            def btn_tap(sender):
                              txt_fld.text=txt_fld.text + sender.title
                            
                            def btndel_tap(sender):
                              txt_fld.text=txt_fld.text[:-1]
                            def btnenter_tap(sender):
                              global ent_count
                              if len(txt_fld.text)!=0:
                                ent_count+=1
                                if ent_count<3: # after 3rd entry stops input
                                  answers.append(txt_fld.text) # records all inputs
                                  txt_fld.text='' # clears entry after enter is pressed
                                else:
                                  answers.append(txt_fld.text) # records last input
                                  view.remove_subview(txt_fld) # clears textfield
                                  some_box.text='My time is a valuable thing' # changes box text
                                  for subv in view.subviews:
                                    if type(subv) is ui.Button:
                                      view.remove_subview(subv)
                                  view.close()
                            
                            # Create key buttons
                            create_btn('1', 'btn1',view.width*0.0,view.height*0.66,view.width*0.04)
                            create_btn('2', 'btn2',view.width*0.05,view.height*0.66,view.width*0.04)
                            create_btn('3', 'btn3',view.width*0.1,view.height*0.66,view.width*0.04)
                            create_btn('4', 'btn4',view.width*0.15,view.height*0.66,view.width*0.04)
                            create_btn('5', 'btn5',view.width*0.2,view.height*0.66,view.width*0.04)
                            create_btn('6', 'btn6',view.width*0.25,view.height*0.66,view.width*0.04)
                            create_btn('7', 'btn7',view.width*0.3,view.height*0.66,view.width*0.04)
                            create_btn('8', 'btn8',view.width*0.35,view.height*0.66,view.width*0.04)
                            create_btn('9', 'btn9',view.width*0.4,view.height*0.66,view.width*0.04)
                            create_btn('0', 'btn0',view.width*0.45,view.height*0.66,view.width*0.04)
                            create_btn('delete', 'btndel',view.width*0.505,view.height*0.66,view.width*0.09)
                            create_btn('q', 'btnq',view.width*0.025,view.height*0.73,view.width*0.04)
                            create_btn('w', 'btnw',view.width*0.075,view.height*0.73,view.width*0.04)
                            create_btn('e', 'btne',view.width*0.125,view.height*0.73,view.width*0.04)
                            create_btn('r', 'btnr',view.width*0.175,view.height*0.73,view.width*0.04)
                            create_btn('t', 'btnt',view.width*0.225,view.height*0.73,view.width*0.04)
                            create_btn('y', 'btny',view.width*0.275,view.height*0.73,view.width*0.04)
                            create_btn('u', 'btnu',view.width*0.325,view.height*0.73,view.width*0.04)
                            create_btn('i', 'btni',view.width*0.375,view.height*0.73,view.width*0.04)
                            create_btn('o', 'btno',view.width*0.425,view.height*0.73,view.width*0.04)
                            create_btn('p', 'btnp',view.width*0.475,view.height*0.73,view.width*0.04)
                            create_btn('🙁', 'btnsf',view.width*0.525,view.height*0.73,view.width*0.04)
                            create_btn('a', 'btna',view.width*0.05,view.height*0.8,view.width*0.04)
                            create_btn('s', 'btns',view.width*0.1,view.height*0.8,view.width*0.04)
                            create_btn('d', 'btnd',view.width*0.15,view.height*0.8,view.width*0.04)
                            create_btn('f', 'btnf',view.width*0.2,view.height*0.8,view.width*0.04)
                            create_btn('g', 'btng',view.width*0.25,view.height*0.8,view.width*0.04)
                            create_btn('h', 'btnh',view.width*0.3,view.height*0.8,view.width*0.04)
                            create_btn('j', 'btnj',view.width*0.35,view.height*0.8,view.width*0.04)
                            create_btn('k', 'btnk',view.width*0.4,view.height*0.8,view.width*0.04)
                            create_btn('l', 'btnl',view.width*0.45,view.height*0.8,view.width*0.04)
                            create_btn('🙂', 'btnhf',view.width*0.5,view.height*0.8,view.width*0.04)
                            create_btn('z', 'btnz',view.width*0.075,view.height*0.87,view.width*0.04)
                            create_btn('x', 'btnx',view.width*0.125,view.height*0.87,view.width*0.04)
                            create_btn('c', 'btnc',view.width*0.175,view.height*0.87,view.width*0.04)
                            create_btn('v', 'btnv',view.width*0.225,view.height*0.87,view.width*0.04)
                            create_btn('b', 'btnb',view.width*0.275,view.height*0.87,view.width*0.04)
                            create_btn('n', 'btnn',view.width*0.325,view.height*0.87,view.width*0.04)
                            create_btn('m', 'btnm',view.width*0.375,view.height*0.87,view.width*0.04)
                            create_btn('enter', 'btnenter',view.width*0.425,view.height*0.87,view.width*0.09)
                            
                            # Include non-interactive box
                            some_box = ui.Label(
                              text='This is where you can ask some questions', # box text
                              background_color=(95/255,96/255,98/255), # box colour
                              text_color='white', # box text colour
                              alignment=ui.ALIGN_CENTER, # text alignment in box
                              number_of_lines=0, # number of lines used in box
                              frame=(0, 0, view.width, 100)) # position of top box (0 in, 0 down, view.width wide, 100 high)
                            some_box.font=('HoeflerText-BlackItalic', 40) # box font type and size
                            view.add_subview(some_box) # create box
                            
                            txt_fld=ui.TextField(frame=(view.width*0.275, view.height*0.34,view.width*0.45, view.height*0.1)) # defines textfield dimensions
                            txt_fld.alignment=ui.ALIGN_CENTER # places text in center of the box
                            txt_fld.font = ('Chalkduster', 30) # change textfield font
                            txt_fld.text_color='hotpink' # text colour
                            txt_fld.enabled = False # cannot click in textfield
                            view.add_subview(txt_fld) # create textfield
                            
                            
                            1 Reply Last reply Reply Quote 1
                            • cvp
                              cvp @RoninSage last edited by

                              @RoninSage still shorter

                              # Create key buttons
                              def create_row(row_labels,row_x,row_y):
                                x = row_x
                                for btn_label in row_labels:
                                  create_btn(btn_label,'btn'+btn_label, view.width*x, view.height*row_y, view.width*0.04)
                                  x = x + 0.05
                              create_row('1234567890', 0.0,0.66)
                              create_btn('delete', 'btndel',view.width*0.505,view.height*0.66,view.width*0.09)
                              create_row('qwertyuiop🙁', 0.025,0.73)
                              create_row('asdfghjkl🙂', 0.05,0.8)
                              create_row('zxcvbnm', 0.075,0.87)
                              create_btn('enter', 'btnenter',view.width*0.425,view.height*0.87,view.width*0.09)
                              
                              1 Reply Last reply Reply Quote 2
                              • cvp
                                cvp @RoninSage last edited by

                                @RoninSage Additional infos

                                • button name is not needed because we remove them by sub_view of view
                                1 Reply Last reply Reply Quote 1
                                • RoninSage
                                  RoninSage last edited by

                                  @cvp perfect, that simplified all the repetions and I still understand what is going on, thanks heaps.

                                  1 Reply Last reply Reply Quote 0
                                  • First post
                                    Last post
                                  Powered by NodeBB Forums | Contributors