Handling real-time updates
Most modern UIs also update based on some external events, not just user actions. To support that, we need to extend our model and include an event mechanism that will flow events from python to the WinForms layer. In the previous section, when we invoked Application.Run() on the view, we’ve effectively handed control over the the windows message loop(http://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows) and any further updates must be performed from a python thread that should have been started before the Application.Run() has been called. Furthermore, WinForms are not thread-safe, therefore one must use Invoke or BeginInvoke to update the UI.
import clr
from System.Reflection import Assembly
from System.Windows.Forms import Application
from System.Windows.Forms import MethodInvoker
Assembly.LoadFile(r'c:\work\simple_form\SimpleForm.DLL')
import SimpleForm
import threading
import random
import time
class View(SimpleForm.SimpleForm):
@property
def text(self):
return self.textBox.Text
@text.setter
def text(self, value):
def updater():
self.textBox.Text = str(value)
self.BeginInvoke(MethodInvoker(updater))
def bind_handler(self, handler):
self.btn_sayit.Click += handler
class Presenter:
def __init__(self, view, model, event_generator):
self.view = view
self.model = model
self.event_generator = event_generator
self.bind_events()
def bind_events(self):
self.view.bind_handler(self.sayit_handler)
self.event_generator.bind_handler(self.update_text)
def update_text(self, new_text):
self.view.text = new_text
def sayit_handler(self, sender, args):
self.model.perform_sayit(self.view.text)
class Model:
def perform_sayit(self, text):
print("Got Text: %s" % text)
class EventGenerator(threading.Thread):
_handler = None
def bind_handler(self, handler):
self._handler = handler
def run(self):
while True:
if self._handler:
self._handler( random.random() )
time.sleep( 1 )
generator = EventGenerator()
generator.setDaemon(True)
generator.start()
p = Presenter(View(), Model(), generator)
Application.Run(p.view)
|
No comments:
Post a Comment