Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Multiple data in QT Signal
Forum Updated to NodeBB v4.3 + New Features

Multiple data in QT Signal

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 3 Posters 521 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.
  • X Offline
    X Offline
    Xav12358
    wrote on last edited by
    #1

    Hello
    I use PySide2 and I want to create a custom signal which send (str, QImage) data.

    But I get that error:

    Value types used on meta functions (including signals) need to be registered on meta type: str
    

    So I decided to use QLineEdit instead because QString doesn't exist. Here is the program I use:

    from typing import Callable, List, Dict
    
    import cv2
    from PySide2.QtGui import QImage, QPixmap
    from PySide2.QtWidgets import QWidget, QPushButton, QStackedWidget, QLineEdit, QMessageBox, QGroupBox, QLabel
    from PySide2.QtWidgets import QTreeWidget, QTreeWidgetItem, QTreeWidgetItemIterator
    from PySide2.QtCore import QFile, Signal, Slot, SIGNAL, QObject, QLine
    from PySide2 import QtCore
    from PySide2.QtUiTools import QUiLoader
    
    import os
    
    from cv_bridge import CvBridge
    
    from datalog_parser import DatalogParser
    
    
    class View(QWidget):
        classifier_groupbox : QGroupBox
        datalog_tree_widget: QTreeWidget
        environmental_groupbox : QGroupBox
    
        label_dict : Dict[str, QLabel]
        new_image : QtCore.Signal(QImage)
    
        item_signal = QtCore.Signal(QLineEdit, QImage)
    
        def __init__(self):
            self.label_dict =  dict()
    
            super(View, self).__init__()
            self.window = None
    
            QtCore.QObject.connect(self,  QtCore.SIGNAL("item_signal(QLineEdit, QImage)"), self, QtCore.SLOT("new_image_callback(QLineEdit, QImage)"))
            # self.new_image.emit("dada")
            # QObject.connect(self.new_image, SIGNAL("new_image_callback(QImage)"), self.new_image_callback)
    
            self.load_ui()
            self.classifier_groupbox = self.window.findChild(QGroupBox, 'classifier_groupbox')
            self.datalog_tree_widget = self.window.findChild(QTreeWidget, 'datalog_tree_widget')
            self.environmental_groupbox = self.window.findChild(QGroupBox, 'environmental_groupbox')
            self.label = self.window.findChild(QLabel, 'label')
            self.window.show()
    
        def load_ui(self):
                loader = QUiLoader()
                path = os.path.join(os.path.dirname(__file__), "form.ui")
                print(f'ui path {path}')
                ui_file = QFile(path)
                ui_file.open(QFile.ReadOnly)
                self.window = loader.load(ui_file, self)
                ui_file.close()
    
        @Slot( QLineEdit,QImage)
        def new_image_callback(self,line: QLineEdit, image: QImage):
            print(f'new_image_callback arg ')
    
            # self.label.setPixmap(QPixmap.fromImage(image))
    
            data_name = line.text()
            if not data_name in self.label_dict:
                self.label_dict[data_name] = QLabel()
                self.environmental_groupbox.layout().addWidget(self.label_dict[data_name])
                # self.label_dict[data_name].setPixmap(QPixmap.fromImage(q_image))
                self.label.setPixmap(QPixmap.fromImage(image))
                # print(f"image data type {type(data)} data{data}")
    
        def player_callback(self, data, data_name:str):
            print(f"here dataname {data_name}")
    
            try:
                image_data = CvBridge().imgmsg_to_cv2(data.message)
    
                q_image = QImage(image_data, image_data.shape[1], image_data.shape[0],
                                 QImage.Format_RGB888)
    
                # self.new_image.emit((q_image, data_name))
                self.emit(SIGNAL("item_signal(QLine,QImage)"),   QLineEdit(), q_image)
                # self.item_signal.emit( q_image)
    
                print("done")
    
            except Exception as err:
                print(err)
                pass
    
        def update_tree(self, datalogs: DatalogParser):
            for product, datalog_list in datalogs.datalogs.items():
                parent_item = QTreeWidgetItem(self.datalog_tree_widget)
                print(f"add {product}")
                parent_item.setText(0, product)
    
                for datalog in datalog_list:
                    print(f'child {datalog}')
                    child = QTreeWidgetItem(parent_item)
                    child.setText(0, datalog.name)
    
            self.datalog_tree_widget.expandAll()
    
    

    I get no error but no callback is called. When I use signal/slot with only one argument, it works properly but with the previous program, no error and no callback.

    Pl45m4P JonBJ 2 Replies Last reply
    0
    • X Xav12358

      Hello
      I use PySide2 and I want to create a custom signal which send (str, QImage) data.

      But I get that error:

      Value types used on meta functions (including signals) need to be registered on meta type: str
      

      So I decided to use QLineEdit instead because QString doesn't exist. Here is the program I use:

      from typing import Callable, List, Dict
      
      import cv2
      from PySide2.QtGui import QImage, QPixmap
      from PySide2.QtWidgets import QWidget, QPushButton, QStackedWidget, QLineEdit, QMessageBox, QGroupBox, QLabel
      from PySide2.QtWidgets import QTreeWidget, QTreeWidgetItem, QTreeWidgetItemIterator
      from PySide2.QtCore import QFile, Signal, Slot, SIGNAL, QObject, QLine
      from PySide2 import QtCore
      from PySide2.QtUiTools import QUiLoader
      
      import os
      
      from cv_bridge import CvBridge
      
      from datalog_parser import DatalogParser
      
      
      class View(QWidget):
          classifier_groupbox : QGroupBox
          datalog_tree_widget: QTreeWidget
          environmental_groupbox : QGroupBox
      
          label_dict : Dict[str, QLabel]
          new_image : QtCore.Signal(QImage)
      
          item_signal = QtCore.Signal(QLineEdit, QImage)
      
          def __init__(self):
              self.label_dict =  dict()
      
              super(View, self).__init__()
              self.window = None
      
              QtCore.QObject.connect(self,  QtCore.SIGNAL("item_signal(QLineEdit, QImage)"), self, QtCore.SLOT("new_image_callback(QLineEdit, QImage)"))
              # self.new_image.emit("dada")
              # QObject.connect(self.new_image, SIGNAL("new_image_callback(QImage)"), self.new_image_callback)
      
              self.load_ui()
              self.classifier_groupbox = self.window.findChild(QGroupBox, 'classifier_groupbox')
              self.datalog_tree_widget = self.window.findChild(QTreeWidget, 'datalog_tree_widget')
              self.environmental_groupbox = self.window.findChild(QGroupBox, 'environmental_groupbox')
              self.label = self.window.findChild(QLabel, 'label')
              self.window.show()
      
          def load_ui(self):
                  loader = QUiLoader()
                  path = os.path.join(os.path.dirname(__file__), "form.ui")
                  print(f'ui path {path}')
                  ui_file = QFile(path)
                  ui_file.open(QFile.ReadOnly)
                  self.window = loader.load(ui_file, self)
                  ui_file.close()
      
          @Slot( QLineEdit,QImage)
          def new_image_callback(self,line: QLineEdit, image: QImage):
              print(f'new_image_callback arg ')
      
              # self.label.setPixmap(QPixmap.fromImage(image))
      
              data_name = line.text()
              if not data_name in self.label_dict:
                  self.label_dict[data_name] = QLabel()
                  self.environmental_groupbox.layout().addWidget(self.label_dict[data_name])
                  # self.label_dict[data_name].setPixmap(QPixmap.fromImage(q_image))
                  self.label.setPixmap(QPixmap.fromImage(image))
                  # print(f"image data type {type(data)} data{data}")
      
          def player_callback(self, data, data_name:str):
              print(f"here dataname {data_name}")
      
              try:
                  image_data = CvBridge().imgmsg_to_cv2(data.message)
      
                  q_image = QImage(image_data, image_data.shape[1], image_data.shape[0],
                                   QImage.Format_RGB888)
      
                  # self.new_image.emit((q_image, data_name))
                  self.emit(SIGNAL("item_signal(QLine,QImage)"),   QLineEdit(), q_image)
                  # self.item_signal.emit( q_image)
      
                  print("done")
      
              except Exception as err:
                  print(err)
                  pass
      
          def update_tree(self, datalogs: DatalogParser):
              for product, datalog_list in datalogs.datalogs.items():
                  parent_item = QTreeWidgetItem(self.datalog_tree_widget)
                  print(f"add {product}")
                  parent_item.setText(0, product)
      
                  for datalog in datalog_list:
                      print(f'child {datalog}')
                      child = QTreeWidgetItem(parent_item)
                      child.setText(0, datalog.name)
      
              self.datalog_tree_widget.expandAll()
      
      

      I get no error but no callback is called. When I use signal/slot with only one argument, it works properly but with the previous program, no error and no callback.

      Pl45m4P Online
      Pl45m4P Online
      Pl45m4
      wrote on last edited by
      #2

      @Xav12358 said in Multiple data in QT Signal:

      need to be registered on meta type: str

      You can register the type str and then use it with signals


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      X 1 Reply Last reply
      0
      • X Xav12358

        Hello
        I use PySide2 and I want to create a custom signal which send (str, QImage) data.

        But I get that error:

        Value types used on meta functions (including signals) need to be registered on meta type: str
        

        So I decided to use QLineEdit instead because QString doesn't exist. Here is the program I use:

        from typing import Callable, List, Dict
        
        import cv2
        from PySide2.QtGui import QImage, QPixmap
        from PySide2.QtWidgets import QWidget, QPushButton, QStackedWidget, QLineEdit, QMessageBox, QGroupBox, QLabel
        from PySide2.QtWidgets import QTreeWidget, QTreeWidgetItem, QTreeWidgetItemIterator
        from PySide2.QtCore import QFile, Signal, Slot, SIGNAL, QObject, QLine
        from PySide2 import QtCore
        from PySide2.QtUiTools import QUiLoader
        
        import os
        
        from cv_bridge import CvBridge
        
        from datalog_parser import DatalogParser
        
        
        class View(QWidget):
            classifier_groupbox : QGroupBox
            datalog_tree_widget: QTreeWidget
            environmental_groupbox : QGroupBox
        
            label_dict : Dict[str, QLabel]
            new_image : QtCore.Signal(QImage)
        
            item_signal = QtCore.Signal(QLineEdit, QImage)
        
            def __init__(self):
                self.label_dict =  dict()
        
                super(View, self).__init__()
                self.window = None
        
                QtCore.QObject.connect(self,  QtCore.SIGNAL("item_signal(QLineEdit, QImage)"), self, QtCore.SLOT("new_image_callback(QLineEdit, QImage)"))
                # self.new_image.emit("dada")
                # QObject.connect(self.new_image, SIGNAL("new_image_callback(QImage)"), self.new_image_callback)
        
                self.load_ui()
                self.classifier_groupbox = self.window.findChild(QGroupBox, 'classifier_groupbox')
                self.datalog_tree_widget = self.window.findChild(QTreeWidget, 'datalog_tree_widget')
                self.environmental_groupbox = self.window.findChild(QGroupBox, 'environmental_groupbox')
                self.label = self.window.findChild(QLabel, 'label')
                self.window.show()
        
            def load_ui(self):
                    loader = QUiLoader()
                    path = os.path.join(os.path.dirname(__file__), "form.ui")
                    print(f'ui path {path}')
                    ui_file = QFile(path)
                    ui_file.open(QFile.ReadOnly)
                    self.window = loader.load(ui_file, self)
                    ui_file.close()
        
            @Slot( QLineEdit,QImage)
            def new_image_callback(self,line: QLineEdit, image: QImage):
                print(f'new_image_callback arg ')
        
                # self.label.setPixmap(QPixmap.fromImage(image))
        
                data_name = line.text()
                if not data_name in self.label_dict:
                    self.label_dict[data_name] = QLabel()
                    self.environmental_groupbox.layout().addWidget(self.label_dict[data_name])
                    # self.label_dict[data_name].setPixmap(QPixmap.fromImage(q_image))
                    self.label.setPixmap(QPixmap.fromImage(image))
                    # print(f"image data type {type(data)} data{data}")
        
            def player_callback(self, data, data_name:str):
                print(f"here dataname {data_name}")
        
                try:
                    image_data = CvBridge().imgmsg_to_cv2(data.message)
        
                    q_image = QImage(image_data, image_data.shape[1], image_data.shape[0],
                                     QImage.Format_RGB888)
        
                    # self.new_image.emit((q_image, data_name))
                    self.emit(SIGNAL("item_signal(QLine,QImage)"),   QLineEdit(), q_image)
                    # self.item_signal.emit( q_image)
        
                    print("done")
        
                except Exception as err:
                    print(err)
                    pass
        
            def update_tree(self, datalogs: DatalogParser):
                for product, datalog_list in datalogs.datalogs.items():
                    parent_item = QTreeWidgetItem(self.datalog_tree_widget)
                    print(f"add {product}")
                    parent_item.setText(0, product)
        
                    for datalog in datalog_list:
                        print(f'child {datalog}')
                        child = QTreeWidgetItem(parent_item)
                        child.setText(0, datalog.name)
        
                self.datalog_tree_widget.expandAll()
        
        

        I get no error but no callback is called. When I use signal/slot with only one argument, it works properly but with the previous program, no error and no callback.

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

        @Xav12358
        Unless Python/PySide2 magically lets you do it somehow, you cannot have QLineEdit as a parameter to anything in C++, whether signal, slot or any other function.

        QtCore.QObject.connect(self, QtCore.SIGNAL("item_signal(QLineEdit, QImage)"), self, QtCore.SLOT("new_image_callback(QLineEdit, QImage)"))

        self.emit(SIGNAL("item_signal(QLine,QImage)"), QLineEdit(), q_image)

        Do you have any evidence either of these lines work?

        You should be able to define a signal passing a str in PySide2. The Examples section at https://wiki.qt.io/Qt_for_Python_Signals_and_Slots includes:

        import sys                                                                  
        from PySide2.QtWidgets import QApplication, QPushButton                     
        from PySide2.QtCore import QObject, Signal, Slot                            
                                                                                    
        app = QApplication(sys.argv)                                                
                                                                                    
        # define a new slot that receives a string and has                          
        # 'saySomeWords' as its name                                                
        @Slot(str)                                                                  
        def say_some_words(words):                                                  
            print(words)                                                               
                                                                                    
        class Communicate(QObject):                                                 
         # create a new signal on the fly and name it 'speak'                       
         speak = Signal(str)                                                        
                                                                                    
        someone = Communicate()                                                     
        # connect signal and slot                                                   
        someone.speak.connect(say_some_words)                                         
        # emit 'speak' signal                                                         
        someone.speak.emit("Hello everybody!")
        

        So does that work for you?

        X 1 Reply Last reply
        0
        • Pl45m4P Pl45m4

          @Xav12358 said in Multiple data in QT Signal:

          need to be registered on meta type: str

          You can register the type str and then use it with signals

          X Offline
          X Offline
          Xav12358
          wrote on last edited by
          #4

          @Pl45m4
          How can I register str ?

          1 Reply Last reply
          0
          • JonBJ JonB

            @Xav12358
            Unless Python/PySide2 magically lets you do it somehow, you cannot have QLineEdit as a parameter to anything in C++, whether signal, slot or any other function.

            QtCore.QObject.connect(self, QtCore.SIGNAL("item_signal(QLineEdit, QImage)"), self, QtCore.SLOT("new_image_callback(QLineEdit, QImage)"))

            self.emit(SIGNAL("item_signal(QLine,QImage)"), QLineEdit(), q_image)

            Do you have any evidence either of these lines work?

            You should be able to define a signal passing a str in PySide2. The Examples section at https://wiki.qt.io/Qt_for_Python_Signals_and_Slots includes:

            import sys                                                                  
            from PySide2.QtWidgets import QApplication, QPushButton                     
            from PySide2.QtCore import QObject, Signal, Slot                            
                                                                                        
            app = QApplication(sys.argv)                                                
                                                                                        
            # define a new slot that receives a string and has                          
            # 'saySomeWords' as its name                                                
            @Slot(str)                                                                  
            def say_some_words(words):                                                  
                print(words)                                                               
                                                                                        
            class Communicate(QObject):                                                 
             # create a new signal on the fly and name it 'speak'                       
             speak = Signal(str)                                                        
                                                                                        
            someone = Communicate()                                                     
            # connect signal and slot                                                   
            someone.speak.connect(say_some_words)                                         
            # emit 'speak' signal                                                         
            someone.speak.emit("Hello everybody!")
            

            So does that work for you?

            X Offline
            X Offline
            Xav12358
            wrote on last edited by
            #5

            @JonB said in Multiple data in QT Signal:

            import sys
            from PySide2.QtWidgets import QApplication, QPushButton
            from PySide2.QtCore import QObject, Signal, Slot

            app = QApplication(sys.argv)

            define a new slot that receives a string and has

            'saySomeWords' as its name

            @Slot(str)
            def say_some_words(words):
            print(words)

            class Communicate(QObject):

            create a new signal on the fly and name it 'speak'

            speak = Signal(str)

            someone = Communicate()

            connect signal and slot

            someone.speak.connect(say_some_words)

            emit 'speak' signal

            someone.speak.emit("Hello everybody!")

            The example works properly. I don't understand why I get that error in my code

            Value types used on meta functions (including signals) need to be registered on meta type: str
            

            I try to send only str, and I also get the same trouble.

            X 1 Reply Last reply
            0
            • X Xav12358

              @JonB said in Multiple data in QT Signal:

              import sys
              from PySide2.QtWidgets import QApplication, QPushButton
              from PySide2.QtCore import QObject, Signal, Slot

              app = QApplication(sys.argv)

              define a new slot that receives a string and has

              'saySomeWords' as its name

              @Slot(str)
              def say_some_words(words):
              print(words)

              class Communicate(QObject):

              create a new signal on the fly and name it 'speak'

              speak = Signal(str)

              someone = Communicate()

              connect signal and slot

              someone.speak.connect(say_some_words)

              emit 'speak' signal

              someone.speak.emit("Hello everybody!")

              The example works properly. I don't understand why I get that error in my code

              Value types used on meta functions (including signals) need to be registered on meta type: str
              

              I try to send only str, and I also get the same trouble.

              X Offline
              X Offline
              Xav12358
              wrote on last edited by
              #6

              In fact, it comes from the connect signal function. When I connect the signal inside my View, it does works.

              Now I connect the signal and the slot outside the View class and it works.

              JonBJ 1 Reply Last reply
              0
              • X Xav12358

                In fact, it comes from the connect signal function. When I connect the signal inside my View, it does works.

                Now I connect the signal and the slot outside the View class and it works.

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

                @Xav12358
                So you have it working now, right? I have no idea about the QtCore.SIGNAL("...") syntax you are trying to employ, never used it and would not use it.

                I tried with your original syntax involving

                self.emit(SIGNAL("item_signal(str, QImage)"),  "hello", QImage())
                

                and got the same error as you about str needing to be registered.

                Threw that away and replaced with "proper"/"normal" syntax:

                self.item_signal.connect(self.new_image_callback)
                ...
                self.item_signal.emit("hello", QImage())
                

                and all is well.

                1 Reply Last reply
                1

                • Login

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