1. Code Organization and Structure
pythoncustomtkinterguibest-practicesoop
Description
This rule provides best practices for developing efficient, maintainable, and scalable GUI applications with CustomTkinter. It covers code organization, performance, security, testing, and common pitfalls.
Globs
**/*.py
---
description: This rule provides best practices for developing efficient, maintainable, and scalable GUI applications with CustomTkinter. It covers code organization, performance, security, testing, and common pitfalls.
globs: **/*.py
---
- **Always use UV when installing dependencies.**
- **Always use Python 3.10 or higher.** CustomTkinter requires a modern Python version for compatibility and feature support.
- **Prefer an object-oriented approach.** Encapsulate UI elements and logic within classes for better organization, maintainability, and scalability. Avoid procedural coding for complex applications.
- **Use virtual environments.** Create isolated environments for each project to manage dependencies and avoid conflicts.
- **Use descriptive variable and function names.** Clear and concise names improve code readability.
## 1. Code Organization and Structure
- **Directory Structure:**
- Project Root
- `src/` (Source code)
- `gui/` (CustomTkinter-related modules)
- `__init__.py`
- `main_window.py` (Main application window)
- `components/` (Reusable UI components)
- `__init__.py`
- `button.py`
- `label.py`
- `models/` (Data models if applicable)
- `__init__.py`
- `user.py`
- `utils/` (Utility functions and helpers)
- `__init__.py`
- `config.py`
- `helpers.py`
- `services/` (API interaction services)
- `__init__.py`
- `api_service.py`
- `tests/` (Tests)
- `__init__.py`
- `gui/`
- `test_main_window.py`
- `utils/`
- `test_helpers.py`
- `data/` (Data files, configuration files)
- `requirements.txt` (Dependencies)
- `README.md` (Project documentation)
- `.gitignore`
- `LICENSE`
- `pyproject.toml` or `setup.py`
- **File Naming Conventions:**
- Python files: `lowercase_with_underscores.py`
- Class names: `PascalCase` (e.g., `MainWindow`, `CustomButton`)
- Variable names: `lowercase_with_underscores` (e.g., `main_window`, `button_text`)
- Constants: `UPPERCASE_WITH_UNDERSCORES` (e.g., `DEFAULT_FONT`, `API_KEY`)
- **Module Organization:**
- Group related functionalities into separate modules.
- Use `__init__.py` files to define packages and control namespace imports.
- Keep modules focused on a single responsibility.
- **Component Architecture:**
- Divide the UI into reusable components (e.g., buttons, labels, forms).
- Create custom widget classes by inheriting from `customtkinter.CTkBaseClass` or other appropriate customtkinter base classes.
- Utilize the Model-View-Controller (MVC) or Model-View-ViewModel (MVVM) design pattern to separate UI logic from data and presentation.
- **Code Splitting:**
- Break down large UI components into smaller, manageable parts.
- Use functions and methods to encapsulate specific actions.
- Consider creating separate modules for complex features.
## 2. Common Patterns and Anti-patterns
- **Design Patterns:**
- **MVC (Model-View-Controller):** Separate data (Model), UI (View), and user input handling (Controller).
- **MVVM (Model-View-ViewModel):** Similar to MVC, but uses a ViewModel to mediate between the Model and View.
- **Observer:** Implement event handling and notifications between components.
- **Factory:** Create UI elements dynamically based on configuration or user input.
- **Singleton:** Ensures a class only has one instance.
- **Recommended Approaches:**
- **Dynamic UI updates:** Use `configure()` to modify widget properties instead of recreating widgets.
- **Data binding:** Link UI elements to data models for automatic updates.
- **Theming:** Create reusable themes with consistent styles for your application.
- **Asynchronous Operations:** Use `after()` or `threading` module to handle long-running tasks without blocking the main event loop.
- **Use `CTkFont`**: Use this to ensure that the correct font family is used, that is appropriate across all operating systems.
- **Anti-patterns and Code Smells:**
- **God object:** Avoid creating a single class that handles too many responsibilities.
- **Global variables:** Minimize the use of global variables; use instance variables or dependency injection instead.
- **Deeply nested code:** Refactor complex conditional statements and loops into smaller, more readable functions.
- **Mixing grid() and pack() layout managers**: Stick to one layout manager per container to avoid unexpected behavior.
- **State Management:**
- **Centralized state:** Use a dedicated state management class or library to store and manage application state (e.g., using the observer pattern). This can be a simple class for smaller apps, or something like RxPY for more complex state handling.
- **Immutable data:** Treat state data as immutable and create new copies when modifying it to prevent unexpected side effects.
- **Observable state:** Use observable patterns to notify components when the state changes.
- **Error Handling:**
- **Try-except blocks:** Wrap potentially failing code with `try-except` blocks to handle exceptions gracefully.
- **Logging:** Use the `logging` module to record errors and debug information.
- **User feedback:** Provide informative error messages to the user.
- **Specific exception handling:** Handle exceptions in specific branches of your application, rather than catching all errors in a single block.
## 3. Performance Considerations
- **Optimization Techniques:**
- **Minimize UI redraws:** Use `update_idletasks()` to refresh the UI without a full redraw, especially when making multiple changes to widgets. Only update relevant portions of the UI.
- **Efficient layout management:** Choose the appropriate layout manager (grid or pack) and use it consistently.
- **Widget caching:** Reuse existing widgets instead of creating new ones whenever possible.
- **Batch updates:** Group multiple UI updates into a single operation to reduce the number of redraws.
- **Efficient image handling**: Use optimized image formats (e.g., WebP) and resize images appropriately for the UI.
- **Memory Management:**
- **Avoid memory leaks:** Be careful with circular references and ensure that objects are properly released when they are no longer needed.
- **Resource cleanup:** Close files, release database connections, and other resources when they are no longer needed.
- **Rendering Optimization:**
- **Reduce widget complexity:** Avoid using overly complex widgets or layouts.
- **Use hardware acceleration:** Enable hardware acceleration if available to improve rendering performance. This is typically handled by Tkinter itself, but ensure your system supports it.
- **Lazy Loading:**
- **Load UI elements on demand:** Load UI elements only when they are needed to reduce the initial load time.
- **Virtual scrolling:** Implement virtual scrolling for large lists or grids to render only the visible items.
- **Use `after()` wisely:** Delegate intensive tasks to run in the background using `after()` to prevent freezing.
## 4. Security Best Practices
- **Common Vulnerabilities:**
- **Code injection:** Prevent code injection by validating and sanitizing user inputs.
- **Cross-site scripting (XSS):** Escape user-generated content to prevent XSS attacks.
- **Data exposure:** Protect sensitive data by encrypting it and storing it securely.
- **Denial of Service (DoS):** Prevent DoS attacks by limiting the rate of requests and validating input sizes.
- **Input Validation:**
- **Validate all user inputs:** Check data types, formats, and ranges to prevent invalid data from entering the system.
- **Sanitize inputs:** Remove or escape potentially harmful characters from user inputs.
- **Use parameterized queries:** Avoid SQL injection by using parameterized queries when interacting with databases.
- **Authentication and Authorization:**
- **Secure password storage:** Use strong hashing algorithms (e.g., bcrypt, Argon2) to store passwords.
- **Two-factor authentication (2FA):** Implement 2FA to enhance account security.
- **Role-based access control (RBAC):** Control access to resources based on user roles.
- **Use HTTPS:** Always use HTTPS for secure communication between the client and server.
- **Data Protection:**
- **Encryption:** Encrypt sensitive data both in transit and at rest.
- **Data masking:** Mask or redact sensitive data when displaying it to users.
- **Regular backups:** Create regular backups of your data to prevent data loss.
- **Secure API Communication:**
- **API keys:** Store API keys securely and protect them from unauthorized access.
- **Rate limiting:** Limit the rate of API requests to prevent abuse.
- **Input validation:** Validate all data received from APIs.
- **HTTPS:** Always use HTTPS when communicating with APIs.
## 5. Testing Approaches
- **Unit Testing:**
- **Test individual components:** Write unit tests for each component to ensure that it functions correctly.
- **Mock dependencies:** Use mocking to isolate the component being tested from its dependencies.
- **Test edge cases:** Test edge cases and boundary conditions to identify potential issues.
- **Use a testing framework:** Use pytest or unittest.
- **Integration Testing:**
- **Test interactions between components:** Write integration tests to ensure that components work together correctly.
- **Test API interactions:** Test the interaction between the UI and the backend API.
- **Use a testing framework:** Use pytest or unittest.
- **End-to-End Testing:**
- **Test the entire application workflow:** Write end-to-end tests to simulate user interactions and ensure that the application functions correctly from start to finish.
- **Use a testing framework:** Use playwright or selenium.
- **Test Organization:**
- **Separate test files:** Create separate test files for each module or component.
- **Follow a consistent naming convention:** Use a consistent naming convention for test files and functions (e.g., `test_<module_name>.py`, `test_<function_name>`).
- **Mocking and Stubbing:**
- **Use mocking libraries:** Use libraries like `unittest.mock` or `pytest-mock` to create mock objects for dependencies.
- **Stub external services:** Use stubs to replace external services with predictable responses during testing.
## 6. Common Pitfalls and Gotchas
- **Frequent Mistakes:**
- **Forgetting `self`:** Forgetting to use `self` when accessing instance variables.
- **Incorrect layout management:** Mixing `grid` and `pack` in the same container or not specifying proper row/column configurations.
- **Blocking the main loop:** Performing long-running operations in the main thread, causing the UI to freeze. Use `after()` or `threading` for background tasks.
- **Incorrect event handling:** Not properly binding events to UI elements.
- **Using the same variable name for Tkinter elements**: Tkinter elements should be named descriptively so that they are not confused with other local variables.
- **Edge Cases:**
- **Handling different screen resolutions:** Test the UI on different screen resolutions to ensure that it looks correct.
- **Handling different operating systems:** Test the UI on different operating systems to ensure that it functions correctly.
- **Handling different font sizes:** Test the UI with different font sizes to ensure that the layout remains consistent.
- **Version-Specific Issues:**
- **Check compatibility:** Consult the CustomTkinter documentation for version-specific issues and compatibility information.
- **Compatibility Concerns:**
- **Tkinter versions:** Ensure compatibility between CustomTkinter and the underlying Tkinter version.
- **Operating system:** Test the application on different operating systems to identify potential compatibility issues.
- **Python versions:** Ensure that the application is compatible with the target Python versions.
- **Debugging Strategies:**
- **Use print statements:** Insert `print` statements to debug code and inspect variable values.
- **Use a debugger:** Use a debugger to step through code and inspect the execution flow.
- **Read error messages:** Carefully read error messages to understand the root cause of the problem.
## 7. Tooling and Environment
- **Recommended Tools:**
- **Text editor:** VS Code with Python extension.
- **Virtual environment manager:** `venv` or `conda`.
- **Package manager:** `pip` or `poetry`.
- **Testing framework:** `pytest`.
- **Linting and formatting:** `pylint` or `flake8` and `black` or `autopep8`.
- **Build Configuration:**
- **Use `pyproject.toml` or `setup.py`:** Define project metadata, dependencies, and build instructions in `pyproject.toml` or `setup.py`.
- **Specify dependencies:** List all dependencies in `requirements.txt` or `pyproject.toml`.
- **Linting and Formatting:**
- **Configure linting rules:** Configure linting tools to enforce code style and identify potential issues.
- **Use a formatter:** Use a code formatter to automatically format code according to a consistent style guide.
- **Integrate with CI/CD:** Integrate linting and formatting checks into the CI/CD pipeline.
- **Deployment:**
- **Package the application:** Package the application into an executable or installer using tools like `pyinstaller` or `cx_Freeze`.
- **Create a virtual environment:** Create a virtual environment for the application and include all dependencies.
- **Follow platform-specific guidelines:** Follow platform-specific guidelines for deploying applications.
- **CI/CD Integration:**
- **Automate testing:** Automate unit, integration, and end-to-end tests in the CI/CD pipeline.
- **Automate linting and formatting:** Automate linting and formatting checks in the CI/CD pipeline.
- **Automate deployment:** Automate the deployment process in the CI/CD pipeline.