Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Issue with Multiple QML Engines and Signal-Slot Connections

Issue with Multiple QML Engines and Signal-Slot Connections

Scheduled Pinned Locked Moved Unsolved Qt for Python
2 Posts 2 Posters 511 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    IGuessIJustStoopid
    wrote on last edited by IGuessIJustStoopid
    #1

    Hi everyone,

    I'm encountering an issue with my Qt6/PySide6 application where I'm using multiple QML engines to display content on multiple screens. I'm trying to achieve independent video playback on each screen, but I'm running into a problem where the same video plays on all displays despite setting different sources.

    Here's a simplified overview of my application structure:

    main py: Creates a QApplication and multiple QQmlApplicationEngine instances, one for each connected display.

    NetworkManager: Handles network requests to fetch media information from a server.

    MediaManager: Processes the server response, downloads media files, and updates a configuration file with media paths for each screen.

    main.qml: Contains the UI elements, including a Video object for video playback.

    Initial Approach (Problem):
    Initially, I had a single instance of MediaManager that was shared across all QML engines. The NetworkManager would emit a requestFinished signal with the server response, and the MediaManager would handle the response, download the media, and update the configuration. However, this resulted in the same video being played on all displays because the mediaReady signal (emitted by MediaManager) was received by all QML engines.

    Modified Approach:
    To address this, I modified the main.py to create a separate instance of MediaManager for each QML engine within the loop that creates the engines. This ensures that each display has its own independent media manager and configuration.

    Here's a snippet of the relevant code:

    Before (Single MediaManager):

    class DisplayApp(QApplication):
        def __init__(self, argv):
            # ...
            self.media_manager = MediaManager()  # Single instance
    
            # ... 
            for index, screen in enumerate(self.screens()):
                engine = QQmlApplicationEngine()
                # ...
                engine.rootContext().setContextProperty("mediaManager", self.media_manager)  # Shared instance
                # ...
                self.network_manager.requestFinished.connect(self.media_manager.save_media_info)
                # ...
    

    After (Separate MediaManager Instances):

    class DisplayApp(QApplication):
        def __init__(self, argv):
            # ...
            for index, screen in enumerate(self.screens()):
                engine = QQmlApplicationEngine()
                # ...
                media_manager = MediaManager()  # Separate instance for each engine
                engine.rootContext().setContextProperty("mediaManager", media_manager)
                # ...
                self.network_manager.requestFinished.connect(media_manager.save_media_info)
                # ...
    

    However, after making this change, the signal emission seems to have stopped working. The MediaManager methods are no longer being triggered, and video playback functionality is not working as expected.

    I've verified that:
    The file paths are correct and include the file:// scheme.

    The signal-slot connections are established for each individual MediaManager instance within the loop in main.py.

    The context property names match between main . py and the QML code.

    Despite these checks, the signal emission issue persists. I would be grateful for any insights or suggestions on what might be causing this problem and how to further debug it.

    Thank you!

    Here is the simplified version of my code.
    My network_manager.py which works and emits the signal which is not working anymore:

    from PySide6.QtCore import QObject, Signal
    from PySide6.QtNetwork import QNetworkAccessManager
    
    class NetworkManager(QObject):
        requestFinished = Signal(str)
    
        def __init__(self):
            super().__init__()
            self.manager = QNetworkAccessManager()
            self.manager.finished.connect(self.handle_response)
    
        def submit_pin(self, pin, screen_index):
            # (URL construction omitted for privacy)
            request = QNetworkRequest(QUrl(url))
            self.manager.get(request)  # Send the request
    
        def handle_response(self):
            reply = self.sender()
            if not isinstance(reply, QNetworkReply):
                return
    
            if reply.error() != QNetworkReply.NoError:
                print("Network Error:", reply.errorString())
                self.requestFinished.emit("Error")
            else:
                response_data = reply.readAll().data().decode("utf-8")
                print("Server Response:", response_data)
                self.requestFinished.emit(response_data)
    
            reply.deleteLater()
    

    and my media_manager.py:

    import json
    import os
    from PySide6.QtCore import QObject, Slot, Signal
    from PySide6.QtNetwork import QNetworkAccessManager
    
    class MediaManager(QObject):
        mediaSaved = Signal(bool)
        mediaReady = Signal(str)
    
        def __init__(self):
            super().__init__()
            self.manager = QNetworkAccessManager(self)
            self.config_file = "autoload.cfg"
            self.media_folder = "media"
    
            # ... (folder creation) ... 
    
        @Slot(str)
        def save_media_info(self, response_data):
            # ... (JSON parsing and PIN/screenIndex extraction) ... 
    
            # ... (filename generation and file_path construction) ...
    
            self.download_media(media_url, file_path)
    
            # ... (update config file) ...
    
            self.mediaSaved.emit(True) 
    
        def download_media(self, url, file_path):
            request = QNetworkRequest(QUrl(url))
            reply = self.manager.get(request)
            reply.finished.connect(lambda: self.handle_download_finished(reply, file_path))
    
        def handle_download_finished(self, reply, file_path):
            # ... (download handling and mediaReady emission) ...
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      One thing to test: keep a reference of your MediaManager objects in your application class. I am currently wondering whether the Python garbage collection is at work with your issue.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved