Multiple data in QT Signal
-
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.
-
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.
-
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.
@Xav12358
Unless Python/PySide2 magically lets you do it somehow, you cannot haveQLineEdit
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?
-
@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 -
@Xav12358
Unless Python/PySide2 magically lets you do it somehow, you cannot haveQLineEdit
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?
@JonB said in Multiple data in QT Signal:
import sys
from PySide2.QtWidgets import QApplication, QPushButton
from PySide2.QtCore import QObject, Signal, Slotapp = 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.
-
@JonB said in Multiple data in QT Signal:
import sys
from PySide2.QtWidgets import QApplication, QPushButton
from PySide2.QtCore import QObject, Signal, Slotapp = 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.
-
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.
@Xav12358
So you have it working now, right? I have no idea about theQtCore.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.