SignalProxy.py 2.13 KB
Newer Older
Luke Campagnola's avatar
Luke Campagnola committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# -*- coding: utf-8 -*-
from PyQt4 import QtCore
from ptime import time

def proxyConnect(source, signal, slot, delay=0.3):
    """Connect a signal to a slot with delay. Returns the SignalProxy
    object that was created. Be sure to store this object so it is not
    garbage-collected immediately."""
    sp = SignalProxy(source, signal, delay)
    sp.connect(sp, signal, slot)
    return sp

class SignalProxy(QtCore.QObject):
    """Object which collects rapid-fire signals and condenses them
    into a single signal. Used, for example, to prevent a SpinBox
    from generating multiple signals when the mouse wheel is rolled
    over it."""
    
    def __init__(self, source, signal, delay=0.3):
        QtCore.QObject.__init__(self)
        source.connect(source, signal, self.signal)
        self.delay = delay
        self.waitUntil = 0
        self.args = None
        self.timers = 0
        self.signal = signal
Luke Campagnola's avatar
Luke Campagnola committed
27
        self.block = False
Luke Campagnola's avatar
Luke Campagnola committed
28
29
30
31
32
33
        
    def setDelay(self, delay):
        self.delay = delay
        
    def flush(self):
        """If there is a signal queued up, send it now."""
Luke Campagnola's avatar
Luke Campagnola committed
34
        if self.args is None or self.block:
Luke Campagnola's avatar
Luke Campagnola committed
35
            return False
Luke Campagnola's avatar
Luke Campagnola committed
36
37
        if self.block:
            return
Luke Campagnola's avatar
Luke Campagnola committed
38
39
40
41
42
43
44
        self.emit(self.signal, *self.args)
        self.args = None
        return True
        
        
    def signal(self, *args):
        """Received signal, queue to be forwarded later."""
Luke Campagnola's avatar
Luke Campagnola committed
45
46
        if self.block:
            return
Luke Campagnola's avatar
Luke Campagnola committed
47
48
49
50
51
52
53
        self.waitUntil = time() + self.delay
        self.args = args
        self.timers += 1
        QtCore.QTimer.singleShot((self.delay*1000)+1, self.tryEmit)
        
    def tryEmit(self):
        """Emit signal if it has been long enougn since receiving the last signal."""
Luke Campagnola's avatar
Luke Campagnola committed
54
        if self.args is None or self.block:
Luke Campagnola's avatar
Luke Campagnola committed
55
56
57
58
59
60
61
62
63
64
65
66
            return False
        self.timers -= 1
        t = time()
        if t >= self.waitUntil:
            return self.flush()
        else:
            if self.timers == 0:
                self.timers += 1
                QtCore.QTimer.singleShot((self.waitUntil - t) * 1000, self.tryEmit)
        return True
                
        
Luke Campagnola's avatar
Luke Campagnola committed
67
68
    def disconnect(self):
        self.block = True
Luke Campagnola's avatar
Luke Campagnola committed
69