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. Slots with no types
Qt 6.11 is out! See what's new in the release blog

Slots with no types

Scheduled Pinned Locked Moved Unsolved Qt for Python
7 Posts 3 Posters 4.6k 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.
  • J Offline
    J Offline
    james2048
    wrote on last edited by
    #1

    Hi guys,

    Apologies, this is kind of a basic issue with Qt for Python but I couldn't find much online.
    I want to make a Q_INVOKABLE equivalent for Python, with no arguments.

    In this page, it says there is no Q_INVOKABLE in PySide2, I need to use Slot.
    https://doc.qt.io/qtforpython-5.12/extras/PySide.QtCore.Slot.html

    I managed to get it working when using a parameter, such as

    @Slot(int)
    def update(self, num):
        self.set_test(str(datetime.now()))
    

    However as you can see, that was using a "dummy" int, most of the time I want to call the Slot without arguments.
    All slots used in the examples I can find use parameters: https://wiki.qt.io/Qt_for_Python_Signals_and_Slots

    Basically I want to do this:

    @Slot
    def update(self):
        self.set_test(str(datetime.now()))
    

    But the error in that case, when it applies the Slot decorator, is:

    Exception has occurred: TypeError
    Unknown signal argument type: function
    

    What's the way around this? Is there like a "void" type I can add to the decorator to make the Slot able to work with no arguments?

    Thanks.

    JonBJ 1 Reply Last reply
    0
    • J james2048

      Hi guys,

      Apologies, this is kind of a basic issue with Qt for Python but I couldn't find much online.
      I want to make a Q_INVOKABLE equivalent for Python, with no arguments.

      In this page, it says there is no Q_INVOKABLE in PySide2, I need to use Slot.
      https://doc.qt.io/qtforpython-5.12/extras/PySide.QtCore.Slot.html

      I managed to get it working when using a parameter, such as

      @Slot(int)
      def update(self, num):
          self.set_test(str(datetime.now()))
      

      However as you can see, that was using a "dummy" int, most of the time I want to call the Slot without arguments.
      All slots used in the examples I can find use parameters: https://wiki.qt.io/Qt_for_Python_Signals_and_Slots

      Basically I want to do this:

      @Slot
      def update(self):
          self.set_test(str(datetime.now()))
      

      But the error in that case, when it applies the Slot decorator, is:

      Exception has occurred: TypeError
      Unknown signal argument type: function
      

      What's the way around this? Is there like a "void" type I can add to the decorator to make the Slot able to work with no arguments?

      Thanks.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @james2048

      • Show your connect() statement.
      • What is wrong then with:
      @Slot(int)
      def update(self):
          self.set_test(str(datetime.now()))
      

      So you declare the slot as taking a parameter but omit that from the def line?

      1 Reply Last reply
      1
      • J Offline
        J Offline
        james2048
        wrote on last edited by
        #3

        Hi Jon8,

        I can't declare it as Slot taking an int without matching the signature, because the decorator catches it as an error (mismatching method types).
        I am not using connect() here: a couple more details.
        I am trying to call the method from QML. Usually in C++ I would mark the method as Q_INVOKABLE and then QML is able to find it and call it.

        I create a QObject subclass which contains the Slot:

        class ViewModel(QObject):
            test_changed = Signal()
            property_changed = Signal(str)
        
            def get_test(self):
                return self._test
        
            def set_test(self, val):
                self._test = val
                self.test_changed.emit()
                self.property_changed.emit("test")
        
            test = Property(str, get_test, set_test, notify=test_changed)
        
            def __init__(self):
                QObject.__init__(self)
                self.update(0)
        
            # Here is the Slot I'd like to be able to declare without arguments.
            @Slot(int)
            def update(self, dummy):
                self.set_test(str(datetime.now()))
        

        I instantiate it and register it to the QML engine:

        vm = ViewModel()
        engine.rootContext().setContextProperty("viewModel", vm)
        

        Then I use it from here in the QML (rest of layout ommitted):

        Text {
            text: viewModel.test
        }
        
        Button {
            text: "Update"
            onClicked: viewModel.update(0)
        }
        

        So ideally I'd like not to have to write update(0) or insert a dummy value and so on when I don't need the parameter.
        Is that possible at all? I must be missing something.

        Thanks.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          james2048
          wrote on last edited by
          #4

          I found the way to do it.
          I was sure this was able to be expressed in PySide2!

          I looked at the .pyi file and I saw it is looking for a list of types as arguments, with no default arguments.
          So I tried putting "None" as the argument to it, and it worked.
          Ideally if they had a default argument one could just write @Slot but for now this is needed. Maybe I could write in the bug tracker as an improvement.

          Now this works:

          @Slot(None)
          def update(self):
              self.set_test(str(datetime.now()))
          

          And now this QML also works:

          onClicked: viewModel.update()
          
          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Hi,

            AFAIR, just use @Slot() and you should be good to go. This is a parametrized decorator, you can't just remove the parenthesis.

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

            J 1 Reply Last reply
            2
            • SGaistS SGaist

              Hi,

              AFAIR, just use @Slot() and you should be good to go. This is a parametrized decorator, you can't just remove the parenthesis.

              J Offline
              J Offline
              james2048
              wrote on last edited by
              #6

              @SGaist
              Thanks, this exposes a preconception I had about Python decorators! I though @Slot == @Slot() and this is obviously not right.

              It does work with @Slot().

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

                Indeed they are different, one takes parameters and the other does not. But even if you have all parameters with default values, you can not bypass the use of the parenthesis for proper initialization.

                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