Execute a function at a later time in PyQt6 - python

Is there a minimal overhead way of calling a custom function in my main window at a later time, similar to how an event would be called later when triggered by a call to postEvent()?
While it's easy to find info on triggering predefined events ad hoc, it's not clear how to quickly set up a custom event function that can be called this way. It's also not clear to me how the default implementation of some class's event() function maps from QEvent subclass to knowing what actual function must be called to process that event.
Since the function and its initiation will be at the same level, inside the same class, I'm not really looking for a signal/slot solution. I'm hoping I don't have to resort to creating a QEvent subclass, but if this is the cleanest way, I'll do that, I just don't know how to hook everything up.

Related

Python Timer Class: Keeping Track of State?

I have a class that uses the Python Timer class. I was wondering about whether or not I have to manually keep track of the state of the Timer. Namely, I had the following questions:
What happens if start() is called on an already running Timer? Is this the same behavior as the Thread class (which is documented here)?
What happens if cancel() is called on a Timer that is not running?
For the above questions, is the behavior well defined in either case? I can't seem to find the specific details I'm looking for in the docs.

How can I maintain, atleast, some order in which callbacks connect to a signal?

When I simply use 'connect', there is no way I can specify the order in the callbacks will be called. Having connect_before and connect_after to connect before/after the default doesn't serve my purpose. I want something like connect_first and connect_last or anything else that will help me specify the order in which callbacks connect to a signal.
Something like this?
something.connect_first('my-signal', callback1)
somethingelse.connect_last('my-signal', callback2)
There is only one explicit ordering guarantee for GObject signals:
the class closure added when creating a new signal with G_SIGNAL_RUN_FIRST will be called before all callbacks added using g_signal_connect()
the class closure added when creating a new signal eith G_SIGNAL_RUN_LAST will be called after all callbacks added using g_signal_connect() and before all callbacks added using g_signal_connect_after()
This means that you can only control whether a callback is invoked before or after all other callbacks connected manually when you're creating a new signal - for obvious reasons, since you may want to provide an initial state at the start of an emission chain, or you want to ensure a stable state at the end of an emission chain.
As for the order of the callbacks added using g_signal_connect(), there is no explicit guarantee of any ordering. There's an implicit order, the order of connection, though, that won't likely ever be changed. Remember that signal handlers can install new handlers, or disconnect them, or block the signal emission, so relying on a specific order is usually an indication of a design problem in the code.

Python Threading.Timer is calling command without waiting

I have a very basic Tkinter application that I'm trying to set to automatically refresh. I am using threading.Timer to trigger a function called go at the end of which cocalls the timer to reset it to run again.
def SetTimer():
t=threading.Timer(5,go())
t.start
SetTimer()
I've spent most of my afternoon trying to resolve this but I can't seem to figure out what I'm doing wrong. Based upon the other questions I've read I understand that each instance creates a separate thread with the timer, but why isn't it waiting for the time to elapse prior to triggering the function.
Use:
t=threading.Timer(5,go)
Note the go rather than go(). The parentheses tell Python to call the function. In contrast, go is a function object. Functions are "first-class" objects in Python; they can be passed to functions just like any other object.
Python evaluates the arguments to a function before calling the function. So using go() calls the go before calling threading.Timer. The value returned by go() gets sent to Timer, which is not what you want.
Note that all Tkinter UI code should be called from a single thread. For this reason, using Tkinter's root.after method is probably a better choice for what you want to do. The after method schedules a function to be called by Tkinter's mainloop. Here are some examples using after:
Tkinter and Threads
A rotating image

python deregister weakreference callback

How to deregister a callback passed to a weakref.ref() ?
I'm implementing a signal slot module, then I need to be notified when either the object or the method is garbage collected. So I registered a callback for both, that works well. However, after one has been collected, and the signal cleaned, when the second is collected too it still calls the callback.
I can simply ignore this call but it would be much cleaner to be able to prevent it...

On thread safety in python using D-Bus asynchronous method calls

I write a python class which makes asynchronous method calls using D-Bus. When my reply_handler is called, it stores data in list. This list can be used by another class methods at the same time. Is it safe or I can use only synchronized data structures like Queue class?
If you do not modify the list outside of the callback context, then you do not necessarily need synchronization - you will just need to be aware that the list object's state is volatile.
If the list must be modified both in the callback handler as well as, say, the main execution context (or other threads, etc.), then yes you will need synchronization.
The Python synchronized Queue works naturally for message pumps - allowing you to perform actions sequentially in the order that the events come in one of your own contexts. This benefits code simplicity and readability as well since major state changes are easier to track. Callbacks generally shouldn't be too complicated anyway as the outside context in which the callbacks are called shouldn't (and probably doesn't) have to deal with exceptions raised from your code. There are also potential timing considerations as well - the callback will block the async emitter's context - so keeping the handler short and sweet is also good.

Categories