2013-04-22 23 views
8

Sto lavorando a un programma che accetta un input dell'utente e genera un output come trama di proiezione di mappe. La libreria di proiezione di mappe più semplice che ho trovato è matplotlib-basemap, scritto in python un linguaggio con cui non sono molto più familiare (lavoro su Java). Ho scritto l'interfaccia utente in Java. Attualmente sto eseguendo il codice Python e inviando matrici di comando con dati usando il comando Runtime ed exec() chiamando il file ".py". Questo prelude il comando e mostra la trama come una finestra separata.GUI Python da Java

La mia domanda è questa: È possibile incorporare questa mappa di base (funzioni interattive con zoom) su un Jpanel? O su una GUI Python che può quindi essere incorporata su un JPanel? So che posso salvare l'immagine generata da matplotlib come un file che può essere corretto su un pannello, ma non sarà interattivo, quindi le funzionalità di Zoom non saranno disponibili. O sta utilizzando uno strumento basato su Java piuttosto che basemap è più appropriato? (Non ho trovato alcun buono)

---- Modifica il 22 maggio 2013 ------

Jython è non una soluzione come matplotlib è incompatibile con esso. Fare tutto in python sono d'accordo, ma è ciò con cui devo lavorare.

Jar JACOB: non è stato possibile trovare un codice di esempio che mostra come incorporare un'applicazione separata (mappa di base) su JPanel o JFrame.

Attualmente sto pianificando di incorporare la mappa di base in una GUI wxpython e quindi utilizzare i socket per comunicare tra le due lingue.

Socket TCP/IP con Server Java e Client Python.

+0

Correlato: http://stackoverflow.com/questions/309158/embedding-an-application-inside-another-application – hyde

+0

Fornire parte del codice per sperimentare. – utapyngo

+0

Non una soluzione multipiattaforma ma su Windows questo dovrebbe aiutare: [Funzione SetParent] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633541%28v=vs.85%29.aspx) – utapyngo

risposta

2

Questo è se sei aperto a nuove idee e imparare nuove cose.
Non è una soluzione per il tuo problema specifico che vuoi unire due lingue, questo è un rimpiazzo per quell'idea di incorporare tutto in Python.

#!/usr/bin/python 
import pyglet 
from time import time, sleep 

class Window(pyglet.window.Window): 
    def __init__(self): 
     super(Window, self).__init__(vsync = False) 
     self.alive = 1 

     self.click = None 
     self.drag = False 

     with open('map.png', 'rb') as fh: 
      self.geodata_image = pyglet.image.load('map.png', file=fh) 
      self.geo_info = self.geodata_image.width, self.geodata_image.height 

    def on_draw(self): 
     self.render() 

    def on_mouse_press(self, x, y, button, modifiers): 
     self.click = x,y 

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): 
     if self.click: 
      self.drag = True 
      print 'Drag offset:',(dx,dy) 

    def on_mouse_release(self, x, y, button, modifiers): 
     if not self.drag and self.click: 
      print 'You clicked here', self.click, 'Relese point:',(x,y) 
      ## Do work on corindate 
     else: 
      print 'You draged from', self.click, 'to:',(x,y) 
      ## Move or link two points, or w/e you want to do. 
     self.click = None 
     self.drag = False 

    def render(self): 
     self.clear() 
     ## An alternative to only getting a region if you only want to show a specific part of 
     ## the image: 
     # subimage = self.geodata_image.get_region(0, 0, self.geo_info[0], self.geo_info[1]) 
     self.geodata_image.blit(0, 0, 0) # x, y, z from the bottom left corner 
     self.flip() 

    def on_close(self): 
     self.alive = 0 

    def run(self): 
     while self.alive: 
      self.render() 

      ## self.dispatch_events() must be in the main loop 
      ## or any loop that you want to "render" something 
      ## Because it is what lets Pyglet continue with the next frame. 
      event = self.dispatch_events() 
      sleep(1.0/25) # 25FPS limit 

win = Window() 
win.run() 

Tutto ciò che serve è:


Python mockup di esecuzione come un modulo per Javav

import sys 
for line in sys.stdin.readline(): 
    if line == 'plot': 
     pass # create image here 

Ad esempio.

+0

Grazie @Torxed. Mentre sono d'accordo sul fatto che questa è una soluzione (cioè buttare via l'intero componente Java), sono desideroso di vedere un'implementazione * Java * che richiama un sottoprocesso Python e rende le figure matplotlib (in questo caso un grafico di Basemap) che può essere interagito con – pelson

+0

Yw, ho aggiunto un piccolo esempio di come è possibile eseguire uno script Python come sottoprocesso in Java e ascoltare l'input "live" offrendoti la possibilità di interagire e ri-renderizzare bitmap/basemaps. – Torxed

+0

@Torxed Sì, ho capito che fare il tutto in Python sarebbe ottimale, ma l'interfaccia Java-Python è ciò con cui devo lavorare (lavoro/cose relative ai client). Python puramente a causa delle caratteristiche interattive di Matplotlib-basemap. Ho provato a correggere l'immagine png su Jpanel, ma non è interattiva. Grazie allo stesso. – javaEd

0

È possibile incorporare la GUI in Jython, un'implementazione Java di Python. Sfortunatamente non supporta matplotlib, poiché si basa sul codice nativo. Potresti provare a usare execnet per invocare Python da Jython.