[pyar] Aplicacion embebida en Python3 GTK
Gustavo Ibarra
ibarrags en gmail.com
Mar Feb 2 20:11:40 ART 2016
On Tue, Feb 2, 2016 at 4:33 PM, roberto <cygnus2k en gmail.com> wrote:
> Hola, estoy desarrollando una app para administrar la aplicacion Putty (SSH
> and telnet client) en solapas, puesto que no hay ninguna app parecida en
> linux (en windows hay varias) .
Si estas buscando una aplicación para administrar varias terminales(no
dejan de ser ventanas :D) desde una sola terminal, quizas esto te
pueda ser de utilidad: http://www.gnu.org/software/screen/
> Soy principiante, por lo que mucho de mi codigo seguro esta mal, pero lo
> importante ahora es que ahora ya puedo embeber la aplicacion en un objeto
> StackSwitcher, y las nuevas terminales tambien. El tema es que una vez
> abierto el putty no tengo el foco inmediato en el. Intente usar la funcion
> grab_focus() y no hace nada, tengo que tocar la tecla de direcion ABAJO, 2
> veces para que me de el foco. Mi duda tambien es que si el "widget" en el
> que esta embebido es el que trato como socket o es un sub-objeto, de
> cualquier manera tengo muy poca documentacion sobre estos objetos.
>
> from gi.repository import Gtk
> from gi.repository import Gio
> import sys
> import os
> import urllib.parse
> import shlex, subprocess
> import time
>
> class VentanaPrincipal(Gtk.Window):
> def __init__(self):
> Gtk.Window.__init__(self, title="Putty Tray")
> self.set_border_width(10)
> self.set_default_size(800, 600)
>
> self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
> self.add(self.vbox)
> self.stack = Gtk.Stack()
>
> self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
> self.stack.set_transition_duration(1000)
>
> self.stack_switcher = Gtk.StackSwitcher()
> self.stack_switcher.set_stack(self.stack)
>
> self.vbox.pack_start(self.stack_switcher, False, True, 0)
> self.vbox.pack_start(self.stack, True, True, 0)
>
> def plug_event(self, garb):
> print("Un putty fue insertado")
>
> def addPutty(self, pid, session):
> print("Putty window_id: " + str(pid))
> socket = Gtk.Socket()
> socket.connect("plug-added", self.plug_event)
> self.stack.add_titled(socket, session, session)
>
> socket.add_id(pid)
> socket.grab_focus()
> self.show_all()
> socket.grab_focus()
>
> class IconoTray:
> pids = []
> def __init__(self, iconname):
> self.menu = Gtk.Menu()
>
> APPIND_SUPPORT = 1
> try: from gi.repository import AppIndicator3
> except: APPIND_SUPPORT = 0
>
> if APPIND_SUPPORT == 1:
> self.ind = AppIndicator3.Indicator.new("putty", iconname,
> AppIndicator3.IndicatorCategory.APPLICATION_STATUS)
> self.ind.set_status (AppIndicator3.IndicatorStatus.ACTIVE)
> self.ind.set_menu(self.menu)
> else:
> self.myStatusIcon = Gtk.StatusIcon()
> self.myStatusIcon.set_from_icon_name(iconname)
> self.myStatusIcon.connect('popup-menu',
> self.right_click_event_statusicon)
>
> def add_seperator(self):
> aMenuitem = Gtk.SeparatorMenuItem()
> self.menu.append(aMenuitem)
> self.menu.show_all()
>
> def get_tray_menu(self):
> return self.menu
>
> def right_click_event_statusicon(self, icon, button, time):
> self.get_tray_menu()
>
> def pos(menu, aicon):
> return (Gtk.StatusIcon.position_menu(menu, aicon))
>
> self.menu.popup(None, None, pos, icon, button, time)
>
> def display_message_dialog(self, message_type):
> messagedialog = Gtk.MessageDialog(message_format="MessageDialog")
> messagedialog.set_property("message-type", message_type)
>
> messagedialog.run()
> messagedialog.destroy()
>
> def add_menu_item(self, command, title, session=""):
> aMenuitem = Gtk.MenuItem()
> aMenuitem.set_label(title)
> aMenuitem.connect("activate", command, session)
>
> self.menu.append(aMenuitem)
> self.menu.show_all()
>
> def add_menu_item_s(self, command, title, session=""):
> aMenuitem = Gtk.MenuItem()
> aMenuitem.set_label(title)
> aMenuitem.connect("activate", command,session)
> self.menu_sessions.append(aMenuitem)
> self.menu_sessions.show_all()
> self.menu.show_all()
>
> def addpid(self, par, p_session):
> aMenuitem = Gtk.MenuItem()
> aMenuitem.set_label(par)
> self.menu.append(aMenuitem)
> self.menu.show_all()
>
> def children_pid(self, ppid):
> import subprocess as SP
> print("Parent PID: "+str(ppid))
> proc = SP.Popen('ps -o pid,ppid ax | grep "'+str(ppid)+'"',
> shell=True, stdout=SP.PIPE)
> pidppid = [x.split() for x in proc.communicate()[0].split(b"\n") if
> x]
> return list(int(p) for p, pp in pidppid if int(pp) == ppid)
>
> def new_session(self, par, p_session):
> if len(self.pids) < 1:
> self.appmain = VentanaPrincipal()
> self.appmain.show_all()
>
> p = subprocess.Popen('/usr/bin/putty -load '+ p_session, shell=True,
> stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
> childrenpid=self.children_pid(p.pid)
> print(childrenpid[0])
> self.pids.append(childrenpid)
>
> #Relacionar PID con el window_id
> #xwininfo -tree -root | grep -i putty -> All_Windows_ID
> #xprop -id Windows_ID[i] | grep _NET_WM_PID(CARDINAL)
> #_NET_WM_PID(CARDINAL) = 21151
>
> print ("PID: " + str(childrenpid[0]))
> time.sleep(1)
> proc =
> subprocess.Popen("/home/roberto/Projects/puttytray/find_windows.sh "+
> str(childrenpid[0]), shell=True, stdout=subprocess.PIPE)
> proc.wait()
> for line in proc.stdout:
> print (b"test:" + line.rstrip())
> win_id_hex=line.strip()
> win_id = int(win_id_hex, 0)
> print("WIN_ID: " + str(win_id))
> self.appmain.addPutty(win_id, p_session)
> self.add_menu_item( self.addpid, str(p.pid), "\""+p_session+"\"")
>
> def add_menu_sessions(self):
> self.menu_sessions = Gtk.Menu()
> submenuitem = Gtk.MenuItem(label="Sessiones")
> submenuitem.set_submenu(self.menu_sessions)
> self.menu.append(submenuitem)
>
> def quit(self, par, p_session):
> Gtk.main_quit()
>
> def main():
> app = IconoTray("putty")
> app.add_menu_sessions()
> dirputty = "/home/roberto/.putty/sessions"
> onlyfiles = [f for f in os.listdir(dirputty) if
> os.path.isfile(os.path.join(dirputty, f))]
> onlyfiles.sort()
> for filessessionhtml in onlyfiles:
> filessession = urllib.parse.unquote(filessessionhtml)
> app.add_menu_item_s( app.new_session, filessession,
> "\""+filessession+"\"")
>
> app.add_seperator()
> app.add_menu_item( app.quit, "Salir", "Salir")
>
> if __name__ == '__main__':
> Gtk.main()
>
> main()
>
> Desde ya muchas gracias
>
> _______________________________________________
> pyar mailing list pyar en python.org.ar
> http://listas.python.org.ar/listinfo/pyar
>
> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>
> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
> Argentina - http://www.usla.org.ar
Más información sobre la lista de distribución pyar