CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-qtpy

Provides an abstraction layer on top of the various Qt bindings (PyQt5/6 and PySide2/6).

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

compatibility.mddocs/

Compatibility Utilities

Cross-binding compatibility functions for file dialogs, text processing, object lifecycle management, and QVariant handling that smooth over differences between Qt bindings and versions.

Capabilities

Text Processing Functions

Utilities for handling text strings consistently across Python versions and Qt bindings.

def is_text_string(obj) -> bool:
    """
    Return True if obj is a text string, False if it is anything else.
    
    Args:
        obj: Object to check
        
    Returns:
        bool: True if obj is a text string (str)
    """

def to_text_string(obj, encoding: str | None = None) -> str:
    """
    Convert obj to (unicode) text string.
    
    Args:
        obj: Object to convert to string
        encoding: Encoding to use if obj is bytes, defaults to None
        
    Returns:
        str: Text string representation of obj
    """

TEXT_TYPES: tuple[type, ...]
"""Tuple of text string types (str,)"""

Usage example:

from qtpy.compat import is_text_string, to_text_string

data = "Hello World"
if is_text_string(data):
    print("It's a string!")

# Convert various objects to text
text = to_text_string(42)  # "42"
text = to_text_string(b"bytes", encoding="utf-8")  # "bytes"

QVariant Compatibility

Compatibility layer for QVariant differences between Qt bindings.

def to_qvariant(obj=None):
    """
    Convert Python object to QVariant.
    This is a transitional function from PyQt API#1 (QVariant exist)
    to PyQt API#2 and PySide (QVariant does not exist).
    
    Args:
        obj: Python object to convert
        
    Returns:
        The object itself (no conversion needed in modern bindings)
    """

def from_qvariant(qobj=None, pytype=None):
    """
    Convert QVariant object to Python object.
    This is a transitional function from PyQt API #1 (QVariant exist)
    to PyQt API #2 and PySide (QVariant does not exist).
    
    Args:
        qobj: QVariant object to convert
        pytype: Python type hint (unused in modern bindings)
        
    Returns:
        The object itself (no conversion needed in modern bindings)
    """

PYQT_API_1: bool
"""Always False - legacy PyQt API compatibility flag"""

File Dialog Wrappers

Consistent file dialog interfaces that handle differences between Qt bindings and return types.

def getexistingdirectory(
    parent=None,
    caption: str = '',
    basedir: str = '',
    options=None
) -> str:
    """
    Wrapper for QFileDialog.getExistingDirectory.
    
    Args:
        parent: Parent widget
        caption: Dialog caption
        basedir: Starting directory
        options: Dialog options
        
    Returns:
        str: Selected directory path or empty string if cancelled
    """

def getopenfilename(
    parent=None,
    caption: str = '',
    basedir: str = '',
    filters: str = '',
    selectedfilter: str = '',
    options=None
) -> tuple[str, str]:
    """
    Wrapper for QFileDialog.getOpenFileName.
    
    Args:
        parent: Parent widget
        caption: Dialog caption
        basedir: Starting directory
        filters: File filters (e.g., "Images (*.png *.jpg);;All Files (*)")
        selectedfilter: Initially selected filter
        options: Dialog options
        
    Returns:
        tuple[str, str]: (selected_filename, selected_filter)
    """

def getopenfilenames(
    parent=None,
    caption: str = '',
    basedir: str = '',
    filters: str = '',
    selectedfilter: str = '',
    options=None
) -> tuple[list[str], str]:
    """
    Wrapper for QFileDialog.getOpenFileNames.
    
    Args:
        parent: Parent widget
        caption: Dialog caption
        basedir: Starting directory
        filters: File filters
        selectedfilter: Initially selected filter
        options: Dialog options
        
    Returns:
        tuple[list[str], str]: (selected_filenames, selected_filter)
    """

def getsavefilename(
    parent=None,
    caption: str = '',
    basedir: str = '',
    filters: str = '',
    selectedfilter: str = '',
    options=None
) -> tuple[str, str]:
    """
    Wrapper for QFileDialog.getSaveFileName.
    
    Args:
        parent: Parent widget
        caption: Dialog caption
        basedir: Starting directory
        filters: File filters
        selectedfilter: Initially selected filter
        options: Dialog options
        
    Returns:
        tuple[str, str]: (selected_filename, selected_filter)
    """

Usage example:

from qtpy.compat import getopenfilename, getsavefilename, getexistingdirectory
from qtpy.QtWidgets import QApplication, QWidget

app = QApplication([])
parent = QWidget()

# Open file dialog
filename, filter_used = getopenfilename(
    parent, 
    "Open File", 
    "", 
    "Python Files (*.py);;All Files (*)"
)
if filename:
    print(f"Selected: {filename}")

# Save file dialog
filename, filter_used = getsavefilename(
    parent,
    "Save File",
    "",
    "Text Files (*.txt);;All Files (*)"
)

# Directory selection
directory = getexistingdirectory(parent, "Select Directory")

Object Lifecycle Functions

Utilities for checking Qt object validity across different bindings.

def isalive(obj) -> bool:
    """
    Wrapper for sip.isdeleted/shiboken.isValid to check if Qt object is alive.
    
    Args:
        obj: Qt object to check
        
    Returns:
        bool: True if the Qt object is still valid/alive, False if deleted
    """

Usage example:

from qtpy.compat import isalive
from qtpy.QtWidgets import QWidget

widget = QWidget()
print(isalive(widget))  # True

widget.deleteLater()
# After event loop processes deletion
print(isalive(widget))  # False

Import Patterns

All compatibility functions are available through the compat module:

# Import specific functions
from qtpy.compat import getopenfilename, isalive, to_text_string

# Import entire module
from qtpy import compat

filename, _ = compat.getopenfilename(None, "Open File")
is_valid = compat.isalive(some_widget)
text = compat.to_text_string(some_object)

Cross-Binding Consistency

The compatibility module ensures consistent behavior across all supported Qt bindings:

  • File Dialogs: Uniform return types and parameter handling
  • Text Processing: Consistent string handling across Python versions
  • Object Lifecycle: Unified interface for checking object validity
  • QVariant: Transparent handling of QVariant differences

This allows code to work identically whether using PyQt5, PyQt6, PySide2, or PySide6.

Install with Tessl CLI

npx tessl i tessl/pypi-qtpy

docs

compatibility.md

core-package.md

development-tools.md

index.md

qt-modules.md

uic-module.md

tile.json