Reputation: 831
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
Upvotes: 1
Views: 254
Reputation: 13430
capture_thread = Instance(CaptureThread)
doesn't make an instance of CaptureThread
. It is more of a declaration that gets consumed by the Camera
class when the class gets created. It tells that Camera
class that it will have an attribute named capture_thread
that should be an instance of CaptureThread
or None
and will default to None
. This default lets the "test if self.capture_thread
is initialized, otherwise create it" logic in _start_stop_capture_fired()
a little cleaner, at least to some people's tastes.
For threading.Thread
subclasses, yes, it's one idiomatic way to do it, though not the only one. Thread
already 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 HasTraits
subclasses which is indeed to use keyword arguments.
Upvotes: 2