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. Custom Return Type Signals Not Received in QML Despite Being Emitted
Forum Updated to NodeBB v4.3 + New Features

Custom Return Type Signals Not Received in QML Despite Being Emitted

Scheduled Pinned Locked Moved Solved Qt for Python
5 Posts 3 Posters 417 Views 2 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.
  • CKurduC Offline
    CKurduC Offline
    CKurdu
    wrote on last edited by
    #1

    I'm working on a PySide6 project where I need to return a custom type from a Python method to QML. I've registered the type and can see the signals being emitted in Python, but they're not being received in QML.

    Here's my minimal example:

    # data_response.py
    from PySide6.QtCore import QObject, Signal, Property
    
    class DataResponse(QObject):
        dataReceived = Signal(str)
        errorOccurred = Signal(str)
        
        def __init__(self, parent=None):
            super().__init__(parent)
            self._data = ""
            
        def set_data(self, data: str):
            print(f"Setting data: {data}")  # This prints
            self.dataReceived.emit(data)
            print("Signal emitted")         # This prints
    
    # data_api.py
    from PySide6.QtCore import QObject, Slot
    from PySide6.QtQml import qmlRegisterUncreatableType
    
    class DataApi(QObject):
        def __init__(self, parent=None):
            super().__init__(parent)
            qmlRegisterUncreatableType(
                DataResponse, 
                "CustomTypes", 
                1, 
                0, 
                "DataResponse",
                "DataResponse cannot be created from QML"
            )
        
        @Slot(str, result=DataResponse)
        def fetch_data(self, query: str) -> DataResponse:
            response = DataResponse(self)
            response.set_data(f"Data for query: {query}")
            return response
    

    QML usage:

    import QtQuick
    import CustomTypes 1.0
    
    Item {
        Button {
            onClicked: {
                var response = dataApi.fetch_data("test")
                response.dataReceived.connect(function(data) {
                    console.log("Data received:", data)  // Never prints
                })
            }
        }
    }
    

    Debug output shows:

    Setting data: Data for query: test
    Signal emitted
    

    The Python side is clearly emitting the signal (and I can verify this with debug prints), but the QML side never receives it. I suspect this might be related to signal timing or object lifetime, but I'm not sure.

    What am I missing? How can I properly handle signals from a returned Python object in QML?

    Environment:

    • Python 3.10
    • PySide6 6.7.2
    • Debian 12

    Any help would be greatly appreciated!

    You reap what you sow it

    1 Reply Last reply
    1
    • GrecKoG Offline
      GrecKoG Offline
      GrecKo
      Qt Champions 2018
      wrote on last edited by GrecKo
      #3

      Slots can have return values (so can signals, but let's not get there), and there doesn't seem to be an @Invokable decorator in Python.
      The QML code in the onClicked signal handler has the correct syntax for imperatively connecting a signal to a function in QML ( https://doc.qt.io/qt-6/qtqml-syntax-signals.html#connecting-signals-to-methods-and-signals ).

      There doesn't seem to be much wrong in the current code.
      What does the connect call returns? Is the response object returned by fetch_data valid in QML? Can you try to print it? And add a property to it and print that too?

      EDIT: Reading your code again, it just appears that the dataReceived signal is emitted before your fetch_data returns (and thus before QML can establish the connection).

      SGaistS 1 Reply Last reply
      2
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by SGaist
        #2

        Hi,

        First thing: slots, in principle, do not have return values, if you want that, use invokable methods.

        Python is an exception it seems to this rule when implementing invokable functions. Found it in the documentation

        What strikes me in your code is that you are using Python syntax in your QML code.

        It seems you want to implement your own QNetworkAccessManager class, is that correct ?

        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
        1
        • GrecKoG Offline
          GrecKoG Offline
          GrecKo
          Qt Champions 2018
          wrote on last edited by GrecKo
          #3

          Slots can have return values (so can signals, but let's not get there), and there doesn't seem to be an @Invokable decorator in Python.
          The QML code in the onClicked signal handler has the correct syntax for imperatively connecting a signal to a function in QML ( https://doc.qt.io/qt-6/qtqml-syntax-signals.html#connecting-signals-to-methods-and-signals ).

          There doesn't seem to be much wrong in the current code.
          What does the connect call returns? Is the response object returned by fetch_data valid in QML? Can you try to print it? And add a property to it and print that too?

          EDIT: Reading your code again, it just appears that the dataReceived signal is emitted before your fetch_data returns (and thus before QML can establish the connection).

          SGaistS 1 Reply Last reply
          2
          • GrecKoG GrecKo

            Slots can have return values (so can signals, but let's not get there), and there doesn't seem to be an @Invokable decorator in Python.
            The QML code in the onClicked signal handler has the correct syntax for imperatively connecting a signal to a function in QML ( https://doc.qt.io/qt-6/qtqml-syntax-signals.html#connecting-signals-to-methods-and-signals ).

            There doesn't seem to be much wrong in the current code.
            What does the connect call returns? Is the response object returned by fetch_data valid in QML? Can you try to print it? And add a property to it and print that too?

            EDIT: Reading your code again, it just appears that the dataReceived signal is emitted before your fetch_data returns (and thus before QML can establish the connection).

            SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by SGaist
            #4

            @GrecKo while I agree on the fact that slot can have return value, it's really not how they are usually implemented nor used hence I wouldn't go that route as mostly nobody would be using them that way. I reworded my answer.

            Ok, so, doing some more searches, it seems the correct way to do Invokable in Python is to, in fact, use slots with return value. It's in the documentation.

            Thanks for the pointer on the declarative connection style. It's something I either missed or had forgotten about.

            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
            1
            • CKurduC Offline
              CKurduC Offline
              CKurdu
              wrote on last edited by
              #5

              Thank you for your answers,
              It appears I made a simple mistake in the actual code.
              The garbage collector removed the object. Additionally, when an error occurs, it emits a signal immediately, and my connection isn't functioning as @GrecKo described.

              You reap what you sow it

              1 Reply Last reply
              0
              • CKurduC CKurdu has marked this topic as solved on

              • Login

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