我有两个类A和B,从A到B发出信号。当我尝试打印信号对象时,它给了我<bound PYQT_SIGNAL mysignal of RowProduct object at 0x7f65e800aa60>
您能帮我解决为什么会发生这种情况,以及如何将对象读取为有效的python数据类型,以便可以使用所需的方法吗?
import sys
from PyQt5.QtCore import QSize, pyqtSignal
from PyQt5.QtWidgets import *
class A(QWidget):
my_signal = pyqtSignal(str)
def __init__(self, parent=None):
super(A, self).__init__(parent)
self.gridlay = QGridLayout(self)
self.btn = QPushButton('10')
self.btn.setMinimumSize(QSize(150, 150))
self.btn.clicked.connect(self.send_data)
self.gridlay.addWidget(self.btn, 0, 0, 1, 1)
self.btn_1 = QPushButton('20')
self.btn_1.setMinimumSize(QSize(150, 150))
self.btn_1.clicked.connect(self.send_data)
self.gridlay.addWidget(self.btn_1, 0, 1, 1, 1)
self.btn_2 = QPushButton('30')
self.btn_2.setMinimumSize(QSize(150, 150))
self.btn_2.clicked.connect(self.send_data)
self.gridlay.addWidget(self.btn_2, 1, 0, 1, 2)
def send_data(self):
sender = self.sender()
self.my_signal.emit(sender.text())
print(self.my_signal)
self.close()
class B(QWidget):
product = ''
def __init__(self, parent=None):
super(B, self).__init__(parent)
self.grid = QGridLayout(self)
self.la = QLabel()
self.la.setMinimumSize(200, 50)
self.grid.addWidget(self.la, 0, 0, 1, 1)
self.btn = QPushButton('click me i am the main window')
self.btn.setMinimumSize(QSize(200, 150))
self.btn.clicked.connect(self.fire)
self.grid.addWidget(self.btn, 1, 0, 1, 1)
self.con = A()
self.con.my_signal.connect(self.signal_receiver)
def fire(self):
self.con.show()
def signal_receiver(self, incoming_signal):
self.product = incoming_signal
print(self.product)
self.la.setText(self.product)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = B()
w.show()
sys.exit(app.exec_())
更新,这是我的代码的最小可复制示例,此代码可以正常工作,而在主代码中,发出的对象未连接到所需的方法。
这是python 3.6的示例。示例使用协程和事件循环创建多个示例。您可以修改signal_slot方法以打印信号对象以重现您的情况
from PyQt5.QtCore import (pyqtSignal, pyqtSlot, QObject)
import asyncio
import datetime
#custom DataModel to pass as signal parameter
class CustomObject:
_id = None
_name = None
_date = None
def __init__(self, _id, _name, _date):
self._id = _id
self._name = _name
self._date = _date
@property
def id(self):
return self._id
@property
def name(self):
return self._name
@property
def date(self):
return self._date
#classes which leverage signal should be inherited from QObject
class A(QObject):
signal = pyqtSignal(object)
def __init__(self):
try:
# init line chould have been missed in your case
QObject.__init__(self)
print("class A initialized")
except Exception as e:
print(e)
def method_call(self, _custom_object):
self.signal.emit(_custom_object)
#classes which leverage signal should be inherited from QObject
class B(QObject):
def __init__(self, _custom_object):
try:
# init line chould have been missed in your case
QObject.__init__(self)
print("class B initialized")
a = A()
# slot method should still work if not decorated with slot
# its provided here with slot decorator as best practice
a.signal.connect(self.slot)
a.method_call(_custom_object)
except Exception as e:
print(e)
@pyqtSlot(object)
def slot(self, _custom_object):
if isinstance(_custom_object, CustomObject):
print(f"id: {_custom_object.id}, name:{_custom_object.name}, date: {_custom_object.date}")
# sample coroutine as infinite reproducible call
@asyncio.coroutine
async def signal_slot():
c = 0
while True:
c = c + 1
custom_object = CustomObject(c, f"object {c}", datetime.datetime.now())
b = B(_custom_object=custom_object)
await asyncio.sleep(1)
if __name__ == "__main__":
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(signal_slot())
输出
class B initialized
class A initialized
id: 1, name:object 1, date: 2019-12-29 15:37:15.240500
class B initialized
class A initialized
id: 2, name:object 2, date: 2019-12-29 15:37:16.240738
class B initialized
class A initialized
id: 3, name:object 3, date: 2019-12-29 15:37:17.241039
class B initialized
class A initialized
id: 4, name:object 4, date: 2019-12-29 15:37:18.241728
class B initialized
class A initialized
id: 5, name:object 5, date: 2019-12-29 15:37:19.242258
....
....