>
> I think maybe I misunderstood you previously. I thought we *were* talking 
> about using signals to pass data between threads? But you are asking if I 
> have done it without signals? 
>

Yes, I think this is where we may have a misunderstanding. It probably 
stems for my ambiguity in use of the words *pyqtSignal* and the custom 
implementation *Signal *(as in the above article).

What I am trying to convey, is that using *pyqtSignal* works with threads 
(as far as I can tell), but *Signal *(which I'll refer to as *CustomSignal 
*from 
now on) in an identical scenario may not.

In the above example, I provided both pyqtSignal() and CustomSignal() as 
class attributes for the thread (CustomClass being temporarily commented 
out). I was trying to illustrate that taking out pyqtSignal for 
CustomSignal would cause a crash, but I should have been more explicit, so 
apologies for this.

Now I certainly see why wanted to get to the bottom of this! :) If someone 
made the claim that using Qt's own QThreads with pyqtSignal would be cause 
for crashes, I'd be doing the same thing.

In any case, I may still be completely off in my statement regarding 
passing data across threads causing crashes, so I'm glad we're still on the 
topic. In the three examples you listed, Justin, thread-safety is already 
inherent. What I would love to get a hold on however, is whether it is 
considered safe to pass data from one thread to another, or to simply 
trigger methods from one thread *to* another, by using a class as simple as 
my CustomSignal implementation that has no regard for locking of resources 
during its run.

I'm still having crashes and occasional hang-ups in my original program, 
and made a slightly longer version of in a minimal example, but did not 
succeed in reproducing the crash. Posting as is, just in case, and will 
once again return once I know more. 


import threading


from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


PORT = 18000




class CustomSignal:


    def __init__(self):
        self.__subscribers = []
      
    def emit(self, *args, **kwargs):
        for subs in self.__subscribers:
            subs(*args, **kwargs)


    def connect(self, func):
        self.__subscribers.append(func)  
      
    def disconnect(self, func):  
        try:  
            self.__subscribers.remove(func)  
        except ValueError:  
            print('Warning: function %s not removed '
                  'from signal %s'%(func,self))




class Window(QWidget):


    rpc_show = pyqtSignal()  # Causes no crash
    # rpc_show = CustomSignal()  # Causes crash


    def __init__(self, parent=None):
        super(Window, self).__init__(parent)


        self.__rpc_server = None


        self.rpc_show.connect(self.restore)


    def start_rpc(self):
        from rpyc.utils.server import ThreadedServer
        from rpyc.core import SlaveService


        if self.__rpc_server:
            self.__rpc_server.close()
            self.__rpc_server = None


        class Service(SlaveService):
            def exposed_show(self):
                self.show_signal.emit()


        Service.show_signal = self.rpc_show
        server = ThreadedServer(Service, port=PORT, reuse_addr=True)


        self.__rpc_server = server


        def thread():
            self.__rpc_server.start()


        print("Running RPC server")
        thread = threading.Thread(target=thread, name="rpc")
        thread.daemon = True
        thread.start()


    def restore(self):
        self.activateWindow()
        self.showNormal()




def start_application():
    import sys
    app = QApplication(sys.argv)


    win = Window()
    win.show()


    win.start_rpc()


    sys.exit(app.exec_())




def request_application():
    print("Requesting a new Window")
    
    import socket
    import rpyc


    try:
        proxy = rpyc.connect('localhost', PORT)
        proxy.root.show()
        print("Restored existing instance of Window")


    except socket.error:
        print("Running new instance of Window")
        start_application()




if __name__ == '__main__':
    request_application()

-- 
You received this message because you are subscribed to the Google Groups 
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/python_inside_maya/95bdc1ec-09cd-4086-baee-21715533db5b%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to