Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcfbd77c

Browse files
committed
Major changes:
- Enhanced API documentation with more detailed explanations and examples- Improved worker thread pattern implementation with better lifecycle management- Added thread-safe property support with notification signals- Enhanced error handling and logging throughout codebase- Implemented graceful shutdown utilities- Added connection type AUTO_CONNECTION for dynamic connection behaviorTechnical improvements:- Refactored signal/slot connection logic for better thread safety- Enhanced worker thread pattern with proper thread affinity handling- Added context variables for emission tracking- Improved test coverage and organization- Updated code formatting and linting configurations
1 parent1e17998 commitcfbd77c

35 files changed

+3290
-859
lines changed

‎README.md‎

Lines changed: 94 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,39 @@
11
#TSignal
22

3-
Are you looking for a signal/slotpattern in Python without Qt dependencies? TSignalprovidesa lightweight,thread-safe,andasyncio-compatibleimplementation that gives you allthepower of Qt's signal/slot pattern without the heavyweight dependencies.Perfect for:
3+
TSignal is a lightweight, pure-Python signal/slotlibrary thatprovides thread-safe, asyncio-compatibleevent handling inspired bytheQt signal/slot pattern—but without the heavyweightQtdependencies.It enables clean decoupling of components, seamless thread-to-thread communication, and flexible asynchronous/synchronous slot handling.
44

5-
- Async applications needing event handling
6-
- Thread communication in Python applications
7-
- Event-driven architectures
8-
- Decoupled component communication
5+
##Key Features
6+
7+
-**Pure Python**: No Qt or external GUI frameworks needed.
8+
-**Async/Await Friendly**: Slots can be synchronous or asynchronous, and integrate seamlessly with asyncio.
9+
-**Thread-Safe**: Signal emissions and slot executions are automatically managed for thread safety.
10+
-**Flexible Connection Types**: Direct or queued connections, automatically chosen based on the caller and callee threads.
11+
-**Worker Thread Pattern**: Simplify background task execution with a built-in worker pattern that provides an event loop and task queue in a dedicated thread.
12+
-**Familiar Decorators**: Inspired by Qt’s pattern,`@t_with_signals`,`@t_signal`, and`@t_slot` let you define signals and slots declaratively.
913

1014
##Why TSignal?
11-
- 🚀 Pure Python implementation - no Qt or external dependencies required
12-
- ⚡ Async/await support out of the box
13-
- 🔒 Thread-safe signal emission and slot execution
14-
- 🎯 Simple, decorator-based API similar to Qt
15-
- 🔄 Automatic thread handling for cross-thread signals
15+
16+
Modern Python applications often rely on asynchronous operations and multi-threading. Traditional event frameworks either require large external dependencies or lack seamless async/thread support. TSignal provides:
17+
18+
- A minimal, dependency-free solution for event-driven architectures.
19+
- Smooth integration with asyncio for modern async Python code.
20+
- Automatic thread-affinity handling so cross-thread signals "just work."
21+
- Decorator-based API that’s intuitive and maintainable.
22+
23+
##Installation
24+
25+
TSignal requires Python 3.10 or higher.
26+
27+
```bash
28+
git clone https://github.com/TSignalDev/tsignal-python.git
29+
cd tsignal-python
30+
pip install -e.
31+
```
32+
33+
For development (includes tests and linting tools):
34+
```
35+
pip install -e ".[dev]
36+
```
1637

1738
##Quick Start
1839

@@ -46,7 +67,7 @@ counter.count_changed.connect(display, display.on_count_changed)
4667
counter.increment()# Will print: "Count is now: 1"
4768
```
4869

49-
###Async Example
70+
###Asynchronous Slot Example
5071
```python
5172
@t_with_signals
5273
classAsyncDisplay:
@@ -69,51 +90,79 @@ async def main():
6990
asyncio.run(main())
7091
```
7192

72-
##Features
73-
- Requires Python 3.10+
74-
- Easy-to-use signal-slot mechanism with decorators
75-
- Support for both synchronous and asynchronous slots
76-
- Thread-safe signal emissions
77-
- Automatic connection type detection (direct/queued)
78-
- Compatible with Python's asyncio
93+
##Core Concepts
7994

80-
##Installation
95+
###Signals and Slots
96+
- Signals: Declared with`@t_signal`. Signals are attributes of a class that can be emitted to notify interested parties.
97+
- Slots: Declared with`@t_slot`. Slots are methods that respond to signals. Slots can be synchronous or async functions.
98+
- Connections: Use`signal.connect(receiver, slot)` to link signals to slots. Connections can also be made directly to functions or lambdas.
8199

82-
TSignal requires Python 3.10 or higher. You can install it directly from the repository:
100+
###Thread Safety and Connection Types
101+
TSignal automatically detects whether the signal emission and slot execution occur in the same thread or different threads:
83102

84-
```bash
85-
git clone https://github.com/tsignal/tsignal-python.git
86-
cd tsignal-python
87-
pip install -e.
88-
```
103+
-**Direct Connection**: If signal and slot share the same thread affinity, the slot is invoked directly.
104+
-**Queued Connection**: If they differ, the call is queued to the slot’s thread/event loop, ensuring thread safety.
89105

90-
For development installation (includes test dependencies):
91-
```bash
92-
pip install -e".[dev]"
93-
```
106+
This mechanism frees you from manually dispatching calls across threads.
94107

95-
##Documentation
96-
-[Detailed Usage Guide](docs/usage.md)
97-
-[API Reference](docs/api.md)
98-
-[Examples](docs/examples.md)
99-
-[Logging Guidelines](docs/logging.md)
100-
-[Testing Guide](docs/testing.md)
108+
###Worker Threads
109+
For background work, TSignal provides a`@t_with_worker` decorator that:
101110

102-
##Development
111+
- Spawns a dedicated event loop in a worker thread.
112+
- Allows you to queue async tasks to this worker.
113+
- Enables easy start/stop lifecycle management.
114+
- Integrates with signals and slots for thread-safe updates to the main
103115

104-
###Logging
105-
TSignal uses Python's standard logging module. For detailed logging configuration,
106-
please see[Logging Guidelines](docs/logging.md).
116+
**Worker Example**
117+
```python
118+
from tsignalimport t_with_worker, t_signal
119+
120+
@t_with_worker
121+
classDataProcessor:
122+
@t_signal
123+
defprocessing_done(self):
124+
"""Emitted when processing completes"""
125+
126+
asyncdefrun(self,*args,**kwargs):
127+
# The main entry point for the worker thread’s event loop
128+
# Wait for tasks or stopping signal
129+
awaitself._tsignal_stopping.wait()
130+
131+
asyncdefprocess_data(self,data):
132+
# Perform heavy computation in the worker thread
133+
result=await heavy_computation(data)
134+
self.processing_done.emit(result)
135+
136+
processor= DataProcessor()
137+
processor.start()
138+
139+
# Queue a task to run in the worker thread:
140+
processor.queue_task(processor.process_data(some_data))
141+
142+
# Stop the worker gracefully
143+
processor.stop()
144+
```
145+
146+
##Documentation and Example
147+
-[Usage Guide](docs/usage.md): Learn how to define signals/slots, manage threads, and structure your event-driven code.
148+
-[API Reference](docs/api.md): Detailed documentation of classes, decorators, and functions.
149+
-[Examples](docs/examples.md): Practical use cases, including UI integration, async operations, and worker pattern usage.
150+
-[Logging Guidelines](docs/logging.md): Configure logging levels and handlers for debugging.
151+
-[Testing Guide](docs/testing.md): earn how to run tests and contribute safely.
152+
153+
##Logging
154+
Configure logging to diagnose issues:
107155

108-
Basic usage:
109156
```python
110157
import logging
111-
logging.getLogger('tsignal').setLevel(logging.INFO)
158+
logging.getLogger('tsignal').setLevel(logging.DEBUG)
112159
```
113160

161+
For more details, see the[Logging Guidelines](docs/logging.md).
162+
114163
##Testing
115164

116-
TSignalincludes a comprehensive test suite usingpytest. For basic testing:
165+
TSignaluses`pytest` for testing:
117166

118167
```bash
119168
# Run all tests
@@ -126,95 +175,10 @@ pytest -v
126175
pytest tests/unit/test_signal.py
127176
```
128177

129-
For detailed testing instructions and guidelines, see[Testing Guide](docs/testing.md).
178+
See the[Testing Guide](docs/testing.md) for more details.
130179

131180
##Contributing
132-
Pleasesee[Contributing Guidelines](CONTRIBUTING.md)for details on how to contribute to this project.
181+
We welcome contributions.Pleaseread the[Contributing Guidelines](CONTRIBUTING.md)before submitting PRs.
133182

134183
##License
135-
This project is licensed under the MIT License - see the[LICENSE](LICENSE) file for details.
136-
137-
##Connecting Signals and Slots
138-
139-
###Classic Object-Member Connection
140-
```python
141-
@t_with_signals
142-
classCounter:
143-
@t_signal
144-
defcount_changed(self):
145-
pass
146-
147-
@t_with_signals
148-
classDisplay:
149-
@t_slot
150-
defon_count_changed(self,value):
151-
print(f"Count is now:{value}")
152-
153-
counter= Counter()
154-
display= Display()
155-
counter.count_changed.connect(display, display.on_count_changed)
156-
```
157-
158-
###Function Connection
159-
```python
160-
# Connect to a simple function
161-
defprint_value(value):
162-
print(f"Value:{value}")
163-
164-
counter.count_changed.connect(print_value)
165-
166-
# Connect to a lambda
167-
counter.count_changed.connect(lambdax:print(f"Lambda received:{x}"))
168-
169-
# Connect to an object method without @t_slot
170-
classHandler:
171-
defprocess_value(self,value):
172-
print(f"Processing:{value}")
173-
174-
handler= Handler()
175-
counter.count_changed.connect(handler.process_value)
176-
```
177-
178-
##Worker Thread Pattern
179-
180-
TSignal provides a worker thread pattern that combines thread management with signal/slot communication and task queuing:
181-
182-
```python
183-
from tsignalimport t_with_worker
184-
185-
@t_with_worker
186-
classDataProcessor:
187-
asyncdefinitialize(self,config=None):
188-
# Setup worker (called in worker thread)
189-
self.config= configor {}
190-
191-
asyncdefprocess_data(self,data):
192-
# Heavy processing in worker thread
193-
result=await heavy_computation(data)
194-
self.processing_done.emit(result)
195-
196-
asyncdeffinalize(self):
197-
# Cleanup worker (called before thread stops)
198-
awaitself.cleanup()
199-
200-
@t_signal
201-
defprocessing_done(self):
202-
pass
203-
204-
# Usage
205-
processor= DataProcessor()
206-
processor.start(config={'threads':4})# Starts worker thread
207-
208-
# Queue task in worker thread
209-
await processor.queue_task(processor.process_data(some_data))
210-
211-
# Stop worker
212-
processor.stop()# Graceful shutdown
213-
```
214-
215-
The worker pattern provides:
216-
- Dedicated worker thread with event loop
217-
- Built-in signal/slot support
218-
- Async task queue
219-
- Graceful initialization/shutdown
220-
- Thread-safe communication
184+
TSignal is licensed under the MIT License. See[LICENSE](LICENSE) for details.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp