Skip to content

Some Qt applications fail to run when using StreamController from source #33

Description

@godlike64

I'm running StreamController from source, and I just noticed that certain applications do not start. It seems related to Qt. Most applications work fine but, for example, if I start a konsole instance from a button, then try to start VLC from within that instance, I get:

loaded library "/home/godlike/virtualenv/streamcontroller/lib/python3.13/site-packages/cv2/qt/plugins/platforms/libqxcb.so"
QObject::moveToThread: Current thread (0x7f9a50000dc0) is not the object's thread (0x7f9a5000bd50).
Cannot move to target thread (0x7f9a50000dc0)

qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/home/godlike/virtualenv/streamcontroller/lib/python3.13/site-packages/cv2/qt/plugins" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: xcb, eglfs, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland.

The only other application I noticed was affected was Quassel, which is in a weird state where it still depends on Qt-5/KDE-5 bits IIUC.

I tried replacing opencv-python==4.11.0.86 with opencv-contrib-python==4.11.0.86 but the issue still persists. I'm using Gentoo with qt-6.8.3, and the opencv version installed system-wide is 4.10, everything works otherwise

Moving that libqxcb.so away from the virtualenv and re-running StreamController makes everything work correctly.

Activity

  1. dennisrijsdijk commented on Jun 30, 2025

    @dennisrijsdijk

    I think the general issue here is that the run command actions spawn processes within the venv, so anything relying on python in particular acts up. I'm able to reproduce this with lutris, which gives the following error when ran in the streamcontroller venv

    Error importing Lutris application module: No module named 'lutris'

  2. godlike64 commented on Jun 30, 2025

    @godlike64
    Author

    Maybe there should be an option to spawn the command with a clean env?

  3. dennisrijsdijk commented on Jul 1, 2025

    @dennisrijsdijk

    Maybe there should be an option to spawn the command with a clean env?

    Yeah. I can't really see a way to escape the venv though, but it can probably be done

  4. godlike64 commented on Jul 1, 2025

    @godlike64
    Author

    If I'm not mistaken, the venv is just a path prepended to PATH, and possibly other env variables get added/modified inadvertently.

    A quick test done by opening a konsole window, then checking which python version we are using:

    godlike@aiur ~ $ which python
    /home/godlike/virtualenv/streamcontroller/bin/python
    

    Which I was not originally expecting (I was expecting /usr/bin/python), but I get it now. This python interpreter gets chosen due to prepending the virtualenv directory to the PATH. A quick check from inside a python shell spawned in that konsole window shows me every env var that mentions my VIRTUAL_ENV dir:

    >>> from os import environ
    >>> for key, value in environ.items():
    ...     if environ['VIRTUAL_ENV'] in value:
    ...         print(f"{key}: {value}")
    ...         
    VIRTUAL_ENV: /home/godlike/virtualenv/streamcontroller
    QT_QPA_FONTDIR: /home/godlike/virtualenv/streamcontroller/lib/python3.13/site-packages/cv2/qt/fonts
    LD_LIBRARY_PATH: /home/godlike/virtualenv/streamcontroller/lib/python3.13/site-packages/cv2/../../lib64:
    PATH: /home/godlike/virtualenv/streamcontroller/bin:/home/godlike/virtualenv/streamcontroller/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin:/usr/lib/llvm/20/bin:/etc/eselect/wine/bin:/home/godlike/bin:/home/godlike/.local/bin/:/home/godlike/bin:/home/godlike/.local/bin/
    QT_QPA_PLATFORM_PLUGIN_PATH: /home/godlike/virtualenv/streamcontroller/lib/python3.13/site-packages/cv2/qt/plugins
    _: /home/godlike/virtualenv/streamcontroller/bin/python
    >>> 
    
    

    So it's hack-ish but:

    • Removing VIRTUAL_ENV, QT_QPA_FONTDIR, QT_QPA_PLATFORM_PLUGIN_PATH and LD_LIBRARY_PATH

    as well as:

    • Removing the VIRTUAL_ENV dir from the PATH variable

    before running a command should ensure the environment is back to 'clean'. For my particular issue with Qt applications, I just tested that popping QT_QPA_PLATFORM_PLUGIN_PATH env variable fixes the issue:

    >>> environ['QT_QPA_PLATFORM_PLUGIN_PATH']
    '/home/godlike/virtualenv/streamcontroller/lib/python3.13/site-packages/cv2/qt/plugins'
    >>> environ.pop('QT_QPA_PLATFORM_PLUGIN_PATH')
    '/home/godlike/virtualenv/streamcontroller/lib/python3.13/site-packages/cv2/qt/plugins'
    >>> subprocess.run(shlex.split('vlc'))
    VLC media player 3.0.21 Vetinari (revision )
    [00005587afc575a0] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
    [00005587afd24a80] qt interface error: Unable to load extensions module
    [00005587afce2550] main playlist: playlist is empty
    CompletedProcess(args=['vlc'], returncode=0)
    >>> 
    

    Although probably some variables should not be removed from env (as the user may have purposefully set them up, e.g. LD_LIBRARY_PATH), but their contents should be cleaned off of any mention to VIRTUAL_ENV.

  5. dennisrijsdijk commented on Jul 1, 2025

    @dennisrijsdijk

    Maybe there should be an option to spawn the command with a clean env?

    Also, I feel like it should be either default, or just forced. This has the potential to be one of those settings that causes many support requests if done wrong

  6. godlike64 commented on Jul 1, 2025

    @godlike64
    Author

    Maybe there should be an option to spawn the command with a clean env?

    Also, I feel like it should be either default, or just forced. This has the potential to be one of those settings that causes many support requests if done wrong

    Second this, default or forced would be ideal. In the meantime I can create a wrapper script to clean the env vars but it would be great not to need this.

  7. godlike64 commented on Aug 31, 2025

    @godlike64
    Author

    OK since this didn't get traction at all I decided to hack away at it. The following modification to actions/RunCommand/RunCommand.py cleans the env before launching (of course you have to import os at the top):

        152     def run_command(self, command):
        153         if command is None:
        154             return
        155 
        156         if is_in_flatpak():
        157             command = "flatpak-spawn --host " + command
        158 
        159         clean_env = os.environ.copy()
        160         virtualenv_dir = clean_env['VIRTUAL_ENV']
        161         split_path = clean_env['PATH'].split(':')
        162         new_path = []
        163         for item in split_path:
        164             if virtualenv_dir not in item:
        165                 new_path.append(item)
        166         clean_env["PATH"] = ':'.join(new_path)
        167         clean_env.pop('VIRTUAL_ENV')
        168         clean_env.pop('QT_QPA_FONTDIR')
        169         clean_env.pop('QT_QPA_PLATFORM_PLUGIN_PATH')
        170         clean_env.pop('LD_LIBRARY_PATH')
        171         if self.get_settings().get("detached", True):
        172             p = multiprocessing.Process(target=subprocess.Popen, args=[command], kwargs={"env": clean_env, "shell": True, "start_new_session": Tru    172 e, "stdin": subprocess.DEVNULL, "stdout": subprocess.DEVNULL, "stderr": subprocess.DEVNULL, "cwd": os.path.expanduser("~")})
        173             p.start()
        174             return ""
        175 
        176         result = subprocess.Popen(command, env=clean_env, shell=True, start_new_session=True, text=True, stdout=subprocess.PIPE, cwd=os.path.expan    176 duser("~"))  # If cwd is not set in the flatpak /app/bin/StreamController cannot be found
        177 
        178         result.wait()
        179         return result.communicate()[0].rstrip()
    
    

    Not nice at all I know, and hackish as hell, but it works in the meantime :)

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions