I have a question regarding the traitsui tutorial by Gael Varoquaux. In code snippet 7 he makes a CaptureThread class for producing a thread for taking images from a camera. He also make a Camera class.
class TextDisplay(HasTraits):
string = String()
view = View(Item('string', show_label=False, springy=True, style='custom'))
class CaptureThread(Thread):
def run(self):
#self.display is set outside the class definition by the caller
self.display.string = 'Camera started\n' + self.display.string
n_img = 0
while not self.wants_abort:
sleep(0.5)
n_img += 1
self.display.string = ' %d image captured\n' % n_img \
+ self.display.string
self.display.string = 'Camera stopped\n' + self.display.string
class Camera(HasTraits):
start_stop_capture = Button()
display = Instance(TextDisplay)
capture_thread = Instance(CaptureThread)
view = View( Item('start_stop_capture', show_label=False))
def _start_stop_capture_fired(self):
if self.capture_thread and self.capture_thread.isAlive():
self.capture_thread.wants_abort = True
else:
self.capture_thread = CaptureThread()
self.capture_thread.wants_abort = False
self.capture_thread.display = self.display
self.capture_thread.start()
I have two questions about this code:
1) Why in the Camera class definition does he make capture_thread a Trait, by calling Instance(CaptureThread)? CaptureThread is just a thread class, why should we make a trait instance out of it?
2) In the CaptureThread class he makes use of a field self.display.string and of self.wants_abort. These two fields are not passed in via a constructor method, rather they are assigned outside of the class definition by the Camera class. Is this the best practise? Since if the user of the CaptureThread forgot to set these two fields, then an error would occur. Are there some sensible guidelines to know when I can assign thing like that, or I should use a constructor to assign them?
I hope that these questions make sense, and that this is the right place to ask them! Thanks, labjunky
capture_thread = Instance(CaptureThread)doesn't make an instance ofCaptureThread. It is more of a declaration that gets consumed by theCameraclass when the class gets created. It tells thatCameraclass that it will have an attribute namedcapture_threadthat should be an instance ofCaptureThreadorNoneand will default toNone. This default lets the "test ifself.capture_threadis initialized, otherwise create it" logic in_start_stop_capture_fired()a little cleaner, at least to some people's tastes.For
threading.Threadsubclasses, yes, it's one idiomatic way to do it, though not the only one.Threadalready has a specific__init__implementation, and you could override it to do something else, but it is understandable that the author would avoid doing so in this case.This is not the idiomatic way to initialize
HasTraitssubclasses which is indeed to use keyword arguments.