A parser Python to Qt Style Sheets (QSS)
Project description
QSS Parser
QSS Parser is a lightweight and robust Python library designed to parse and validate Qt Style Sheets (QSS), the stylesheet language used by Qt applications to customize the appearance of widgets. It enables developers to validate QSS syntax, parse QSS into structured rules, and extract styles for specific Qt widgets based on their object names, class names, attributes, or additional selectors. This library is particularly useful for developers working with PyQt or PySide applications who need to manage and apply QSS styles programmatically.
Table of Contents
Features
- QSS Validation: Checks QSS for syntax errors such as missing semicolons, unclosed braces, properties outside blocks, and invalid selectors.
- Structured Parsing: Converts QSS into a structured representation with
QSSRuleandQSSPropertyobjects, making it easy to manipulate styles programmatically. - Style Extraction: Retrieves styles for Qt widgets based on their object names, class names, attribute selectors (e.g.,
[data-value="complex string"]), pseudo-states (e.g.,:hover), or pseudo-elements (e.g.,::handle). - Advanced Selector Support: Handles complex selectors, including attribute selectors with spaces or special characters, composite selectors (e.g.,
QPushButton #myButton), and normalized selector processing to ensure consistent parsing. - Lightweight and Dependency-Free: No external dependencies required, ensuring easy integration into any Python project.
- Extensible Design: Built with a plugin-based architecture to support custom parsing logic and future enhancements.
- Comprehensive Testing: Includes a robust test suite covering validation, parsing, and style extraction, ensuring reliability and correctness.
Installation
To install qss-parser, use pip:
pip install qss-parser
Requirements
- Python 3.6 or higher
- No external dependencies are required for core functionality.
- For integration with Qt applications, you may need
PyQt5,PyQt6, orPySide2/PySide6(not included in the package dependencies).
To install with Qt support (e.g., PyQt5):
pip install qss-parser PyQt5
Usage
The qss-parser library provides a simple and intuitive API for validating, parsing, and applying QSS styles. Below are several examples to demonstrate its capabilities.
Complete Example
Check the complete example here.
Basic Example
This example shows how to validate and parse a QSS string and retrieve styles for a mock widget.
from qss_parser import QSSParser
from unittest.mock import Mock
# Create a mock widget
widget = Mock()
widget.objectName.return_value = "myButton"
widget.metaObject.return_value.className.return_value = "QPushButton"
# Initialize the parser
parser = QSSParser()
# Sample QSS
qss = """
#myButton {
color: red;
}
QPushButton {
background: blue;
}
"""
# Validate QSS format
errors = parser.check_format(qss)
if errors:
print("Invalid QSS format:")
for error in errors:
print(error)
else:
# Parse and retrieve styles
parser.parse(qss)
styles = parser.get_styles_for(widget)
print("Styles for widget:")
print(styles)
Output:
Styles for widget:
#myButton {
color: red;
}
Validating QSS Syntax
The check_format method validates QSS syntax and returns a list of error messages for any issues found.
from qss_parser import QSSParser
parser = QSSParser()
qss = """
QPushButton {
color: blue
}
"""
errors = parser.check_format(qss)
for error in errors:
print(error)
Output:
Error on line 3: Property missing ';': color: blue
Parsing QSS with Attribute Selectors
This example demonstrates parsing QSS with complex attribute selectors and extracting styles for a widget.
from qss_parser import QSSParser
from unittest.mock import Mock
# Create a mock widget
widget = Mock()
widget.objectName.return_value = "myButton"
widget.metaObject.return_value.className.return_value = "QPushButton"
parser = QSSParser()
qss = """
QPushButton[data-value="complex string with spaces"] {
color: blue;
}
"""
parser.parse(qss)
styles = parser.get_styles_for(widget)
print("Styles for widget:")
print(styles)
Output:
Styles for widget:
QPushButton[data-value="complex string with spaces"] {
color: blue;
}
Integration with Qt Applications
This example demonstrates how to use qss-parser in a real PyQt5 application to apply styles to a widget.
from PyQt5.QtWidgets import QApplication, QPushButton
from qss_parser import QSSParser
import sys
# Initialize the Qt application
app = QApplication(sys.argv)
# Initialize the parser
parser = QSSParser()
# Load QSS from a file
with open("styles.qss", "r", encoding="utf-8") as f:
qss = f.read()
# Validate QSS
errors = parser.check_format(qss)
if errors:
print("Invalid QSS format:")
for error in errors:
print(error)
sys.exit(1)
# Parse QSS
parser.parse(qss)
# Create a button
button = QPushButton("Click Me")
button.setObjectName("myButton")
# Apply styles
styles = parser.get_styles_for(button, include_class_if_object_name=True)
button.setStyleSheet(styles)
# Show the button
button.show()
# Run the application
sys.exit(app.exec_())
API Reference
QSSParser Class
The main class for parsing and managing QSS.
- Methods:
check_format(qss_text: str) -> List[str]: Validates QSS syntax and returns a list of error messages.parse(qss_text: str): Parses QSS into a list ofQSSRuleobjects.get_styles_for(widget, fallback_class: Optional[str] = None, additional_selectors: Optional[List[str]] = None, include_class_if_object_name: bool = False) -> str: Retrieves QSS styles for a widget based on its object name, class name, attribute selectors, and optional parameters.on(event: str, handler: Callable[[Any], None]): Registers an event handler for parser events (rule_added,error_found).__repr__() -> str: Returns a string representation of all parsed rules.
QSSRule Class
Represents a QSS rule with a selector and properties.
-
Attributes:
selector: str: The rule's selector (e.g.,#myButton,QPushButton[data-value="value"]).properties: List[QSSProperty]: List of properties in the rule.original: str: The original QSS text for the rule.attributes: List[str]: List of attribute selectors (e.g.,[data-value="complex string"]).pseudo_states: List[str]: List of pseudo-states (e.g.,hover,focus).object_name: Optional[str]: The object name if present (e.g.,myButtonfor#myButton).class_name: Optional[str]: The class name if present (e.g.,QPushButton).
-
Methods:
add_property(name: str, value: str): Adds a property to the rule.clone_without_pseudo_elements() -> QSSRule: Creates a copy of the rule without pseudo-elements or pseudo-states.
QSSProperty Class
Represents a single QSS property.
-
Attributes:
name: str: The property name (e.g.,color).value: str: The property value (e.g.,blue).
-
Methods:
to_dict() -> QSSPropertyDict: Converts the property to a dictionary.
QSSValidator Class
Validates QSS syntax.
- Methods:
check_format(qss_text: str) -> List[str]: Validates QSS syntax and returns a list of error messages.
QSSStyleSelector Class
Selects and formats QSS styles for widgets.
- Methods:
get_styles_for(rules: List[QSSRule], widget, ...): Retrieves styles for a widget from a list of rules.
QSSParserPlugin and DefaultQSSParserPlugin
QSSParserPlugin: Abstract base class for parser plugins.DefaultQSSParserPlugin: Default plugin for parsing QSS, handling selectors and properties with advanced normalization for attribute selectors.
Contributing
We welcome contributions to qss-parser! To contribute:
- Fork the Repository: Fork the qss-parser repository on GitHub.
- Create a Branch: Create a new branch for your feature or bug fix (
git checkout -b feature/my-feature). - Make Changes: Implement your changes and ensure they follow the project's coding style.
- Run Tests: Run the test suite to verify your changes (
python -m unittest discover tests). - Submit a Pull Request: Push your branch to your fork and open a pull request with a clear description of your changes.
Please read our Contributing Guidelines for more details.
Code Style
- Follow PEP 8 for Python code style.
- Use type hints where applicable (per PEP 484).
- Write clear, concise docstrings for all public methods and classes.
Testing
The library includes a comprehensive test suite located in the tests/ directory. To run the tests:
python -m unittest discover tests
To ensure compatibility across Python versions, you can use tox:
pip install tox
tox
Please ensure all tests pass before submitting a pull request.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Support
If you encounter issues or have questions, please:
- Open an Issue: Report bugs or request features on the GitHub Issues page.
- Contact the Maintainer: Reach out to Onimock for direct support.
Acknowledgements
- Thanks to the Qt community for their extensive documentation on QSS.
- Inspired by the need for programmatic QSS handling in PyQt/PySide applications.
- Special thanks to contributors and users who provide feedback and improvements.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file qss_parser-0.1.2.tar.gz.
File metadata
- Download URL: qss_parser-0.1.2.tar.gz
- Upload date:
- Size: 26.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7d5cb85da78321f41a6a53491342a4bec3ef3136d61e3cd3b80f2a79d93e748
|
|
| MD5 |
e89085c314a29e2c9fdbc9a9ed7f7642
|
|
| BLAKE2b-256 |
308c19aa67db827f06bc17d29f98ca5a1243059750694405c29c779576ba2a97
|
File details
Details for the file qss_parser-0.1.2-py3-none-any.whl.
File metadata
- Download URL: qss_parser-0.1.2-py3-none-any.whl
- Upload date:
- Size: 13.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc6ed797f999d36b497fe4c44c3249676eb2061d7c6ba9fb2ca6d53f4f8f73d0
|
|
| MD5 |
d1ab4552de7d97042309bd0ae4da903b
|
|
| BLAKE2b-256 |
0483d00ed122d93a3e79bd2b3459d93b6c27196b757342d935d2fbf939c96af1
|