Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: threaded-client
Fetching contributors…

Cannot retrieve contributors at this time

executable file 101 lines (70 sloc) 2.604 kb
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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
#!/usr/bin/env python

"""
An example of using GTK from Emacs.

* Manipulate GTK window from Emacs:

Python server exposes remote methods called `destroy` and
`set_button_label`. You can call these methods from Emacs by
``M-x pyepc-sample-gtk-destroy`` and
``M-x pyepc-sample-gtk-set-button-label``.

- `destroy` (`pyepc-sample-gtk-destroy`):
Close GTK window from Emacs command

- `set_button_label` (`pyepc-sample-gtk-set-button-label`):
Change GUI button label from Emacs command.

* Manipulate Emacs from GTK GUI.

Emacs client exposes a remote method called `message`.

- `message`:
Emacs prints message in minibuffer when GUI button is clicked.

"""

import threading
import logging

import pygtk
pygtk.require('2.0')
import gtk
import gobject

from epc.server import ThreadingEPCServer, setuplogfile


class SampleGTKServer(object):

    def __init__(self):
        self.setup_gtk()
        self.setup_epc()

    def setup_gtk(self):
        gtk.threads_init()

        # Create a new window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)

        # Quit when window is closed
        self.window.connect("destroy", self.destroy)

        # Creates a new button
        self.button = gtk.Button("Push me!")
        self.button.connect("clicked", self.clicked, None)

        # Show widgets and window
        self.window.add(self.button)
        self.button.show()
        self.window.show()

    def setup_epc(self):
        self.server = ThreadingEPCServer(('localhost', 0))

        # Setup logger
        self.server.logger.setLevel(logging.DEBUG)
        setuplogfile()

        # Setup server thread
        self.server_thread = threading.Thread(target=self.server.serve_forever)
        self.server_thread.allow_reuse_address = True

        # Define and register RPC functions
        def destroy():
            gobject.idle_add(gtk.Widget.destroy, self.window)

        def set_button_label(label):
            gobject.idle_add(self.button.set_label, label)

        self.server.register_function(destroy)
        self.server.register_function(set_button_label)

    def clicked(self, widget, data=None):
        handler = self.server.clients[0]
        message = "Button '{0}' is clicked!".format(self.button.get_label())
        handler.call('message', [message])

    def destroy(self, widget, data=None):
        self.server.shutdown()
        gtk.main_quit()

    def main(self):
        self.server_thread.start()
        self.server.print_port()
        gtk.main()


if __name__ == "__main__":
    server = SampleGTKServer()
    server.main()
Something went wrong with that request. Please try again.