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()
|