This trick requires rpyc.
You can install rpyc typing:
pip install rpyc
Run the code below and in another interpreter write:
import rpyc
c = rpyc.classic.connect("localhost")
c.execute("from Tkinter import Label; label=Label(app, text='a label')")
c.execute("label.pack()")
app = c.eval("app")
app.responsive_button.invoke()
  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83  | # Author: Miguel Martinez Lopez
#
# This code require rpyc.
# You can install rpyc typing:
#     pip install rpyc
#
# Run this code and in an another interactive interpreter write this:
# >>> import rpyc
# ... c = rpyc.classic.connect("localhost")
# >>> c.execute("from Tkinter import Label; label=Label(app, text='a label')")
# ... c.execute("label.pack()")
# >>> app = c.eval("app")
# >>> app.responsive_button.invoke()
from rpyc.utils.server import ThreadedServer
from rpyc.utils.classic import DEFAULT_SERVER_PORT
from rpyc.core.service import Service, ModuleNamespace
from rpyc.lib.compat import execute, is_py3k
class PublicService(Service):
    exposed_namespace = {}
    def on_connect(self):
        self._conn._config.update(dict(
            allow_all_attrs = True,
            allow_pickle = True,
            allow_getattr = True,
            allow_setattr = True,
            allow_delattr = True,
            import_custom_exceptions = True,
            instantiate_custom_exceptions = True,
            instantiate_oldstyle_exceptions = True,
        ))
        # shortcuts
        self._conn.modules = ModuleNamespace(self._conn.root.getmodule)
        self._conn.eval = self._conn.root.eval
        self._conn.execute = self._conn.root.execute
        self._conn.namespace = self._conn.root.namespace
        if is_py3k:
            self._conn.builtin = self._conn.modules.builtins
        else:
            self._conn.builtin = self._conn.modules.__builtin__
        self._conn.builtins = self._conn.builtin
    def exposed_execute(self, text):
        """execute arbitrary code (using ``exec``)"""
        execute(text, PublicService.exposed_namespace)
    def exposed_eval(self, text):
        """evaluate arbitrary code (using ``eval``)"""
        return eval(text, PublicService.exposed_namespace)
    def exposed_getmodule(self, name):
        """imports an arbitrary module"""
        return __import__(name, None, None, "*")
    def exposed_getconn(self):
        """returns the local connection instance to the other side"""
        return self._conn
if __name__ == "__main__":
    import threading  
    from Tkinter import Tk, Button
    import tkMessageBox
    class App(Tk):
        def __init__(self):
            Tk.__init__(self)
            self.responsive_button = Button(self, text="It's responsive", command = lambda:tkMessageBox.showinfo("alert window", "It's responsive!"))
            self.responsive_button.pack()
    app = App()
    # Add here all the exposed objects in the shared namespace
    PublicService.exposed_namespace = {"app":app}
    t = threading.Thread(target=lambda: ThreadedServer(PublicService, hostname = "localhost", port=DEFAULT_SERVER_PORT).start())
    t.daemon=True
    t.start()
    app.mainloop()
 | 
Download
Copy to clipboard