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.
    • techteej
      techteej last edited by

      You can't set a button name as an action. You need to set each individual button action.

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

        @techteej

        Would this work?

        def scan_view_action(self,sender):
            pass
        
        def make_button(self,name):
            the_action = name + '_action'
            button.action = the_action
        

        Or is there any convenient way to do this to keep it DRY?

        1 Reply Last reply Reply Quote 0
        • 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