I try to use QRemoteObjects
to share more than two objects but
i got "Dynamic metaobject is not assigned" warning while run client.py example, and i can't find out what happened, my example work fine, can anyone give me some advices?
server.py
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtRemoteObjects import *
from faker import Faker
fake = Faker()
class Name(QObject):
sig_name = pyqtSignal(str)
def __init__(self):
super().__init__()
self.name = ''
self.startTimer(1000)
def timerEvent(self, event):
self.name = fake.name()
self.sig_name.emit(self.name)
class Email(QObject):
sig_email = pyqtSignal(str)
def __init__(self):
super().__init__()
self.startTimer(1000)
def timerEvent(self, event):
self.sig_email.emit(fake.email())
class Server(QObject):
def __init__(self):
super().__init__()
self.name = Name()
self.email = Email()
host = QRemoteObjectHost(QUrl('local:server'), self)
r1 = host.enableRemoting(self.name, 'name')
r2 = host.enableRemoting(self.email, 'email')
print([r1, r2])
def print_name(self, x):
print(x)
app = QCoreApplication([])
s = Server()
app.exec()
client.py
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtRemoteObjects import *
class Client(QObject):
def __init__(self):
super().__init__()
node = QRemoteObjectNode(self)
node.connectToNode(QUrl("local:server"))
self.remote_name = node.acquireDynamic('name')
self.remote_email = node.acquireDynamic('email')
self.remote_name.initialized.connect(self.onInitName)
self.remote_email.initialized.connect(self.onInitEmail)
def onInitName(self):
self.remote_name.sig_name.connect(self.print_info)
def onInitEmail(self):
self.remote_email.sig_email.connect(self.print_info)
def print_info(self, x):
print('-->:', x)
app = QCoreApplication([])
c = Client()
app.exec()
After i run python server.py
in terminal one and run python client.py
in terminal two.
I got some warning as below in terminal two.
In C++ you can purchase the replica using 2 methods:
QRemoteObjectNode::acquire()
:
SimpleSwitchReplica *rep = repNode.acquire<SimpleSwitchReplica>("SimpleSwitch"));
QRemoteObjectNode::acquireDynamic()
:
QRemoteObjectDynamicReplica *rep = repNode.acquireDynamic("SimpleSwitch");
As the second method is observed, a QRemoteObjectDynamicReplica
is used which is an object that is class created on-the-fly by copying the properties, signals and slots but does not contain all the information of the node class so it is not an exact copy so which has disadvantages as the docs points out:
There are generated replicas (replicas having the header files produced by the Replica Compiler), and dynamic replicas, which are generated on-the-fly. This is the class for the dynamic type of replica.
When the connection to the Source object is made, the initialization step passes the current property values (see Replica Initialization). In a DynamicReplica, the property/signal/slot details are also sent, allowing the replica object to be created on-the-fly. This can be conventient in QML or scripting, but has two primary disadvantages. First, the object is in effect "empty" until it is successfully initialized by the Source. Second, in C++, calls must be made using QMetaObject::invokeMethod(), as the moc generated lookup will not be available.
(emphasis mine)
And in the case of PyQt, it only supports the second method, so you get that warning message indicating possible problems.