pylablib.core.gui.qt.thread package

Submodules

pylablib.core.gui.qt.thread.callsync module

class pylablib.core.gui.qt.thread.callsync.QCallResultSynchronizer(skippable=True)[source]

Bases: pylablib.core.gui.qt.thread.synchronizing.QThreadNotifier

get_progress()[source]

Get the progress of the call execution.

Can be "waiting" (call is not done executing), "done" (call done successfully), "fail" (call failed, probably due to thread being stopped), "skip" (call was skipped), or "exception" (call raised an exception).

skipped()[source]

Check if the call was skipped

failed()[source]

Check if the call failed

get_value_sync(timeout=None, default=None, error_on_fail=True, error_on_skip=True, pass_exception=True)[source]

Wait (with the given timeout) for the value passed by the notifier

If error_on_fail==True and the controlled thread notifies of a fail (usually, if it’s stopped before it executed the call), raise qt.thread.threadprop.NoControllerThreadError; otherwise, return default. If error_on_skip==True and the call was skipped (e.g., due to full call queue), raise qt.thread.threadprop.SkippedCallError; otherwise, return default. If pass_exception==True and the returned value represents exception, re-raise it in the caller thread; otherwise, return default.

class pylablib.core.gui.qt.thread.callsync.QDummyResultSynchronizer[source]

Bases: object

Dummy result synchronizer for call which don’t require result synchronization (e.g., signals)

notify(value)[source]
class pylablib.core.gui.qt.thread.callsync.QScheduledCall(func, args=None, kwargs=None, result_synchronizer=None)[source]

Bases: object

Object representing a scheduled remote call.

Parameters:
  • func – callable to be invoked in the destination thread
  • args – arguments to be passed to func
  • kwargs – keyword arguments to be passed to func
  • result_synchronizer – result synchronizer object; can be None (create new QCallResultSynchronizer), "async" (no result synchronization), or a QCallResultSynchronizer object.
class TCallback(func, pass_result, call_on_fail)

Bases: tuple

call_on_fail
func
pass_result
add_callback(callback, pass_result=True, call_on_fail=False, position=None)[source]

Set the callback to be executed after the main call is done.

Callback is not provided with any arguments. If pass_result==True, pass function result to the callback (or None if call failed); otherwise, pass no arguments. If callback_on_fail==True, call it even if the original call raised an exception. position specifies callback position in the call list (by default, end of the list).

fail()[source]

Notify that the call is failed (invoked by the destination thread)

skip()[source]

Notify that the call is skipped (invoked by the destination thread)

class pylablib.core.gui.qt.thread.callsync.TDefaultCallInfo(call_time)

Bases: tuple

call_time
class pylablib.core.gui.qt.thread.callsync.QScheduler(call_info_argname=None)[source]

Bases: object

Generic call scheduler.

Two methods are used by the external scheduling routines: build_call() to create a QScheduledCall with appropriate parameters, and schedule(), which takes a call and schedules it. The schedule() method should return True if the scheduling was successfull (at least, for now), and False otherwise.

Parameters:call_info_argname – if not None, supplies a name of a keyword argument via which call info (generated by build_call_info()) is passed on function call
build_call_info()[source]

Build call info tuple which can be passed to scheduled calls

build_call(func, args=None, kwargs=None, callback=None, pass_result=True, callback_on_fail=True, sync_result=True)[source]

Build QScheduledCall for subsequent scheduling.

Parameters:
  • func – function to be called
  • args – arguments to be passed to func
  • kwargs – keyword arguments to be passed to func
  • callback – optional callback to be called when func is done
  • pass_result (bool) – if True, pass func result as a single argument to the callback; otherwise, give no arguments
  • callback_on_fail (bool) – if True, execute the callback on call fail or skip (if it requires an argument, None is supplied); otherwise, only execute it if the call was successfull
  • sync_result – if True, the call has a default result synchronizer; otherwise, no synchronization is made.
schedule(call)[source]

Schedule the call

clear()[source]

Clear the scheduler

class pylablib.core.gui.qt.thread.callsync.QDirectCallScheduler(call_info_argname=None)[source]

Bases: pylablib.core.gui.qt.thread.callsync.QScheduler

Simplest call scheduler: directly executes the calls on scheduling

Parameters:call_info_argname – if not None, supplies a name of a keyword argument via which call info (generated by QScheduler.build_call_info()) is passed on function call
build_call(func, args=None, kwargs=None, callback=None, pass_result=True, callback_on_fail=True, sync_result=False)[source]

Build QScheduledCall for subsequent scheduling.

Parameters:
  • func – function to be called
  • args – arguments to be passed to func
  • kwargs – keyword arguments to be passed to func
  • callback – optional callback to be called when func is done
  • pass_result (bool) – if True, pass func result as a single argument to the callback; otherwise, give no arguments
  • callback_on_fail (bool) – if True, execute the callback on call fail or skip (if it requires an argument, None is supplied); otherwise, only execute it if the call was successfull
  • sync_result – if True, the call has a default result synchronizer; otherwise, no synchronization is made.
schedule(call)[source]

Schedule the call

class pylablib.core.gui.qt.thread.callsync.QQueueScheduler(on_full_queue='current', call_info_argname=None)[source]

Bases: pylablib.core.gui.qt.thread.callsync.QScheduler

Call scheduler with a builtin call queue.

Supports placing the calls and retrieving them (from the destination thread). Has ability to skip some calls if, e.g., the queue is too full. Whether the call should be skipped is determined by can_schedule() (should be overloaded in subclasses). Used as a default command scheduler.

Parameters:
  • on_full_queue – action to be taken if the call can’t be scheduled (i.e., can_schedule() returns False); can be "skip_current" (skip the call which is being scheduled), "skip_newest" (skip the most recent call; place the current) "skip_oldest" (skip the oldest call in the queue; place the current), "wait" (wait until the call can be scheduled, which is checked after every call removal from the queue; place the call), or "call" (execute the call directly in the calling thread; should be used with caution).
  • call_info_argname – if not None, supplies a name of a keyword argument via which call info (generated by QScheduler.build_call_info()) is passed on function call
Methods to overload:
can_schedule: check if the call can be scheduled call_added: called when a new call has been added to the queue call_popped: called when a call has been removed from the queue (either for execution, or for skipping)
can_schedule(call)[source]

Check if the call can be scheduled

call_added(call)[source]

Called whenever call has been added to the queue

call_popped(call, head)[source]

Called whenever call has been removed from the queue

head determines whether the call has been removed from the queue head, or from the queue tail.

schedule(call)[source]

Schedule a call

pop_call()[source]

Pop the call from the queue head.

If the queue is empty, return None

has_calls()[source]

Check if there are queued calls

clear(close=True)[source]

Clear the call queue.

If close==True, mark the queue as closed (any attempt to schedule more calls fails automatically) and fail all calls in the queue; otherwise, skip all calls currently in the queue.

class pylablib.core.gui.qt.thread.callsync.QQueueLengthLimitScheduler(max_len=1, on_full_queue='skip_current', call_info_argname=None)[source]

Bases: pylablib.core.gui.qt.thread.callsync.QQueueScheduler

Queued call scheduler with a length limit.

Parameters:
  • max_len – maximal queue length; non-positive values are interpreted as no limit
  • on_full_queue – action to be taken if the call can’t be scheduled (the queue is full); can be "skip_current" (skip the call which is being scheduled), "skip_newest" (skip the most recent call; place the current) "skip_oldest" (skip the oldest call in the queue; place the current), "wait" (wait until the queue has space; place the call), or "call" (execute the call directly in the calling thread; should be used with caution).
  • call_info_argname – if not None, supplies a name of a keyword argument via which call info (generated by QScheduler.build_call_info()) is passed on function call
change_max_len(max_len)[source]

Change maximal length of the call queue (doesn’t affect already scheduled calls)

get_current_len()[source]

Get current number of calls in the queue

can_schedule(call)[source]

Check if the call can be scheduled

class pylablib.core.gui.qt.thread.callsync.QQueueSizeLimitScheduler(max_size=1, size_calc=None, on_full_queue='skip_current', call_info_argname=None)[source]

Bases: pylablib.core.gui.qt.thread.callsync.QQueueScheduler

Queued call scheduler with a generic size limit; similar to QQueueLengthLimitScheduler, but more flexible and can implement more restrictions (e.g., queue length and arguments RAM size).

Parameters:
  • max_size – maximal total size of the arguments; can be either a single number, or a tuple (if several different size metrics are involved); non-positive values are interpreted as no limit
  • size_calc – function that takes a single argument (call to be placed) and returns its size; can be either a single number, or a tuple (if several different size metrics are involved); by default, simply returns 1, which makes the scheduler behavior identical to QQueueLengthLimitScheduler
  • on_full_queue – action to be taken if the call can’t be scheduled (the queue is full); can be "skip_current" (skip the call which is being scheduled), "skip_newest" (skip the most recent call; place the current) "skip_oldest" (skip the oldest call in the queue; place the current), "wait" (wait until the queue has space; place the call), or "call" (execute the call directly in the calling thread; should be used with caution).
  • call_info_argname – if not None, supplies a name of a keyword argument via which call info (generated by QScheduler.build_call_info()) is passed on function call
change_max_size(max_size)[source]

Change size restrictions

get_current_size()[source]

Get current size metrics

call_added(call)[source]

Called whenever call has been added to the queue

call_popped(call, head)[source]

Called whenever call has been removed from the queue

head determines whether the call has been removed from the queue head, or from the queue tail.

can_schedule(call)[source]

Check if the call can be scheduled

class pylablib.core.gui.qt.thread.callsync.QThreadCallScheduler(thread=None, tag=None, priority=0, call_info_argname=None)[source]

Bases: pylablib.core.gui.qt.thread.callsync.QScheduler

Call scheduler via thread calls (QThreadController.call_in_thread_callback())

Parameters:
  • thread – destination thread (by default, thread which creates the scheduler)
  • tag – if supplied, send the call in a message with the given tag; otherwise, use the interrupt call (generally, higher priority method).
  • priority – message priority (only when tag is not None)
  • call_info_argname – if not None, supplies a name of a keyword argument via which call info (generated by QScheduler.build_call_info()) is passed on function call
schedule(call)[source]

Schedule the call

class pylablib.core.gui.qt.thread.callsync.QSignalThreadCallScheduler(thread=None, limit_queue=1, tag=None, priority=0, call_info_argname=None)[source]

Bases: pylablib.core.gui.qt.thread.callsync.QThreadCallScheduler

Extended call scheduler via thread calls, which can limit number of queued calls.

Parameters:
  • thread – destination thread (by default, thread which creates the scheduler)
  • limit_queue – call queue limit (non-positive numbers are interpreted as no limit)
  • tag – if supplied, send the call in a message with the given tag; otherwise, use the interrupt call (generally, higher priority method).
  • priority – message priority (only when tag is not None)
  • call_info_argname – if not None, supplies a name of a keyword argument via which call info (generated by QScheduler.build_call_info()) is passed on function call
schedule(call)[source]

Schedule the call

pylablib.core.gui.qt.thread.controller module

pylablib.core.gui.qt.thread.controller.exint(error_msg_template='{}:')[source]

Context that intercepts exceptions and stops the execution in a controlled manner (quitting the main thread)

pylablib.core.gui.qt.thread.controller.exsafe(func)[source]

Decorator that intercepts exceptions raised by func and stops the execution in a controlled manner (quitting the main thread)

pylablib.core.gui.qt.thread.controller.exsafeSlot(*slargs, **slkwargs)[source]

Wrapper around PyQt5.QtCore.pyqtSlot which intercepts exceptions and stops the execution in a controlled manner

class pylablib.core.gui.qt.thread.controller.QThreadControllerThread(controller)[source]

Bases: sphinx.ext.autodoc.importer._MockObject

finalized

Used by autodoc_mock_imports.

run()[source]
quit_sync()[source]
pylablib.core.gui.qt.thread.controller.remote_call(func)[source]

Decorator that turns a controller method into a remote call (call from a different thread is passed synchronously)

pylablib.core.gui.qt.thread.controller.call_in_thread(thread_name)[source]

Decorator that turns any function into a remote call in a thread with a given name (call from a different thread is passed synchronously)

pylablib.core.gui.qt.thread.controller.call_in_gui_thread(func)

Decorator that turns any function into a remote call in a GUI thread (call from a different thread is passed synchronously)

pylablib.core.gui.qt.thread.controller.gui_thread_method(func)[source]

Decorator for an object’s method that checks if the object’s gui_thread_safe attribute is true, in which case the call is routed to the GUI thread

class pylablib.core.gui.qt.thread.controller.QThreadController(name=None, kind='loop', signal_pool=None)[source]

Bases: sphinx.ext.autodoc.importer._MockObject

Generic Qt thread controller.

Responsible for all inter-thread synchronization. There is one controller per thread, and

Parameters:
  • name (str) – thread name (by default, generate a new unique name); this name can be used to obtain thread controller via get_controller()
  • kind (str) – thread kind; can be "loop" (thread is running in the Qt message loop; behavior is implemented in process_message() and remote calls), "run" (thread executes run() method and quits after it is complete), or "main" (can only be created in the main GUI thread)
  • signal_poolSignalPool for this thread (by default, use the default common pool)
Methods to overload:
on_start: executed on the thread startup (between synchronization points "start" and "run") on_finish: executed on thread cleanup (attempts to execute in any case, including exceptions) run: executed once per thread; thread is stopped afterwards (only if kind=="run") process_message: function that takes 2 arguments (tag and value) of the message and processes it; returns True if the message has been processed and False otherwise (in which case it is stored and can be recovered via wait_for_message()/pop_message()); by default, always return False process_interrupt: function that tales 2 arguments (tag and value) of the interrupt message (message with a tag starting with "interrupt.") and processes it; by default, assumes that any value with tag "execute" is a function and executes it
Signals:
started: emitted on thread start (after on_start() is executed) finished: emitted on thread finish (before on_finish() is executed)
started

Used by autodoc_mock_imports.

finished

Used by autodoc_mock_imports.

wait_for_message(tag, timeout=None)[source]

Wait for a single message with a given tag.

Return value of a received message with this tag. If timeout is passed, raise threadprop.TimeoutThreadError.

new_messages_number(tag)[source]

Get the number of queued messages with a given tag.

pop_message(tag)[source]

Pop the latest message with the given tag.

Select the message with the highest priority, and among those the oldest one. If no messages are available, raise threadprop.NoMessageThreadError.

wait_for_sync(tag, uid, timeout=None)[source]

Wait for synchronization signal with the given tag and UID.

This method is rarely invoked directly, and is usually used by synchronizers code. If timeout is passed, raise threadprop.TimeoutThreadError.

wait_for_any_message(timeout=None)[source]

Wait for any message (including synchronization messages or pokes).

If timeout is passed, raise threadprop.TimeoutThreadError.

wait_until(check, timeout=None)[source]

Wait until a given condition is true.

Condition is given by the check function, which is called after every new received message and should return True if the condition is met. If timeout is passed, raise threadprop.TimeoutThreadError.

check_messages()[source]

Receive new messages.

Runs the underlying message loop to process newly received message and signals (and place them in corresponding queues if necessary). This method is rarely invoked, and only should be used periodically during long computations to not ‘freeze’ the thread.

sleep(timeout)[source]

Sleep for a given time (in seconds).

Unlike time.sleep(), constantly checks the event loop for new messages (e.g., if stop or interrupt commands are issued).

process_interrupt(tag, value)[source]
process_message(tag, value)[source]

Process a new message.

If the function returns False, the message is put in the corresponding queue. Otherwise, the the message is considered to be already, and it gets ‘absorbed’.

on_start()[source]

Method invoked on the start of the thread.

on_finish()[source]

Method invoked in the end of the thread.

Called regardless of the stopping reason (normal finishing, exception, application finishing).

run()[source]

Method called to run the main thread code (only for "run" thread kind).

subscribe(callback, srcs='any', dsts=None, tags=None, filt=None, priority=0, limit_queue=1, add_call_info=False, id=None)[source]

Subscribe synchronous callback to a signal.

See SignalPool.subscribe() for details. By default, the subscribed destination is the thread’s name.

subscribe_nonsync(callback, srcs='any', dsts=None, tags=None, filt=None, priority=0, scheduler=None, id=None)[source]

Subscribe asynchronous callback to a signal.

See SignalPool.subscribe_nonsync() for details. By default, the subscribed destination is the thread’s name.

unsubscribe(id)[source]

Unsubscribe from a subscription with a given ID.

send_signal(dst='any', tag=None, value=None, src=None)[source]

Send a signal to the signal pool.

See SignalPool.signal() for details. By default, the signal source is the thread’s name.

set_variable(name, value, notify=False, notify_tag='changed/*')[source]

Set thread variable.

Can be called in any thread (controlled or external). If notify==True, send a signal with the given notify_tag (where "*" symbol is replaced by the variable name).

set_func_variable(name, func, use_lock=True)[source]

Set a ‘function’ variable.

Acts as a thread variable to the external user, but instead of reading a stored value, it executed a function instead. Note, that the function is executed in the caller thread (i.e., the thread which tries to access the variable), so use of synchronization methods (commands, signals, locks) is highly advised.

If use_lock==True, then the function call will be wrapped into the usual variable lock, i.e., it won’t run concurrently with other variable access.

send_message(tag, value, priority=0)[source]

Send a message to the thread with a given tag, value and priority

send_sync(tag, uid)[source]

Send a synchronization signal with the given tag and UID.

This method is rarely invoked directly, and is usually used by synchronizers code.

get_variable(name, default=None, copy_branch=True, missing_error=False)[source]

Get thread variable.

Can be called in any thread (controlled or external). If missing_error==False and no variable exists, return default; otherwise, raise and error. If copy_branch==True and the variable is a Dictionary branch, return its copy to ensure that it stays unaffected on possible further variable assignments.

wait_for_variable(name, pred, timeout=None)[source]

Wait until thread variable with the given name satisfies the given condition.

pred is a function which takes one argument (variable value) and returns whether the condition is satisfied.

start()[source]

Start the thread.

request_stop()[source]

Request thread stop (send a stop command).

stop(code=0)[source]

Stop the thread.

If called from the thread, stop immediately by raising a qt.thread.threadprop.InterruptExceptionStop exception. Otherwise, schedule thread stop. If the thread kind is "main", stop the whole application with the given exit code. Otherwise, stop the thread.

poke()[source]

Send a dummy message to the thread.

A cheap way to notify the thread that something happened (useful for, e.g., making thread leave wait_for_any_message() method).

running()[source]

Check if the thread is running.

is_controlled()[source]

Check if this controller corresponds to the current thread.

notify_exec(point)[source]

Mark the given execution point as passed.

Automatically invoked points include "start" (thread starting), "run" (thread setup and ready to run), and "stop" (thread finished), but can be extended for arbitrary points. Any given point can be notified only once, the repeated notification causes error.

sync_exec(point, timeout=None, counter=1)[source]

Wait for the given execution point.

Automatically invoked points include "start" (thread starting), "run" (thread setup and ready to run), and "stop" (thread finished). If timeout is passed, raise threadprop.TimeoutThreadError. counter specifies the minimal number of pre-requisite notify_exec() calls to finish the waiting (by default, a single call is enough). Return actual number of notifier calls up to date.

add_stop_notifier(func, call_if_stopped=True)[source]

Add stop notifier: a function which is called when the thread is about to be stopped (left the main message loop).

The function is called in the controlled thread close to its shutdown, so it should be short, non-blocking, and thread-safe. If the thread is already stopped and call_if_stopped==True, call func immediately (from the caller’s thread). Return True if the thread is still running and the notifier is added, and False otherwise.

remove_stop_notifier(func)[source]

Remove the stop notifier from this controller.

Return True if the notifier was in this thread and is now removed, and False otherwise.

is_in_controlled()[source]

Check if the thread execution this code is controlled by this controller

call_in_thread_callback(func, args=None, kwargs=None, callback=None, tag=None, priority=0)[source]

Call a function in this thread with the given arguments.

If callback is supplied, call it with the result as a single argument (call happens in the controller thread). If tag is supplied, send the call in a message with the given tag; otherwise, use the interrupt call (generally, higher priority method).

call_in_thread_sync(func, args=None, kwargs=None, sync=True, callback=None, timeout=None, default_result=None, pass_exception=True, tag=None, priority=0, error_on_stopped=True, same_thread_shortcut=True)[source]

Call a function in this thread with the given arguments.

If sync==True, calling thread is blocked until the controlled thread executes the function, and the function result is returned (in essence, the fact that the function executes in a different thread is transparent). Otherwise, exit call immediately, and return a synchronizer object (QCallResultSynchronizer), which can be used to check if the call is done (method is_done) and obtain the result (method QCallResultSynchronizer.get_value_sync()). If callback is not None, call it after the function is successfully executed (from the target thread), with a single parameter being function result. If pass_exception==True and func raises and exception, re-raise it in the caller thread (applies only if sync==True). If tag is supplied, send the call in a message with the given tag and priority; otherwise, use the interrupt call (generally, higher priority method). If error_on_stopped==True and the controlled thread is stopped before it executed the call, raise qt.thread.threadprop.NoControllerThreadError; otherwise, return default_result. If same_thread_shortcut==True (default), the call is synchronous, and the caller thread is the same as the controlled thread, call the function directly.

class pylablib.core.gui.qt.thread.controller.QMultiRepeatingThreadController(name=None, signal_pool=None)[source]

Bases: pylablib.core.gui.qt.thread.controller.QThreadController

Thread which allows to set up and run jobs and batch jobs with a certain time period, and execute commands in the meantime.

Mostly serves as a base to a much more flexible QTaskThread class; should rarely be considered directly.

Parameters:
  • name (str) – thread name (by default, generate a new unique name)
  • signal_poolSignalPool for this thread (by default, use the default common pool)
Methods to overload:
on_start: executed on the thread startup (between synchronization points "start" and "run") on_finish: executed on thread cleanup (attempts to execute in any case, including exceptions) check_commands: executed once a scheduling cycle to check for new commands / events and execute them
add_job(name, job, period, initial_call=True)[source]

Add a recurrent job which is called every period seconds.

The job starts running automatically when the main thread loop start executing. If initial_call==True, call job once immediately after adding.

change_job_period(name, period)[source]

Change the period of the job name

remove_job(name)[source]

Change the job name from the roster

add_batch_job(name, job, cleanup=None, min_runtime=0)[source]

Add a batch job which is executed once, but with continuations.

After this call the job is just created, but is not running. To start it, call start_batch_job(). If specified, cleanup is a finalizing function which is called both when the job terminates normally, and when it is forcibly stopped (including thread termination). min_runtime specifies minimal expected runtime of a job; if a job executes faster than this time, it is repeated again unless at least min_runtime seconds passed; useful for high-throughput jobs, as it reduces overhead from the job scheduling mechanism (repeating within min_runtime time window is fast)

Unlike the usual recurrent jobs, here job is a generator (usually defined by a function with yield statement). When the job is running, the generator is periodically called until it raises StopIteration exception, which signifies that the job is finished. From generator function point of view, after the job is started, the function is executed once normally, but every time yield statement is encountered, the execution is suspended for period seconds (specified in start_batch_job()).

change_batch_job_params(name, job=None, cleanup=None, min_runtime=None, stop=False, restart=False)[source]

Change parameters (main body, cleanup function, and minimal runtime) of the batch job.

The parameters are the same as for add_batch_job(). If any of them are None, don’t change them. If stop==True, stop the job before changing the parameters; otherwise the job is continued with the previous parameters (including cleanup) until it is stopped and restarted. If restart==True, restart the job after changing the parameteres.

start_batch_job(name, period, *args, **kwargs)[source]

Start the batch job with the given name.

period specifies suspension period. Optional arguments are passed to the job and the cleanup functions.

batch_job_running(name)[source]

Check if a given batch job running

stop_batch_job(name, error_on_stopped=False)[source]

Stop a given batch job.

If error_on_stopped==True and the job is not currently running, raise an error. Otherwise, do nothing.

check_commands()[source]

Check for commands to execute.

Called once every scheduling cycle: after any recurrent or batch job, but at least every self._new_jobs_check_period seconds (by default 20ms).

run()[source]

Main scheduling loop

on_finish()[source]

Method invoked in the end of the thread.

Called regardless of the stopping reason (normal finishing, exception, application finishing).

class pylablib.core.gui.qt.thread.controller.QTaskThread(name=None, setupargs=None, setupkwargs=None, signal_pool=None)[source]

Bases: pylablib.core.gui.qt.thread.controller.QMultiRepeatingThreadController

Thread which allows to set up and run jobs and batch jobs with a certain time period, and execute commands in the meantime.

Extension of QMultiRepeatingThreadController with more powerful command scheduling and more user-friendly interface.

Parameters:
  • name (str) – thread name (by default, generate a new unique name)
  • setupargs – args supplied to setup_task method
  • setupkwargs – keyword args supplied to setup_task method
  • signal_poolSignalPool for this thread (by default, use the default common pool)
c

command accessor, which makes calls more function-like; ctl.c.comm(*args,**kwarg) is equivalent to ctl.call_command("comm",args,kwargs)

q

query accessor, which makes calls more function-like; ctl.q.comm(*args,**kwarg) is equivalent to ctl.call_query("comm",args,kwargs)

qs

query accessor which is made ‘exception-safe’ via exsafe() wrapper (i.e., safe to directly connect to slots) ctl.qi.comm(*args,**kwarg) is equivalent to with exint(): ctl.call_query("comm",args,kwargs)

qi

query accessor which ignores and silences any exceptions (including missing /stopped controller) useful for sending queries during thread finalizing / application shutdown, when it’s not guaranteed that the query recipient is running (commands already ignore any errors, unless their results are specifically requested)

m

method accessor; directly calles the method corresponding to the command; ctl.m.comm(*args,**kwarg) is equivalent to ctl.call_command("comm",*args,**kwargs), which is often also equivalent to ctl.comm(*args,**kwargs); for most practical purposes it’s the same as directly invoking the class method, but it makes intent more explicit (as command methods are usually not called directly from other threads), and it doesn’t invoke warning about calling method instead of query from another thread.

Methods to overload:
setup_task: executed on the thread startup (between synchronization points "start" and "run") finalize_task: executed on thread cleanup (attempts to execute in any case, including exceptions) process_signal: process a directed signal (signal with dst equal to this thread name); by default, does nothing
setup_task(*args, **kwargs)[source]

Setup the thread (called before the main task loop)

process_signal(src, tag, value)[source]

Process a named signal (with dst equal to the thread name) from the signal pool

finalize_task()[source]

Finalize the thread (always called on thread termination, regardless of the reason)

update_status(kind, status, text=None, notify=True)[source]

Update device status represented in thread variables.

kind is the status kind and status is its value. Status variable name is "status/"+kind. If text is not None, it specifies new status text stored in "status/"+kind+"_text". If notify==True, send a signal about the status change.

on_start()[source]

Method invoked on the start of the thread.

on_finish()[source]

Method invoked in the end of the thread.

Called regardless of the stopping reason (normal finishing, exception, application finishing).

add_command(name, command=None, scheduler=None, limit_queue=None, on_full_queue='skip_current', priority=0)[source]

Add a new command to the command set (by default same set applies both to commands and queries).

Parameters:
  • command – command function; is None, look for the method with the given name.
  • scheduler – a command scheduler; by default, it is a QQueueLengthLimitScheduler, which maintains a call queue with the given length limit and full queue behavior
  • limit_queue – command call queue limit; None means no limit
  • on_full_queue – call queue overflow behavior; can be "skip_current" (skip the call which is being scheduled), "skip_newest" (skip the most recent call, place the current), "skip_oldest" (skip the oldest call in the queue, place the current), "wait" (wait until queue has at least one free spot, place the call), or "call" (execute the call directly in the calling thread; should be used with caution).
  • priority – command priority; higher-priority signals and commands are always executed before the lower-priority ones.
check_commands()[source]

Check for commands to execute.

Called once every scheduling cycle: after any recurrent or batch job, but at least every self._new_jobs_check_period seconds (by default 20ms).

subscribe_commsync(callback, srcs='any', dsts=None, tags=None, filt=None, priority=0, scheduler=None, limit_queue=1, on_full_queue='skip_current', add_call_info=False, id=None)[source]

Subscribe callback to a signal which is synchronized with commands and jobs execution.

Unlike the standard QThreadController.subscribe() method, the subscribed callback will only be executed between jobs or commands, not during one of these.

Parameters:
  • callback – callback function, which takes 3 arguments: signal source, signal tag, signal value.
  • srcs (str or [str]) – signal source name or list of source names to filter the subscription; can be "any" (any source) or "all" (only signals specifically having "all" as a source).
  • dsts (str or [str]) – signal destination name or list of destination names to filter the subscription; can be "any" (any destination) or "all" (only source specifically having "all" as a destination).
  • tags – signal tag or list of tags to filter the subscription (any tag by default).
  • filt (callable) – additional filter function which takes 4 arguments: signal source, signal destination, signal tag, signal value, and checks whether signal passes the requirements.
  • priority (int) – subscribed signal priority; higher-priority signals and commands are always executed before the lower-priority ones.
  • limit_queue (int) – limits the maximal number of scheduled calls 0 or negative value means no limit (not recommended, as it can unrestrictedly bloat the queue)
  • on_full_queue – action to be taken if the call can’t be scheduled (i.e., QQueueScheduler.can_schedule() returns False); can be "skip_current" (skip the call which is being scheduled), "skip_newest" (skip the most recent call; place the current) "skip_oldest" (skip the oldest call in the queue; place the current), "wait" (wait until the call can be scheduled, which is checked after every call removal from the queue; place the call), or "call" (execute the call directly in the calling thread; should be used with caution).
  • add_call_info (bool) – if True, add a fourth argument containing a call information (tuple with a single element, a timestamps of the call).
  • id (int) – subscription ID (by default, generate a new unique name).
unsubscribe(id)[source]

Unsubscribe from a subscription with a given ID.

call_command_direct(name, args=None, kwargs=None)[source]

Invoke a command directly and immediately in the current thread.

call_command(name, args=None, kwargs=None, callback=None)[source]

Invoke command call with the given name and arguments

If callback is not None, call it after the command is successfully executed (from the target thread), with a single parameter being the command result. Return QCallResultSynchronizer object which can be used to wait for and read the command result.

call_query(name, args=None, kwargs=None, timeout=None, ignore_errors=False)[source]

Invoke query call with the given name and arguments, and return the result.

Unlike call_command(), wait until the call is done before returning. If ignore_errors==True, ignore all possible problems with the call (controller stopped, call raised an exception, call was skipped) and return None instead.

class CommandAccess(parent, sync, direct=False, timeout=None, safe=False, ignore_errors=False)[source]

Bases: object

Accessor object designed to simplify command and query syntax.

Automatically created by the thread, so doesn’t need to be invoked externally.

pylablib.core.gui.qt.thread.controller.get_controller(name=None, wait=True, timeout=None, sync=None)[source]

Find a controller with a given name.

If name is not supplied, yield current controller instead. If the controller is not present and wait==True, wait (with the given timeout) until the controller is running; otherwise, raise error if the controller is not running. If sync is not None, synchronize to the thread sync point (usually, "run") before returning.

pylablib.core.gui.qt.thread.controller.get_gui_controller(wait=False, timeout=None, create_if_missing=True)[source]

Get GUI thread controller.

If the controller is not present and wait==True, wait (with the given timeout) until the controller is running. If the controller is still not present and create_if_missing==True, initialize the standard GUI controller.

pylablib.core.gui.qt.thread.controller.stop_controller(name, code=0, sync=True, require_controller=False)[source]

Stop a controller with a given name.

code specifies controller exit code (only applies to the main thread controller). If require_controller==True and the controller is not present, raise and error; otherwise, do nothing. If sync==True, wait until the controller is stopped.

pylablib.core.gui.qt.thread.controller.stop_all_controllers(sync=True, concurrent=True, stop_self=True)[source]

Stop all running threads.

If sync==True, wait until the all of the controller are stopped. If sync==True and concurrent==True stop threads in concurrent manner (first issue stop messages to all of them, then wait until all are stopped). If sync==True and concurrent==False stop threads in consecutive manner (wait for each thread to stop before stopping the next one). If stop_self==True stop current thread after stopping all other threads.

pylablib.core.gui.qt.thread.controller.stop_app()[source]

Initialize stopping the application.

Do this either by stopping the GUI controller (if it exists), or by stopping all controllers.

pylablib.core.gui.qt.thread.mthread module

pylablib.core.gui.qt.thread.mthread.get_app()[source]

Get current application instance.

pylablib.core.gui.qt.thread.mthread.is_gui_running()[source]

Check if GUI is running.

pylablib.core.gui.qt.thread.mthread.is_gui_thread()[source]

Check if the current thread is the one running the GUI loop.

pylablib.core.gui.qt.thread.mthread.is_gui_controlled_thread()[source]

Check if the current thread is controlled by a GUI controller.

class pylablib.core.gui.qt.thread.mthread.CallerObject[source]

Bases: sphinx.ext.autodoc.importer._MockObject

Auxiliary object for making remote calls in the GUI thread.

call_signal

Used by autodoc_mock_imports.

on_call(func)[source]
on_app_stop()[source]
call_after(func)[source]
pylablib.core.gui.qt.thread.mthread.setup_call_after()[source]

Setup the call_after() functionality.

Needs to be called once in the GUI thread.

pylablib.core.gui.qt.thread.mthread.call_after(func, *args, **kwargs)[source]

Call the function func with the given arguments in a GUI thread.

Return immediately. If synchronization is needed, use call_in_gui_thread(). Analogue of wx.CallAfter.

pylablib.core.gui.qt.thread.mthread.call_in_gui_thread(func, args=None, kwargs=None, to_return='result', note=None, on_stopped='error')[source]

Call the function func with the given arguments in a GUI thread.

to_return specifies the return value parameters:
  • "none": execute immediately, return nothing, no synchronization is performed;
  • "syncher": execute immediately, return a synchronizer object (ValueSynchronizer),
    which can be used to check if the execution is done and to obtain the result.
  • "result": pause until the function has been executed, return the result. Mostly equivalent to a simple function call.

If note is not None, it specific a callback function to be called after the execution is done, or (if it’s a string), a message tag which is sent after the execution is done.

pylablib.core.gui.qt.thread.mthread.gui_func(to_return='result', note=None, on_stopped='error')[source]

Decorator for a function which makes it execute through a call_in_gui_thread() call.

Effectively, makes a GUI-realted function thread-safe (can be called from any thread, but the execution is done in the GUI thread).

pylablib.core.gui.qt.thread.mthread.gui_func_sync(func)
class pylablib.core.gui.qt.thread.mthread.GUIThreadController(name='gui', setup=None, cleanup=None)[source]

Bases: pylablib.core.mthread.controller.IThreadController

Thread controller optimized for a GUI thread (uses GUI message loop).

Parameters:
  • name (str) – thread name (can be used to, e.g., get the controller from a different thread).
  • setup (callable) – if not None, function to be called when the thread is starting.
  • cleanup (callable) – if not None, function to be called when the thread is stopped (regardless of the stopping reason).

Any thread creation and synchronization should be done after the controller has started, hence, it should be put into the setup function.

static get_current()[source]
check_messages(tags=None, filt=None, on_broken='error')[source]
add_message(msg, sync=True, on_broken='error', request_message_check='none')[source]

Add the message to the queue.

If sync is True, do the synchronization (wait for receiving and scheduling) after sending the message. on_broken decides what happens if thethread is stopped or hasn’t started yet (see threadprop.on_error()).

Called from any thread.

add_new_message(tag, value=None, priority=0, schedule_sync='wait', receive_sync='none', sync=True, timeout=None, on_broken='error', request_message_check='auto')[source]

Create a new message, add it to the thread’s queue, and return it.

If sync is True, do the synchronization (wait for receiving and scheduling) after sending the message. on_broken decides what happens if thethread is stopped or hasn’t started yet (see threadprop.on_error()).

Called from any thread.

run()[source]

Body of the thread.

Automatically called by the controller; to be overridden in subclasses.

finalize()[source]

Finalize the thread execution (regardless of the stopping reason).

Automatically called by the controller; to be overridden in subclasses.

start(setup=None)[source]

Start the controller.

if as_dependent is True, the new thread becomes dependent on the caller thread (it stops when the caller thread stops). if as_deamon is True, the new thread becomes a daemon (if only daemon threads are running, they get stopped).

pylablib.core.gui.qt.thread.signal_pool module

class pylablib.core.gui.qt.thread.signal_pool.TSignal(src, tag, value)

Bases: tuple

src
tag
value
class pylablib.core.gui.qt.thread.signal_pool.SignalPool[source]

Bases: object

Signal dispatcher (somewhat similar in functionality to Qt signals).

Manages dispatching signals between sources and destinations (callback functions). Each signal has defined source, destination (both can also be "all" or "any", see methods descriptions for details), tag and value. Any thread can send a signal or subscribe for a signal with given filters (source, destination, tag, additional filters). If a signal is emitted, it is checked against filters for all subscribers, and the passing ones are then called.

subscribe_nonsync(callback, srcs='any', dsts='any', tags=None, filt=None, priority=0, scheduler=None, id=None)[source]

Subscribe asynchronous callback to a signal.

If signal is sent, callback is called from the sending thread (not subscribed thread). Therefore, should be used with care. In Qt, analogous to making signal connection with a direct call.

Parameters:
  • callback – callback function, which takes 3 arguments: signal source, signal tag, signal value.
  • src (str or [str]) – signal source or list of sources (controller names) to filter the subscription; can be "any" (any source) or "all" (only signals specifically having "all" as a source).
  • src – signal destination or list of destinations (controller names) to filter the subscription; can be "any" (any destination) or "all" (only source specifically having "all" as a destination).
  • tags – signal tag or list of tags to filter the subscription (any tag by default).
  • filt (callable) – additional filter function which takes 4 arguments: signal source, signal destination, signal tag, signal value, and checks whether signal passes the requirements.
  • priority (int) – subscription priority (higher priority subscribers are called first).
  • scheduler – if defined, signal call gets scheduled using this scheduler instead of being called directly (which is the default behavior)
  • id (int) – subscription ID (by default, generate a new unique name).
Returns:

subscription ID, which can be used to unsubscribe later.

subscribe(callback, srcs='any', dsts='any', tags=None, filt=None, priority=0, limit_queue=1, dest_controller=None, call_tag=None, add_call_info=False, id=None)[source]

Subscribe synchronous callback to a signal.

If signal is sent, callback is called from the dest_controller thread (by default, thread which is calling this function) via the thread call mechanism (QThreadController.call_in_thread_callback()). In Qt, analogous to making signal connection with a queued call.

Parameters:
  • callback – callback function, which takes 3 arguments: signal source, signal tag, signal value.
  • srcs (str or [str]) – signal source name or list of source names to filter the subscription; can be "any" (any source) or "all" (only signals specifically having "all" as a source).
  • dsts (str or [str]) – signal destination name or list of destination names to filter the subscription; can be "any" (any destination) or "all" (only source specifically having "all" as a destination).
  • tags – signal tag or list of tags to filter the subscription (any tag by default).
  • filt (callable) – additional filter function which takes 4 arguments: signal source, signal destination, signal tag, signal value, and checks whether signal passes the requirements.
  • priority (int) – subscription priority (higher priority subscribers are called first).
  • limit_queue (int) – limits the maximal number of scheduled calls (if the signal is sent while at least limit_queue callbacks are already in queue to be executed, ignore it) 0 or negative value means no limit (not recommended, as it can unrestrictedly bloat the queue)
  • call_tag (str or None) – tag used for the synchronized call; by default, use the interrupt call (which is the default of call_in_thread).
  • add_call_info (bool) – if True, add a fourth argument containing a call information (tuple with a single element, a timestamps of the call).
  • id (int) – subscription ID (by default, generate a new unique name).
Returns:

subscription ID, which can be used to unsubscribe later.

unsubscribe(id)[source]

Unsubscribe from a subscription with a given ID.

signal(src, dst='any', tag=None, value=None)[source]

Send a signal.

Parameters:
  • src (str) – signal source; can be a name, "all" (will pass all subscribers’ source filters), or "any" (will only be passed to subscribers specifically subscribed to signal with "any" source).
  • dst (str) – signal destination; can be a name, "all" (will pass all subscribers’ destination filters), or "any" (will only be passed to subscribers specifically subscribed to signal with "any" destination).
  • tag (str) – signal tag.
  • value – signal value.

pylablib.core.gui.qt.thread.synchronizing module

class pylablib.core.gui.qt.thread.synchronizing.QThreadNotifier(skippable=True)[source]

Bases: pylablib.core.mthread.notifier.ISkippableNotifier

Wait-notify thread synchronizer for controlled Qt threads based on notifier.ISkippableNotifier.

Like notifier.ISkippableNotifier, the main functions are ISkippableNotifier.wait() (wait in a message loop until notified or until timeout expires) and ISkippableNotifier.notify() (notify the waiting thread). Both of these can only be called once and will raise and error otherwise. Along with notifying a variable can be passed, which can be accessed using get_value() and get_value_sync().

Parameters:skippable (bool) – if True, allows for skippable wait events (if ISkippableNotifier.notify() is called before ISkippableNotifier.wait(), neither methods are actually called).
get_value()[source]

Get the value passed by the notifier (doesn’t check if it has been passed already)

get_value_sync(timeout=None)[source]

Wait (with the given timeout) for the value passed by the notifier

class pylablib.core.gui.qt.thread.synchronizing.QMultiThreadNotifier[source]

Bases: object

Wait-notify thread synchronizer that can be used for multiple threads and called multiple times.

Performs similar function to conditional variables. The synchronizer has an internal counter which is incread by 1 every time it is notified. The wait functions have an option to wait until the counter reaches the specific counter value (usually, 1 above the last wait call).

wait(state=1, timeout=None)[source]

Wait until notifier counter is equal to at least state

Return current counter state plus 1, which is the next smallest value resulting in waiting.

wait_until(condition, timeout=None)[source]

Wait until condition is met.

condition is a function which is called (in the waiting thread) every time the synchronizer is notified. If it return non-False, the waiting is complete and its result is returned.

notify()[source]

Notify all waiting threads

pylablib.core.gui.qt.thread.threadprop module

exception pylablib.core.gui.qt.thread.threadprop.ThreadError(msg=None)[source]

Bases: RuntimeError

Generic thread error.

exception pylablib.core.gui.qt.thread.threadprop.NoControllerThreadError(msg=None)[source]

Bases: pylablib.core.gui.qt.thread.threadprop.ThreadError

Thread error for a case of thread having no conrollers.

exception pylablib.core.gui.qt.thread.threadprop.DuplicateControllerThreadError(msg=None)[source]

Bases: pylablib.core.gui.qt.thread.threadprop.ThreadError

Thread error for a case of a duplicate thread controller.

exception pylablib.core.gui.qt.thread.threadprop.TimeoutThreadError(msg=None)[source]

Bases: pylablib.core.gui.qt.thread.threadprop.ThreadError

Thread error for a case of a wait timeout.

exception pylablib.core.gui.qt.thread.threadprop.NoMessageThreadError(msg=None)[source]

Bases: pylablib.core.gui.qt.thread.threadprop.ThreadError

Thread error for a case of trying to get a non-existant message.

exception pylablib.core.gui.qt.thread.threadprop.SkippedCallError(msg=None)[source]

Bases: pylablib.core.gui.qt.thread.threadprop.ThreadError

Thread error for a case of external call getting skipped (unscheduled).

exception pylablib.core.gui.qt.thread.threadprop.InterruptException(msg=None)[source]

Bases: Exception

Generic interrupt exception (raised by some function to signal interrupts from other threads).

exception pylablib.core.gui.qt.thread.threadprop.InterruptExceptionStop(msg=None)[source]

Bases: pylablib.core.gui.qt.thread.threadprop.InterruptException

Interrupt exception denoting thread stop request.

pylablib.core.gui.qt.thread.threadprop.get_app()[source]

Get current application instance.

pylablib.core.gui.qt.thread.threadprop.get_gui_thread()[source]

Get main (GUI) thread, or None if Application is not running.

pylablib.core.gui.qt.thread.threadprop.is_gui_running()[source]

Check if GUI is running.

pylablib.core.gui.qt.thread.threadprop.is_gui_thread()[source]

Check if the current thread is the one running the GUI loop.

pylablib.core.gui.qt.thread.threadprop.current_controller(require_controller=True)[source]

Get controller of the current thread.

If the current thread has not controller and `require_controller==True`, raise an error; otherwise, return None.

Module contents