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.


    Polling from a ui.View (built in timers in ui.Views)

    Pythonista
    timer ui.view
    6
    40
    25252
    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.
    • mikael
      mikael @omz last edited by

      @omz, I am not technoway. Sorry for jumping in; I have been waiting for the beta invite in order to test the polling functionality.

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

        @mikael Ah, I'm sorry, I'll send a new invite to the email address you're using for this forum.

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

          @omz, got it, thanks!

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

            @omz, some feedback on the update feature, all of it positive:

            • Very stable and consistent. Stops when the view is closed, no threading hassles.
            • Very intuitive to use. Changing the update_interval to 0.0 stops updates, and positive numbers start them again.

            With my limited Threading skills, I was unable to create stable and predictable UI animations with either ui.delay or custom Threads. With update, no issues. This is my vote for moving the feature out of beta.

            1 Reply Last reply Reply Quote 2
            • omz
              omz last edited by

              @mikael Thanks for your feedback! I appreciate it.

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

                @Phuket2, thank you for taking this up.

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

                  @mikael , thanks all to @omz. When i had to do something threaded or in a loop, I never felt confident about it. I have a small thing now where its just a label update to show when something expires. It's so nice and simple with update mechanism.
                  My experience has been same as yours. Very stable.

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

                    @mikael , I mentioned something in the github issues area about ui.TableViewCell. @omz said just add your view to the cell. I had forgotten @JonB had helped me with this a long time ago. Anyway, i was playing around. The below maybe is not pretty. But I find it interesting and it shows off a few things. Also how well update works. Well i think it does anyway.

                    EDIT: to see the cool stuff I think you have to tap a cell and also scroll. You can see how things are getting suspended when you scroll. I think its nice

                    import ui
                    from random import choice
                    
                    
                    _color_list = ['purple', 'orange', 'deeppink', 'lightblue', 'cornflowerblue'
                                   'red', 'yellow', 'green', 'pink', 'navy', 'teal', 'olive',
                                   'lime', 'maroon', 'aqua', 'silver', 'fuchsia',
                                   ]
                    
                    
                    class MyCustomCell(ui.View):
                        def __init__(self, parent, *args, **kwargs):
                            super().__init__(*args, **kwargs)
                            self.cell = parent
                            self.tableview = None
                            self.blink_count = 0
                            self.lb = None
                            self.frame = self.cell.frame
                            self.flex = 'wh'
                            self.width -= 10
                            self.x = 5
                            self.height -= 10
                            self.y = 5
                            self.alpha = .5
                            self.corner_radius = 6
                    
                            # this allows the touch events to pass through my subview
                            self.touch_enabled = False
                    
                            self.update_interval = .2
                    
                            lb = ui.Label(frame=(0, 0, 24, 24), bg_color='black',
                                          text_color='white', alignment=ui.ALIGN_CENTER)
                    
                            lb.center = self.center
                            lb.corner_radius = 12
                    
                            self.lb = lb
                            self.add_subview(lb)
                    
                        def rect_onscreen(self):
                            '''
                            Have to write this method.  Would be nice if this was built in.
                            like ui.TableView.is_visible for example.  I know its just some rect
                            math, but it means you need to save extra references etc.. to calculate
                            it yourself.
                            '''
                            return True
                    
                        def update(self):
                            if not self.tableview:
                                return
                    
                            # I did not implement this yet. A little drunk and having a party today.
                            # but gives the idea...
                            if not self.rect_onscreen():
                                return
                    
                            if self.blink_count == 98:
                                self.update_interval = 0
                    
                            self.blink_count += 1
                            self.lb.text = str(self.blink_count)
                            self.bg_color = choice(_color_list)
                    
                    
                    def create_cell():
                        '''
                        Create and return a ui.TableViewCell. We add a custom ui.View to
                        the TableViewCell.content_view. This means our view is sitting on top
                        of the normal TableViewCell contents. All is still there.
                        Also create an attr in the cell at runtime that points to our custom class.
                        I guess this can be done many ways.  I choose this way for the example.
                        To me its at least clear for access.
                        '''
                        cell = ui.TableViewCell()
                        myc = MyCustomCell(cell)
                        cell.content_view.add_subview(myc)
                        cell.my_cell = myc
                        return cell
                    
                    
                    class MyDataSource(object):
                    
                        def __init__(self, data):
                            self.data = data
                            self.sel_item = 0
                            self.cells = [create_cell()
                                          for _ in range(len(self.data))]
                    
                        def tableview_number_of_rows(self, tableview, section):
                            # Return the number of rows in the section
                            return len(self.data)
                    
                        def tableview_cell_for_row(self, tableview, section, row):
                            # Create and return a cell for the given section/row
                            cell = self.cells[row]
                            cell.text_label.text = self.data[row]
                    
                            # just showing we can access our class from the my_cell attr
                            # we added. In this case I want to save the tableview attr
                            cell.my_cell.tableview = tableview
                            return cell
                    
                        def tableview_did_select(self, tableview, section, row):
                            # Called when a row was selected.
                            self.select_row(row)
                    
                        def select_row(self, sel_row):
                            for cell in self.cells:
                                cell.accessory_type = ""
                    
                            self.cells[sel_row].accessory_type = 'checkmark'
                            self.sel_item = sel_row
                    
                    
                    def get_table(items):
                        tbl = ui.TableView(frame=(0, 0, 300, 400))
                        tbl.data_source = MyDataSource(items)
                        tbl.delegate = tbl.data_source
                        return tbl
                    
                    
                    if __name__ == '__main__':
                        v = get_table(['Ian', 'Fred', 'John', 'Paul', 'Gaew', 'Pete',
                                       'Ole', 'Christian', 'Mary', 'Susan', 'Juile'
                                       'Simone', 'Terry', 'Michael', 'James'])
                        v.present(style='sheet', animated=False)
                    
                    mikael 1 Reply Last reply Reply Quote 0
                    • mikael
                      mikael @Phuket2 last edited by

                      @Phuket2, could you make it a gist?

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

                        @mikael , sure here is the gist. I forgot it can be hard to copy from here. Anyway, its a stupid example

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

                          @Phuket2, it sure works, although your animations are so subtle, I hardly noticed them at first. :-)

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

                            @mikael , lol. But it's stress testing :)

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

                              Have to say, you can click around, drag around etc.. everything keeps working which is great

                              1 Reply Last reply Reply Quote 0
                              • technoway
                                technoway @omz last edited by technoway

                                @omz - Hi. I also found using update_interval and update very straightforward and it worked without a hitch.

                                Sorry I did not give any feedback before now. I didn't know where to give feedback. Now, I see that this is the place to do that.

                                I had no issues with programming the beta version at all.

                                There is a bug in an example program, which also exist in the release (non-beta) version. The Calculator.py example in the "Widget" folder gives "v is not defined" - "v" should be "widget_view". When that change is made, the program works. (The other Calculator.py program in the "User Interface" folder has no issues).

                                I noticed the download in the App store has been changed to be named, "Pythonista 3", I presume to match the version of Python used. The main application screen still has "Pythonista 2 Documents".

                                Thanks for creating such a great App.

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

                                  @technoway Thanks for your feedback.

                                  Pythonista 3 is the current version. The folder "Pythonista 2 Documents" exists to access files from the old version. It only shows up if you had version 2 installed at some point, and you can turn it off in the settings.

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

                                    If not running the Pythonista 3 beta, someone can also have an update method be periodically called as shown below.

                                    This is not my idea, I just simplified an idea in the TimedRefreshView.py example program that I found at:

                                    https://github.com/cclauss/Pythonista_ui/blob/master/TimedRefreshView.py
                                    

                                    This program below, named say_random_digit.py, says a random digit from 0 to 9 every 5 seconds.

                                    I had to change the data member "self.update_interval" to "self.updatex_interval" and the method "update" to "updatex" so as not to conflict with the names in the Pythonista 3 beta, which I am running.

                                    I like having this functionality built into the class much more than having to implement it, so I look forward to the beta becoming the released product.

                                    import ui
                                    import threading
                                    import speech
                                    from random import randint
                                    
                                    class TimedUpdateView(ui.View):
                                    
                                        def __init__(self):
                                            self.updatex_interval = 5
                                            self.update_after_delay()
                                    
                                        def updatex(self):
                                            """ Say a random digit from 0 to 9 every 5 seconds. """
                                            speech.say('%s' % (randint(0, 9)))
                                    
                                        def update_after_delay(self):
                                            """ This just method calls the updatex method periodically """
                                            self.updatex()
                                            update_thread = threading.Timer(self.updatex_interval,
                                                                            self.update_after_delay).run()
                                    
                                    if __name__ == "__main__":
                                        v = TimedUpdateView()
                                        v.present('sheet')
                                    
                                    1 Reply Last reply Reply Quote 0
                                    • technoway
                                      technoway last edited by technoway

                                      I just updated my iPhone 6s to IOS 12.0.1, and the 'update' method is not longer called in my ui.View derived class.

                                      I wonder if anyone else has encountered this?

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

                                        @technoway, 12.0.1 on iPhone X, still works as previously.

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

                                          You sure you have update_interval set?

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

                                            Thank you mikael and JonB for the help.

                                            @JonB said:

                                            You sure you have update_interval set?

                                            Yes. I have:

                                            self.update_interval = 1.0
                                            

                                            in my derived class's __init__ method.

                                            It likely I did something to break code that was working, but I don't see anything wrong. I'll debug my application - if this works for others, then I'm sure I introduced a bug somewhere. It's odd though, because I only made two very small changes and then updated the OS.

                                            Next time, before I upgrade the OS, I'll test before to make sure it's the OS that breaks code, and not my code changes.

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