New update method in beta - just curious
@omz, this is not important. I am just curious why the code below does not work. Maybe I missed something. I know it was designed to work with custom ui.Views, but it seems like this would work anyway. I don't mean to waste your time. Only answer if you have a spare min.
import ui def myupdate(): print('in Update') v = ui.load_view() v.update_interval = 1 v.update = myupdate v.present('sheet') print(v.update)
@Phuket2 I don't have the code handy to look at right now, but I think the reason this doesn't work is that
ui.Viewchecks whether it has an update method when it's created, and not just before presentation.
@Phuket2 There is a similar mechanism with the
drawmethod. You essentially get a slightly different kind of view object, depending on whether these methods are present.
If you want to add a method dynamically, you can do it as shown below. Method assignment works differently (see the code). I feel that checking for update method is a bug. Omz should provide a dummy update method.
import ui import types class CustomView(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def update(self): pass def myupdate(self): print('in Update') def button_action(sender): s = sender.superview s['view1'].update_interval = 1 s['view1'].update = types.MethodType(myupdate, s['view1']) #print(s['view1'].update) v = ui.View(frame=(0,0,600,600)) v.add_subview(ui.Button(title='update', action=button_action)) v1 = CustomView(frame=(0,300,300,300), name='view1') v.add_subview(v1) v.present('sheet')
@omz , ok. Understand. Now you mention it, I remember the issue with the draw method. I guess you have a good reason to do it like this.
@enceladus I don't really consider this a bug. Your program shows intent by having or not having a
@omz , as a side note I think you also changed the draw method at one time. I think there was a type of a bug where a bunch of structures/buffers were being setup in ui.View for use with the draw method even if it wasn't defended. I think you changed the behaviour so a ui.view would be lighter weight if draw method is not defined.
@omz, sorry to bring this up again. I can image it drives you crazy sometimes :). But anyway.....
I wanted to ask is there any real reason that any ui.View cant have its own update function. I sort of forgot about this thread and started out to make a still dismissing btn today. The crude attempt is below. When I could see it was not working the way I expected, I remembered this thread and found it. I tried to follow @enceladus example, but realised he was adding a update method to a custom class. In the below, I want my created button to look after itself. In this case just thinking about a modal case where if there is no user interaction you want the process to continue after a set timeout.
Why is it important? At first I thought, hmmm so many other ways to do this. But I think is not so clean if you would like to make a reusable ui Item for others. Then I started to think about other use cases. Eg. a textfield updating itself using requests to get a exchange rate. But the beauty would be in if it could be coded in one function using closures. Then the consumer of the "control" only needs to know some pertinent params. The control could be presented without a host container (superview) and still work.
Anyway, I am not trying to be stupid for stupid sake! I can just see some cool possibilities for ppl to create some interesting reusable ui controls that are self contained.
After all that, I have no idea if its a feasible idea or not. I mean the ability to have all your controls to be able to have its own update method (callback). Personally I would say it is feasible after the tests I did with a lot of customviews in a table all having their own update methods.
Anyway, it's just an idea. I can just see the merit in it.
import ui import types def auto_button(time_out_secs=1, *args, **kwargs): ''' Incomplete attempt at getting something other than a Custom View to have its own update event ''' btn = None def myupdate(): ''' here we might change the btns title in x secs. Could then call the btn's action. eg, might close a view that is blocked by ui.wait_modal. ''' print('In Update') btn = ui.Button(**kwargs) btn.update = types.MethodType(myupdate, btn) btn.update_interval = 1 return btn class MyClass(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.make_view() def make_view(self): btn = auto_button(title='Continue', width=100, height=32, bg_color='white', corner_radius=6, ) btn.center = self.center self.add_subview(btn) if __name__ == '__main__': f = (0, 0, 300, 400) v = MyClass(frame=f, bg_color='teal') v.present(style='sheet')
If not running the Pythonista 3 beta, you can get periodic updates with the code below.
This is not my idea, I just simplified an idea in the TimedRefreshView.py example program, written by cclauss, that I found at:
My program, 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 currently running.
I like having this functionality built into the ui.View 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): """ This class contains a method named updatex, which is periodically called. """ 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 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')