Skip to main content

A parser Python to Qt Style Sheets (QSS)

Project description

QSS Parser

PyPI Version Python Version License Build Status

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 QSSRule and QSSProperty objects, 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, or PySide2/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 of QSSRule objects.
    • 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., myButton for #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:

  1. Fork the Repository: Fork the qss-parser repository on GitHub.
  2. Create a Branch: Create a new branch for your feature or bug fix (git checkout -b feature/my-feature).
  3. Make Changes: Implement your changes and ensure they follow the project's coding style.
  4. Run Tests: Run the test suite to verify your changes (python -m unittest discover tests).
  5. 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

qss_parser-0.1.2.tar.gz (26.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qss_parser-0.1.2-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

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

Hashes for qss_parser-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c7d5cb85da78321f41a6a53491342a4bec3ef3136d61e3cd3b80f2a79d93e748
MD5 e89085c314a29e2c9fdbc9a9ed7f7642
BLAKE2b-256 308c19aa67db827f06bc17d29f98ca5a1243059750694405c29c779576ba2a97

See more details on using hashes here.

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

Hashes for qss_parser-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 bc6ed797f999d36b497fe4c44c3249676eb2061d7c6ba9fb2ca6d53f4f8f73d0
MD5 d1ab4552de7d97042309bd0ae4da903b
BLAKE2b-256 0483d00ed122d93a3e79bd2b3459d93b6c27196b757342d935d2fbf939c96af1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page