0
# Event System
1
2
Signal-slot communication system for event handling and inter-widget communication patterns.
3
4
## Capabilities
5
6
### Signal Class
7
8
pyTTkSignal provides the signal mechanism for event communication between objects.
9
10
```python { .api }
11
class pyTTkSignal:
12
def __init__(self, *types):
13
"""
14
Initialize a signal.
15
16
Parameters:
17
- types: Type hints for signal parameters (optional)
18
"""
19
20
def connect(self, slot):
21
"""
22
Connect a slot function to this signal.
23
24
Parameters:
25
- slot: Function or method to call when signal is emitted
26
"""
27
28
def disconnect(self, slot=None):
29
"""
30
Disconnect a slot from this signal.
31
32
Parameters:
33
- slot: Specific slot to disconnect, or None to disconnect all
34
"""
35
36
def emit(self, *args):
37
"""
38
Emit the signal with optional arguments.
39
40
Parameters:
41
- args: Arguments to pass to connected slots
42
"""
43
44
def isConnected(self):
45
"""Check if any slots are connected to this signal."""
46
47
def connectionCount(self):
48
"""Get the number of connected slots."""
49
50
def blockSignals(self, blocked):
51
"""Block or unblock signal emission."""
52
53
def signalsBlocked(self):
54
"""Check if signals are blocked."""
55
```
56
57
### Slot Decorator
58
59
pyTTkSlot decorator marks functions as slots for signal connection.
60
61
```python { .api }
62
def pyTTkSlot(*types):
63
"""
64
Decorator to mark a function as a slot.
65
66
Parameters:
67
- types: Expected parameter types (optional, for type checking)
68
69
Returns:
70
Decorated function that can be connected to signals
71
72
Usage:
73
@pyTTkSlot()
74
def my_slot():
75
pass
76
77
@pyTTkSlot(int, str)
78
def typed_slot(number, text):
79
pass
80
"""
81
```
82
83
### Event Classes
84
85
Event objects that carry information about user interactions and system events.
86
87
```python { .api }
88
class TTkKeyEvent:
89
def __init__(self, type, key, text="", modifiers=0):
90
"""
91
Initialize a keyboard event.
92
93
Parameters:
94
- type (int): Event type (KeyPress, KeyRelease)
95
- key (int): Key code constant
96
- text (str): Text representation of key
97
- modifiers (int): Modifier keys (Ctrl, Alt, Shift)
98
"""
99
100
def type(self):
101
"""Get the event type."""
102
103
def key(self):
104
"""Get the key code."""
105
106
def text(self):
107
"""Get the text representation."""
108
109
def modifiers(self):
110
"""Get the modifier keys."""
111
112
def matches(self, key_sequence):
113
"""Check if event matches a key sequence."""
114
115
def accept(self):
116
"""Accept the event (stops propagation)."""
117
118
def ignore(self):
119
"""Ignore the event (allows propagation)."""
120
121
def isAccepted(self):
122
"""Check if event is accepted."""
123
124
class TTkMouseEvent:
125
def __init__(self, type, pos, button, buttons, modifiers):
126
"""
127
Initialize a mouse event.
128
129
Parameters:
130
- type (int): Event type (MousePress, MouseRelease, MouseMove)
131
- pos (TTkPoint): Mouse position
132
- button (int): Button that caused the event
133
- buttons (int): All pressed buttons
134
- modifiers (int): Modifier keys
135
"""
136
137
def type(self):
138
"""Get the event type."""
139
140
def pos(self):
141
"""Get the mouse position."""
142
143
def x(self):
144
"""Get the x coordinate."""
145
146
def y(self):
147
"""Get the y coordinate."""
148
149
def button(self):
150
"""Get the button that caused the event."""
151
152
def buttons(self):
153
"""Get all pressed buttons."""
154
155
def modifiers(self):
156
"""Get the modifier keys."""
157
158
def accept(self):
159
"""Accept the event."""
160
161
def ignore(self):
162
"""Ignore the event."""
163
164
def isAccepted(self):
165
"""Check if event is accepted."""
166
```
167
168
### Timer Class
169
170
TTkTimer provides timing functionality for periodic events and delayed actions.
171
172
```python { .api }
173
class TTkTimer:
174
def __init__(self, parent=None):
175
"""Initialize a timer."""
176
177
def start(self, msec=None):
178
"""
179
Start the timer.
180
181
Parameters:
182
- msec (int): Interval in milliseconds (optional if set before)
183
"""
184
185
def stop(self):
186
"""Stop the timer."""
187
188
def setInterval(self, msec):
189
"""Set the timer interval in milliseconds."""
190
191
def interval(self):
192
"""Get the timer interval."""
193
194
def setSingleShot(self, singleShot):
195
"""Set whether timer fires only once."""
196
197
def isSingleShot(self):
198
"""Check if timer is single-shot."""
199
200
def isActive(self):
201
"""Check if timer is active."""
202
203
def remainingTime(self):
204
"""Get remaining time until next timeout."""
205
206
# Signals
207
timeout: pyTTkSignal # Emitted when timer times out
208
```
209
210
### Shortcut System
211
212
TTkShortcut provides keyboard shortcut handling for application actions.
213
214
```python { .api }
215
class TTkShortcut:
216
def __init__(self, keySequence, parent=None):
217
"""
218
Initialize a keyboard shortcut.
219
220
Parameters:
221
- keySequence (str): Key sequence (e.g., "Ctrl+S", "Alt+F4")
222
- parent: Parent widget for shortcut scope
223
"""
224
225
def setKey(self, keySequence):
226
"""Set the key sequence."""
227
228
def key(self):
229
"""Get the key sequence."""
230
231
def setEnabled(self, enabled):
232
"""Enable/disable the shortcut."""
233
234
def isEnabled(self):
235
"""Check if shortcut is enabled."""
236
237
def setContext(self, context):
238
"""Set the shortcut context scope."""
239
240
def context(self):
241
"""Get the shortcut context scope."""
242
243
def setAutoRepeat(self, autoRepeat):
244
"""Enable/disable auto-repeat."""
245
246
def autoRepeat(self):
247
"""Check if auto-repeat is enabled."""
248
249
# Signals
250
activated: pyTTkSignal # Emitted when shortcut is activated
251
activatedAmbiguously: pyTTkSignal # Emitted for ambiguous activation
252
```
253
254
## Usage Examples
255
256
### Basic Signal-Slot Connection
257
258
```python
259
import TermTk as ttk
260
261
class MyWidget(ttk.TTkWidget):
262
# Define custom signal
263
dataChanged = ttk.pyTTkSignal(str)
264
265
def __init__(self, parent=None):
266
super().__init__(parent=parent)
267
self._data = ""
268
269
def setData(self, data):
270
if self._data != data:
271
self._data = data
272
self.dataChanged.emit(data) # Emit signal
273
274
def data(self):
275
return self._data
276
277
# Usage
278
root = ttk.TTk()
279
widget = MyWidget(parent=root)
280
281
# Define slot function
282
@ttk.pyTTkSlot(str)
283
def on_data_changed(new_data):
284
print(f"Data changed to: {new_data}")
285
286
# Connect signal to slot
287
widget.dataChanged.connect(on_data_changed)
288
289
# Trigger signal
290
widget.setData("Hello World") # Prints: "Data changed to: Hello World"
291
292
root.mainloop()
293
```
294
295
### Button Click Handling
296
297
```python
298
import TermTk as ttk
299
300
root = ttk.TTk()
301
container = ttk.TTkContainer(parent=root)
302
layout = ttk.TTkVBoxLayout()
303
304
button1 = ttk.TTkButton(text="Button 1")
305
button2 = ttk.TTkButton(text="Button 2")
306
label = ttk.TTkLabel(text="No button clicked yet")
307
308
# Define slot methods
309
@ttk.pyTTkSlot()
310
def button1_clicked():
311
label.setText("Button 1 was clicked!")
312
313
@ttk.pyTTkSlot()
314
def button2_clicked():
315
label.setText("Button 2 was clicked!")
316
317
# Connect signals to slots
318
button1.clicked.connect(button1_clicked)
319
button2.clicked.connect(button2_clicked)
320
321
layout.addWidget(button1)
322
layout.addWidget(button2)
323
layout.addWidget(label)
324
325
container.setLayout(layout)
326
root.mainloop()
327
```
328
329
### Timer Example
330
331
```python
332
import TermTk as ttk
333
334
root = ttk.TTk()
335
container = ttk.TTkContainer(parent=root)
336
337
label = ttk.TTkLabel(text="Timer: 0", parent=container)
338
counter = 0
339
340
# Create timer
341
timer = ttk.TTkTimer()
342
timer.setInterval(1000) # 1 second
343
344
# Define timer slot
345
@ttk.pyTTkSlot()
346
def update_counter():
347
global counter
348
counter += 1
349
label.setText(f"Timer: {counter}")
350
351
# Connect timer to slot
352
timer.timeout.connect(update_counter)
353
354
# Start timer
355
timer.start()
356
357
root.mainloop()
358
```
359
360
### Keyboard Event Handling
361
362
```python
363
import TermTk as ttk
364
365
class KeyCaptureWidget(ttk.TTkWidget):
366
def __init__(self, parent=None):
367
super().__init__(parent=parent)
368
self.setFocusPolicy(ttk.TTkConstant.StrongFocus)
369
self._label = ttk.TTkLabel(parent=self, text="Press any key...")
370
371
def keyEvent(self, evt):
372
if evt.type() == ttk.TTkConstant.KeyPress:
373
key_name = self.get_key_name(evt.key())
374
text = f"Key pressed: {key_name}"
375
376
if evt.modifiers() & ttk.TTkConstant.ControlModifier:
377
text += " (with Ctrl)"
378
if evt.modifiers() & ttk.TTkConstant.AltModifier:
379
text += " (with Alt)"
380
if evt.modifiers() & ttk.TTkConstant.ShiftModifier:
381
text += " (with Shift)"
382
383
self._label.setText(text)
384
evt.accept()
385
else:
386
super().keyEvent(evt)
387
388
def get_key_name(self, key):
389
# Convert key code to readable name
390
key_names = {
391
ttk.TTkConstant.Key_Return: "Return",
392
ttk.TTkConstant.Key_Escape: "Escape",
393
ttk.TTkConstant.Key_Space: "Space",
394
ttk.TTkConstant.Key_Up: "Up Arrow",
395
ttk.TTkConstant.Key_Down: "Down Arrow",
396
ttk.TTkConstant.Key_Left: "Left Arrow",
397
ttk.TTkConstant.Key_Right: "Right Arrow",
398
}
399
return key_names.get(key, f"Key_{key}")
400
401
root = ttk.TTk()
402
widget = KeyCaptureWidget(parent=root)
403
widget.setFocus()
404
405
root.mainloop()
406
```
407
408
### Mouse Event Handling
409
410
```python
411
import TermTk as ttk
412
413
class ClickTracker(ttk.TTkWidget):
414
def __init__(self, parent=None):
415
super().__init__(parent=parent)
416
self._click_count = 0
417
self._label = ttk.TTkLabel(parent=self, text="Click count: 0")
418
419
def mousePressEvent(self, evt):
420
if evt.button() == ttk.TTkConstant.LeftButton:
421
self._click_count += 1
422
self._label.setText(f"Click count: {self._click_count}")
423
print(f"Left click at ({evt.x()}, {evt.y()})")
424
elif evt.button() == ttk.TTkConstant.RightButton:
425
print(f"Right click at ({evt.x()}, {evt.y()})")
426
427
evt.accept()
428
429
root = ttk.TTk()
430
tracker = ClickTracker(parent=root)
431
432
root.mainloop()
433
```
434
435
### Keyboard Shortcuts
436
437
```python
438
import TermTk as ttk
439
440
root = ttk.TTk()
441
container = ttk.TTkContainer(parent=root)
442
layout = ttk.TTkVBoxLayout()
443
444
label = ttk.TTkLabel(text="Use Ctrl+S to save, Ctrl+Q to quit")
445
text_edit = ttk.TTkTextEdit()
446
447
layout.addWidget(label)
448
layout.addWidget(text_edit)
449
container.setLayout(layout)
450
451
# Create shortcuts
452
save_shortcut = ttk.TTkShortcut("Ctrl+S", container)
453
quit_shortcut = ttk.TTkShortcut("Ctrl+Q", container)
454
455
# Define shortcut handlers
456
@ttk.pyTTkSlot()
457
def save_action():
458
print("Save action triggered!")
459
label.setText("File saved!")
460
461
@ttk.pyTTkSlot()
462
def quit_action():
463
print("Quit action triggered!")
464
root.quit()
465
466
# Connect shortcuts
467
save_shortcut.activated.connect(save_action)
468
quit_shortcut.activated.connect(quit_action)
469
470
root.mainloop()
471
```
472
473
### Signal Chaining and Disconnection
474
475
```python
476
import TermTk as ttk
477
478
root = ttk.TTk()
479
container = ttk.TTkContainer(parent=root)
480
layout = ttk.TTkVBoxLayout()
481
482
button = ttk.TTkButton(text="Click me")
483
toggle_button = ttk.TTkButton(text="Toggle Connection")
484
label = ttk.TTkLabel(text="Connection active")
485
486
@ttk.pyTTkSlot()
487
def button_clicked():
488
label.setText("Button was clicked!")
489
490
@ttk.pyTTkSlot()
491
def toggle_connection():
492
if button.clicked.isConnected():
493
button.clicked.disconnect(button_clicked)
494
toggle_button.setText("Connect")
495
label.setText("Connection disabled")
496
else:
497
button.clicked.connect(button_clicked)
498
toggle_button.setText("Disconnect")
499
label.setText("Connection active")
500
501
# Initial connection
502
button.clicked.connect(button_clicked)
503
toggle_button.clicked.connect(toggle_connection)
504
505
layout.addWidget(button)
506
layout.addWidget(toggle_button)
507
layout.addWidget(label)
508
509
container.setLayout(layout)
510
root.mainloop()
511
```