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.


    Python string object as callable method

    Pythonista
    5
    13
    16006
    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.
    • Kipekeedev
      Kipekeedev last edited by Kipekeedev

      Solved it!

      the_action = getattr(self, name + '_action')
      button.action = the_action
      
      1 Reply Last reply Reply Quote 0
      • ccc
        ccc last edited by ccc

        The code above calls .add_subview() twice for each button which will put four buttons on the screen instead of just two. A minimal implementation:

        # coding: utf-8
        
        import ui, console
        
        w, h = ui.get_screen_size()
        buttons = 'Scan_View Show_View'.split()
        
        class OCRApp(ui.View):
            def __init__(self):
                self.background_color = 'orange'
                self.present()
                for i, button in enumerate(buttons):
                    self.add_subview(self.make_button(button.lower(), i))
                
            def scan_view_action(self, sender):
                console.hud_alert('scan')
                
            def show_view_action(self, sender):
                console.hud_alert('show')
            
            def make_button(self, name, i):
                button = ui.Button(title=name)
                button.action = getattr(self, name + '_action')
                button.center = w / 2, i * 60 + button.height * 2
                return button
        
        OCRApp()
        
        1 Reply Last reply Reply Quote 0
        • Kipekeedev
          Kipekeedev last edited by

          Thanks @ccc

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

            I know this is out of topic but I'm having trouble running this code. It freezes my app:

            @ui.in_background
            	def scan_document(self, sender):
            		
            		img = photos.capture_image()
            		console.show_activity()
            		if not img:
            			return
            		with io.BytesIO() as bIO:
            			img.save(bIO, 'PNG')
            			imgOut = ui.Image.from_data
            

            I don't know if you guys know a lot about the photos module but I can't find any good documentation.

            @ccc do you have a github post on it?

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

              http://omz-software.com/pythonista/docs/ios/photos.html

              https://github.com/Pythonista-Tools/Pythonista-Tools/blob/master/Graphics and Imaging.md

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

                do you have another in_background that is running? i tried your code standalone, and it works ok for me on the 1.6 beta.

                I do recall similar porblems on the 1.5, which were solved by not using in_background, but then having the logic that shows the capture phoo dialog called in a ui.delay.

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

                  I will ask the obvious , do you really need to do Background processing ? But I understand, you should be still be able to background process if possible. But sometimes linear processing is reasonable given the task. If I am off track, ignore my comments

                  Kipekeedev 1 Reply Last reply Reply Quote 0
                  • Kipekeedev
                    Kipekeedev @Phuket2 last edited by

                    @Phuket2

                    If I remove the decorator

                    @ui.in_background
                    

                    I get an error:

                    TypeError: Cannot show camera from main UI thread
                    
                    
                    1 Reply Last reply Reply Quote 0
                    • Phuket2
                      Phuket2 last edited by

                      @Kipekeedev, ok I should not be commenting because it's outside my comprehension. But, if you look at what the decorator is doing might give you a better insight to what is happening. I am not trying to be smart, but I have fell into this trap before. You have a decorator called ui.in_background somehow it has some special and magical meaning. But it doesn't. If you look at the root of what the decorator is doing ( in this case it's about threads). Again I am talking above what I know exactly, but I think my idea is correct. Hope what I have said is not misleading.

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

                        The built in dialogs (like console.input_alert, raw_input, camera input dialogs, etc) need to be run in a background thread, though in 1.5 at least, there were some cases where in_background didn't work... possibly because of the fact that everything which uses in_background shares the same queue. I think there was some tuning of priorities in 1.6 (your code worked okay for me, but perhaps we need to see the entire app)

                        Using ui.delay is a simple way to spawn a new independent thread, without having to learn about the threading module. You would do something like

                        def scan_document(self, sender):
                            def show():  
                                img = photos.capture_image()
                                console.show_activity()
                                if not img:
                                    return
                                with io.BytesIO() as bIO:
                                    img.save(bIO, 'PNG')
                                    imgOut = ui.Image.from_data
                                    # actually DO something with the image
                          ui.delay(show,0.1)
                        

                        if that still doesn't work, try first closing the view, before the ui.delay, then increase the delay time to a second or so, to give the view time to minimize. at the end of show you could represent the top level view. Again, i did not have to do any of this in 1.6, but sometimes such things were needed in 1.5.

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