Skip to content

Instantly share code, notes, and snippets.

@bikcrum
Created January 9, 2026 02:26
Show Gist options
  • Select an option

  • Save bikcrum/6daa739bbf402f41d9c144f023b620e2 to your computer and use it in GitHub Desktop.

Select an option

Save bikcrum/6daa739bbf402f41d9c144f023b620e2 to your computer and use it in GitHub Desktop.
Fix Qt/PySide6 Import Errors on Ubuntu - pyqtgraph compatibility fixes
#!/bin/bash
# Fix Qt/PySide6 dependencies for Ubuntu
# Run this script with: bash fix_qt_dependencies.sh
set -e
echo "Installing Qt/X11 system libraries..."
apt-get update && apt-get install -y \
libfontconfig1 \
libxkbcommon0 \
libxkbcommon-x11-0 \
libxcb1 \
libxcb-xinerama0 \
libxcb-xfixes0 \
libxcb-xinput0 \
libxcb-xkb1 \
libxcb-randr0 \
libxcb-shape0 \
libxcb-render0 \
libxcb-render-util0 \
libxcb-image0 \
libxcb-icccm4 \
libxcb-sync1 \
libxcb-keysyms1 \
libxcb-xtest0 \
libxcb-shm0 \
libxcb-util1 \
libxcb-dri3-0 \
libxcb-present0 \
libx11-xcb1 \
libxrender1 \
libxi6 \
libxfixes3 \
libxcb-cursor0 \
libdbus-1-3 \
dbus
echo ""
echo "✓ Qt/X11 libraries installed successfully!"
echo ""
echo "Note: If you encounter PySide6 version attribute errors,"
echo "you may need to patch pyqtgraph. See QT_PYSIDE6_FIXES.md for details."
#!/usr/bin/env python3
"""
Patch pyqtgraph to fix PySide6 compatibility issues.
Usage:
python patch_pyqtgraph.py
python patch_pyqtgraph.py python3
"""
import sys
import os
import re
def patch_qt_init(filepath):
"""Patch pyqtgraph/Qt/__init__.py"""
print(f"Patching {filepath}...")
with open(filepath, 'r') as f:
content = f.read()
# Check if already patched
if "pyside6_version = getattr" in content:
print(" ✓ Already patched")
return True
# Pattern to match the problematic line
pattern = r"VERSION_INFO = 'PySide6 ' \+ PySide6\.__version__ \+ ' Qt ' \+ QtCore\.__version__"
replacement = """pyside6_version = getattr(PySide6, '__version__', QtCore.__version__)
VERSION_INFO = 'PySide6 ' + pyside6_version + ' Qt ' + QtCore.__version__"""
if re.search(pattern, content):
content = re.sub(pattern, replacement, content)
with open(filepath, 'w') as f:
f.write(content)
print(" ✓ Patched successfully")
return True
else:
print(" ⚠ Could not find the line to patch. File may have changed.")
return False
def patch_qt_internals(filepath):
"""Patch pyqtgraph/Qt/internals.py"""
print(f"Patching {filepath}...")
with open(filepath, 'r') as f:
content = f.read()
# Check if already patched
if "except (ImportError, AttributeError):" in content and "# PySide6 doesn't always have" in content:
print(" ✓ Already patched")
return True
# Pattern to match the problematic section
pattern = r"elif QT_LIB == 'PySide6':\s+from PySide6 import __version_info__ as pyside_version_info\s+qt_version_info = QtCore\.__version_info__"
replacement = """elif QT_LIB == 'PySide6':
try:
from PySide6 import __version_info__ as pyside_version_info
except (ImportError, AttributeError):
# PySide6 doesn't always have __version_info__, use QtCore's instead
pyside_version_info = QtCore.__version_info__
qt_version_info = QtCore.__version_info__"""
if re.search(pattern, content, re.MULTILINE):
content = re.sub(pattern, replacement, content, flags=re.MULTILINE)
with open(filepath, 'w') as f:
f.write(content)
print(" ✓ Patched successfully")
return True
else:
# Try alternative approach - find the line and replace more carefully
lines = content.split('\n')
in_pyside6_block = False
modified = False
for i, line in enumerate(lines):
if "elif QT_LIB == 'PySide6':" in line:
in_pyside6_block = True
# Check if next lines match the pattern
if i + 2 < len(lines):
if "from PySide6 import __version_info__" in lines[i + 1] and "qt_version_info = QtCore.__version_info__" in lines[i + 2]:
# Replace the next two lines
lines[i + 1:i + 3] = [
" try:",
" from PySide6 import __version_info__ as pyside_version_info",
" except (ImportError, AttributeError):",
" # PySide6 doesn't always have __version_info__, use QtCore's instead",
" pyside_version_info = QtCore.__version_info__",
" qt_version_info = QtCore.__version_info__"
]
modified = True
break
in_pyside6_block = False
if modified:
with open(filepath, 'w') as f:
f.write('\n'.join(lines))
print(" ✓ Patched successfully")
return True
else:
print(" ⚠ Could not find the section to patch. File may have changed.")
return False
def main():
python_exec = sys.executable if len(sys.argv) == 1 else sys.argv[1]
print("Finding pyqtgraph installation...")
try:
import pyqtgraph
pyqtgraph_path = pyqtgraph.__file__
pyqtgraph_dir = os.path.dirname(pyqtgraph_path)
except ImportError:
print(f"Error: pyqtgraph not found with {python_exec}.")
print("Please install pyqtgraph first or specify the correct Python executable.")
sys.exit(1)
print(f"pyqtgraph found at: {pyqtgraph_dir}")
print()
qt_init_file = os.path.join(pyqtgraph_dir, "Qt", "__init__.py")
qt_internals_file = os.path.join(pyqtgraph_dir, "Qt", "internals.py")
success = True
if os.path.exists(qt_init_file):
if not patch_qt_init(qt_init_file):
success = False
else:
print(f" ✗ File not found: {qt_init_file}")
success = False
if os.path.exists(qt_internals_file):
if not patch_qt_internals(qt_internals_file):
success = False
else:
print(f" ✗ File not found: {qt_internals_file}")
success = False
print()
if success:
print("✓ Patching complete!")
print("You can now test your pyqtgraph application.")
else:
print("⚠ Some patches may have failed. Check the output above.")
sys.exit(1)
if __name__ == "__main__":
main()
#!/bin/bash
# Patch pyqtgraph to fix PySide6 compatibility issues
# Usage: bash patch_pyqtgraph.sh [python_executable]
# Example: bash patch_pyqtgraph.sh python
# bash patch_pyqtgraph.sh /path/to/python
set -e
# Default to 'python' if no argument provided
PYTHON="${1:-python}"
echo "Finding pyqtgraph installation..."
PYQTGGRAPH_PATH=$($PYTHON -c "import pyqtgraph; print(pyqtgraph.__file__)" 2>/dev/null || echo "")
if [ -z "$PYQTGGRAPH_PATH" ]; then
echo "Error: pyqtgraph not found. Is it installed?"
echo "Trying with python3..."
PYTHON="python3"
PYQTGGRAPH_PATH=$($PYTHON -c "import pyqtgraph; print(pyqtgraph.__file__)" 2>/dev/null || echo "")
if [ -z "$PYQTGGRAPH_PATH" ]; then
echo "Error: pyqtgraph still not found. Please install it first."
exit 1
fi
fi
PYQTGGRAPH_DIR=$(dirname "$PYQTGGRAPH_PATH")
QT_INIT_FILE="$PYQTGGRAPH_DIR/Qt/__init__.py"
QT_INTERNALS_FILE="$PYQTGGRAPH_DIR/Qt/internals.py"
echo "pyqtgraph found at: $PYQTGGRAPH_DIR"
echo ""
# Patch 1: Fix Qt/__init__.py
if [ -f "$QT_INIT_FILE" ]; then
echo "Patching $QT_INIT_FILE..."
if grep -q "pyside6_version = getattr" "$QT_INIT_FILE"; then
echo " ✓ Already patched (line 251 area)"
else
# Find and replace the problematic line
if grep -q "PySide6.__version__" "$QT_INIT_FILE"; then
# Using sed to replace the line
sed -i "s/VERSION_INFO = 'PySide6 ' + PySide6.__version__ + ' Qt ' + QtCore.__version__/pyside6_version = getattr(PySide6, '__version__', QtCore.__version__)\n VERSION_INFO = 'PySide6 ' + pyside6_version + ' Qt ' + QtCore.__version__/" "$QT_INIT_FILE"
echo " ✓ Patched successfully"
else
echo " ⚠ Could not find the line to patch. File may have changed."
fi
fi
else
echo " ✗ File not found: $QT_INIT_FILE"
fi
# Patch 2: Fix Qt/internals.py
if [ -f "$QT_INTERNALS_FILE" ]; then
echo "Patching $QT_INTERNALS_FILE..."
if grep -q "try:" "$QT_INTERNALS_FILE" && grep -q "except (ImportError, AttributeError):" "$QT_INTERNALS_FILE" && grep -q "pyside_version_info = QtCore.__version_info__" "$QT_INTERNALS_FILE"; then
echo " ✓ Already patched (line 18 area)"
else
# Find and replace the problematic section
if grep -q "from PySide6 import __version_info__ as pyside_version_info" "$QT_INTERNALS_FILE"; then
# Using sed to replace the section
sed -i '/elif QT_LIB == .PySide6.:/,/qt_version_info = QtCore.__version_info__/c\elif QT_LIB == '\''PySide6'\'':\
try:\
from PySide6 import __version_info__ as pyside_version_info\
except (ImportError, AttributeError):\
# PySide6 doesn'\''t always have __version_info__, use QtCore'\''s instead\
pyside_version_info = QtCore.__version_info__\
qt_version_info = QtCore.__version_info__' "$QT_INTERNALS_FILE"
echo " ✓ Patched successfully"
else
echo " ⚠ Could not find the section to patch. File may have changed."
fi
fi
else
echo " ✗ File not found: $QT_INTERNALS_FILE"
fi
echo ""
echo "✓ Patching complete!"
echo "You can now test your pyqtgraph application."

Qt/PySide6 Installation Fixes for Ubuntu

This document contains fixes for Qt/PySide6 import errors and missing system libraries when running pyqtgraph applications on Ubuntu.

Quick Start

If you're encountering Qt/PySide6 import errors, follow these steps:

  1. Install system libraries (run as root/admin):

    bash fix_qt_dependencies.sh
    # or
    ./fix_qt_dependencies.sh
  2. If you still get PySide6 version attribute errors, patch pyqtgraph:

    python patch_pyqtgraph.py
    # or
    bash patch_pyqtgraph.sh

That's it! Your application should now work. See below for detailed explanations of each fix.

Error Symptoms

When running Python applications that use pyqtgraph and PySide6, you may encounter various import errors related to missing system libraries.

System Libraries to Install

Run the following command to install all required Qt/X11 dependencies:

apt-get update && apt-get install -y \
    libfontconfig1 \
    libxkbcommon0 \
    libxkbcommon-x11-0 \
    libxcb1 \
    libxcb-xinerama0 \
    libxcb-xfixes0 \
    libxcb-xinput0 \
    libxcb-xkb1 \
    libxcb-randr0 \
    libxcb-shape0 \
    libxcb-render0 \
    libxcb-render-util0 \
    libxcb-image0 \
    libxcb-icccm4 \
    libxcb-sync1 \
    libxcb-keysyms1 \
    libxcb-xtest0 \
    libxcb-shm0 \
    libxcb-util1 \
    libxcb-dri3-0 \
    libxcb-present0 \
    libx11-xcb1 \
    libxrender1 \
    libxi6 \
    libxfixes3 \
    libxcb-cursor0 \
    libdbus-1-3 \
    dbus

Specific Errors and Fixes

1. Missing libfontconfig.so.1

Error:

ImportError: libfontconfig.so.1: cannot open shared object file: No such file or directory

Fix:

apt-get install -y libfontconfig1

2. Missing libxkbcommon.so.0

Error:

ImportError: libxkbcommon.so.0: cannot open shared object file: No such file or directory

Fix:

apt-get install -y libxkbcommon0 libxkbcommon-x11-0

3. Missing libdbus-1.so.3

Error:

ImportError: libdbus-1.so.3: cannot open shared object file: No such file or directory

Fix:

apt-get install -y libdbus-1-3 dbus

4. Missing libxcb-cursor0

Error:

qt.qpa.plugin: From 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin.
qt.qpa.plugin: Could not load the Qt platform plugin "xcb"

Fix:

apt-get install -y libxcb-cursor0

5. PySide6 Missing version Attribute

Error:

AttributeError: module 'PySide6' has no attribute '__version__'

Location: pyqtgraph/Qt/__init__.py line 251

Fix: Find the line:

VERSION_INFO = 'PySide6 ' + PySide6.__version__ + ' Qt ' + QtCore.__version__

Replace with:

pyside6_version = getattr(PySide6, '__version__', QtCore.__version__)
VERSION_INFO = 'PySide6 ' + pyside6_version + ' Qt ' + QtCore.__version__

File path (adjust for your Python environment):

# Find your pyqtgraph installation:
python -c "import pyqtgraph; print(pyqtgraph.__file__)"
# Then edit: <path>/pyqtgraph/Qt/__init__.py

6. PySide6 Missing version_info Attribute

Error:

ImportError: cannot import name '__version_info__' from 'PySide6'

Location: pyqtgraph/Qt/internals.py line 18

Fix: Find the section:

elif QT_LIB == 'PySide6':
    from PySide6 import __version_info__ as pyside_version_info
    qt_version_info = QtCore.__version_info__

Replace with:

elif QT_LIB == 'PySide6':
    try:
        from PySide6 import __version_info__ as pyside_version_info
    except (ImportError, AttributeError):
        # PySide6 doesn't always have __version_info__, use QtCore's instead
        pyside_version_info = QtCore.__version_info__
    qt_version_info = QtCore.__version_info__

File path (adjust for your Python environment):

# Find your pyqtgraph installation:
python -c "import pyqtgraph; print(pyqtgraph.__file__)"
# Then edit: <path>/pyqtgraph/Qt/internals.py

Quick Fix Scripts

1. Install System Libraries

Use the provided script to install all required libraries:

bash fix_qt_dependencies.sh

Or run it directly:

./fix_qt_dependencies.sh

2. Patch pyqtgraph

After installing libraries, if you still get PySide6 version attribute errors, patch pyqtgraph:

Using Python script (recommended):

python patch_pyqtgraph.py

Or if using a specific Python:

python patch_pyqtgraph.py python3

Using bash script:

bash patch_pyqtgraph.sh

Complete Manual Installation

If you prefer to install manually, run:

apt-get update && apt-get install -y \
    libfontconfig1 \
    libxkbcommon0 \
    libxkbcommon-x11-0 \
    libxcb1 \
    libxcb-xinerama0 \
    libxcb-xfixes0 \
    libxcb-xinput0 \
    libxcb-xkb1 \
    libxcb-randr0 \
    libxcb-shape0 \
    libxcb-render0 \
    libxcb-render-util0 \
    libxcb-image0 \
    libxcb-icccm4 \
    libxcb-sync1 \
    libxcb-keysyms1 \
    libxcb-xtest0 \
    libxcb-shm0 \
    libxcb-util1 \
    libxcb-dri3-0 \
    libxcb-present0 \
    libx11-xcb1 \
    libxrender1 \
    libxi6 \
    libxfixes3 \
    libxcb-cursor0 \
    libdbus-1-3 \
    dbus

Verifying Installation

After installing libraries, verify they're available:

# Check for fontconfig
ldconfig -p | grep fontconfig

# Check for xkbcommon
ldconfig -p | grep xkbcommon

# Check for dbus
ldconfig -p | grep dbus

# Check for xcb-cursor
ldconfig -p | grep xcb-cursor

Environment

  • OS: Ubuntu 22.04 (Jammy)
  • Python: 3.11
  • Qt: PySide6 6.10.1
  • Library: pyqtgraph

Notes

  • If you're on a headless server without a display, you may need to:

    1. Use X11 forwarding if connecting via SSH
    2. Use a virtual display with xvfb-run
    3. Use the offscreen Qt platform plugin
    4. Or modify the application to work headless
  • The pyqtgraph patches are temporary workarounds for compatibility issues between pyqtgraph and certain PySide6 installations. These may be fixed in future versions of pyqtgraph.

Date Created

Created: $(date) Last Updated: $(date)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment