Gui python empotrada en C
Hola, estoy tratando de implementar interfaz grafica para unos programas en C.
La idea es tener los programas en C, mas la GUI hecha en python (tkinter, pygtk, pyqt o wxpython).
Por mas que he tratado no me funciona el cuento.
Posiblemente lo que estoy tratando de hacer no se puede realizar.
Por esa razon mejor acudo a ustedes, con el fin que me orienten un poco al respecto.
Estoy implementando un programa en C, el cual debe ejecutar un archivo.py el cual contiene la interface grafica python. por ej.
Para hacer mas sencilla la pregunta, un programa contiene:
2 etiquetas (Numero, Resultado)
2 cajas de texto
2 botones (Calcular, Salir)
____________________________________________________________
| Titulo ventana - + x |
|___________________________________________________________|
| _____________ |
| Numero: |____________| <> |
| |
| _____________ |
| Resultado: |____________| << Salir >> |
| |
| |
|___________________________________________________________|
Ingresas un numero en la caja de texto Numero, la caja de texto Resultado esta deshabilitada.
Al presionar el boton Calcular, el numero ingresado lo elevas al cuadarado, habilitas la caja de texto Resultado y muestras el resultado de la operacion.
Para esto he ejecutado varias pruebas, pero hasta ahora sin resultados.
1.- Desde C ejecutas el programa y habre la ventana hecha en python, con la funcion PyRun_SimpleFile(f, "archivo.py");
El problema es que solo abres el archivo.py, no tienes ninguna forma de interactuar con el programa original en C. A menos que si exista la posibilidad (la desconozco).
2.- Luego encontre informacion sobre empotrar clases de python en C, Se supone que da mas poder a la aplicacion.
El problema es que se importa el modulo pero no ejecuta la funcion para mostrar la ventana. resultado ej.
pymod: 0x7f777b976440
pyclass: 0xe08370
pyargs: 0x7f777b97e050
pyinst: 0xd41450
Hasta aqui todo bien, tengo importado el modulo, y cargados la clase, los argumentos y la instancia. Pero llego hasta aqui.
Leyendo en Internet encontre que:
El archivo.py generado con pyuic4, contiene una linea if __name__ == "__main__": , la cual si se crea sin esta linea no funciona.
La línea if __name__ == "__main__": comprueba si la variable __name__ es "__main__", lo cual indica que el programa está siendo ejecutado directamente por python y no está siendo importado en un intérprete Python.
La línea if __name__ == "__main__": permite al programa comenzar automáticamente si es llamado directamente o pasado como argumento al intérprete de Python. En estos casos, el nombre de programa que hay en la variable __name__ será la cadena "__main__" y el código siguiente se ejecutará.
Si el programa se carga en un intérprete de Python en ejecución, las ultimas líneas no serán ejecutadas.
Debido a esto al parecer no puedo ejecutar la parte grafica.
intente agregando al final de la linea if __name__ == "__main__": la clase quedando:
if __name__ == "__main__":clasegui()
ejecutando
python
>>> import modulo
funciona y abre la ventana, pero desde C no funciona. Ademas en python no vuelve el interprete, queda atrapado en la ventana.
Preguntas:
Existe alguna forma de hacer funcionar esta idea planteada.
Alguien tiene algun ejemplo basico similar que funcione.
Saludos y muchas gracias.
- Inicie sesión o regístrese para enviar comentarios
- 2061 lecturas


Creo que el enfoque es un poco raro.
Si archivo.py es la interfaz, ¿por qué no llamar directamente a archivo.py y que este ejecute el programa en C?
Creo que el problema es que, al estar ejecutando otro archivo, el resultado son dos procesos diferentes, siendo o no dos aplicaciones diferentes.
Por cierto, los archivos generados por [py]uic no es recomendable editarlos, ya que se sobreescribirán cada vez que cambies la interfaz con qtdesigner y la vuelvas a compilar, por lo que por lo general se importan y se crea una subclase de la clase que se define en ellos (la de la ventana).
Otra opción sería convertir tu programa en C en módulos de python o, para la comunicación, ya que usas Qt, usar su maravilloso sistema de signals/slots, aunque no sé qué tal funcionaría mezclando C y python.
Incluso tienes otra opción, que sería incrustar el código en C dentro de python, con cython, cinline, o algo similar (hay varias opciones, además de herramientas de creación de bindings a python desde otros lenguages, como por ejemplo sip para C++ y SWIG para casi todo).
Tampoco me ha quedado bien claro lo que quieres que haga la aplicación...
EDITO:
Vale, por ejemplo:
Ejecutas archivo.py, que es la interfaz gráfica. Está en python. Hace que cuando le des al boton calcular, llama al programa en C pasandole como argumentos los numeros, luego recoge la salida del programa en c, y la escribe en el campo resultado de la GUI.
Otra opcion, en vez de llamar al programa escrito en C, es directamente crearte unos bindings a python de tu programa en C, y llamar a sus funciones directamente desde python, con lo que no pierdes rendimiento pero puedes usar python sin tener que ejecutar binarios externos.
Si archivo.py es la interfaz, ¿por qué no llamar directamente a archivo.py y que este ejecute el programa en C?
Tampoco me ha quedado bien claro lo que quieres que haga la aplicación...
EDITO:
Ejecutas archivo.py, que es la interfaz gráfica. Está en python. Hace que cuando le des al boton calcular, llama al programa en C pasandole como argumentos los numeros, luego recoge la salida del programa en c, y la escribe en el campo resultado de la GUI.
.
Respecto de tus consultas, dejo las que me interesan. Porque la idea es ejecutar python desde C.
El llamar directamente a archivo.py y que este ejecute el programa en C, me parece bien pero como ultima opcion, una vez que agote todas las posibilidades.
Respecto de lo que debe hacer el programa:
Ejecutas archivo.py, que es la interfaz gráfica. Está en python. Cuando le des al boton calcular, llama al programa en C pasandole como argumentos el numero, luego recoge la salida del programa en c, y la escribe en el campo resultado de la GUI.
Efectivamente es lo que quiero que realice.
Saludos y gracias.
¿Lo quequieres hacer es eso:
ejecutable en c -> ejecutable en python (GUI) -> ejecutable en C ?
Creo que es complicarse excesivamente la vida.
En todo caso, en vez de llamar a archivo.py desde el ejecutable en C, en todo caso lo que haría yo sería incrustar todo el código de archivo.py en el primer ejecutable... así no tienes que llamar a ejecutables externos, solo a funciones y clases dentro del programa.
Aunque sigo sin ver las ventajas de llamar primero al ejecutable en C en vez de directamente a la interfaz en python... podrías iluminarme al respecto?
¿Lo quequieres hacer es eso:
ejecutable en c -> ejecutable en python (GUI) -> ejecutable en C ?
Si. efectivamente.
Creo que es complicarse excesivamente la vida.
En todo caso, en vez de llamar a archivo.py desde el ejecutable en C, en todo caso lo que haría yo sería incrustar todo el código de archivo.py en el primer ejecutable... así no tienes que llamar a ejecutables externos, solo a funciones y clases dentro del programa.
Eso fue inicialmente lo que queria, pero no encontre informacion acerca de esto. Por eso me fui por otros caminos.
Aunque sigo sin ver las ventajas de llamar primero al ejecutable en C en vez de directamente a la interfaz en python... podrías iluminarme al respecto?
En realidad lanzar la Gui python desde C, es bastante facil.
*** Archivo.c ***
#include
#include
int main() {
FILE * f;
f = fopen("archivo.py", "r");
Py_SetProgramName(argv[0]);
Py_Initialize( );
PySys_SetArgv(argc, argv);
PyRun_SimpleFile(f, "archivo.py");
Py_Finalize();
return 0;
}
Con esto ya tienes lanzado el archivo.py, luego vere como empotrar todo el codigo del archivo.py en C.
Me gusta la idea de dejar todo en C, porque queda el codigo fuente oculto y es bueno cuando realizas un programa para ti y no deseas que te lo copien.
Si quieres realizar un programa libre, bueno ahi tienes la opcion de realizarlo directamente en python completo y lo distribuyes con el codigo fuente completo.
Pero nunca esta demas tener las 2 opciones.
Saludos.
Python se puede compilar... de distintas formas, además.
Puedes distribuir sólo el bytecode, sin código fuente; pues compilarla con freeze, cx_freeze o bb_freeze, o incluso compilarlo a c++ con shedskin (aunque necesitas estar escrito con tipeado estático y alguna otra restricción de estilo).
Eso para CPython. Jython e IronPython son compilables a bytecode de java y dotnet, respectivamente.
Además, si usas la versión comercial de PyQt (porque con la libre es GPL*, o sea, no puedes usarla para hacer cosas no-libres) puedes usar un intérprete de python especial y ligarlo a tu aplicación de tal forma que tu aplicación sólo funcionará en ese intérprete firmado, que será solo capaz de ejecutar tu aplicación...
*PyQt es GPL con excepciones, ya que permite ser usado en software bajo otras licencias libres no necesariamente compatibles con la GPL.
Hay otro enfoque posible, igual te sirve. En vez de incrustar un trozo de python en C y hacer que C llame a python, podrías envolver C dentro de una interfaz gráfica de python y hacer que python trabaje con el archivo C subyacente, y luego compilarlo y distribuirlo como archivo binario .pyc o .pyo si lo necesitas.
import ctypes
Python se puede compilar... de distintas formas, además.
Además, si usas la versión comercial de PyQt (porque con la libre es GPL*, o sea, no puedes usarla para hacer cosas no-libres) puedes usar un intérprete de python especial y ligarlo a tu aplicación de tal forma que tu aplicación sólo funcionará en ese intérprete firmado, que será solo capaz de ejecutar tu aplicación...
En realidad no me interesa distribuir este software.
Te cuento trabajo en forma independiente, y realice algunos programas para poder desarrollar mi trabajo en c.
Como en ocasiones la carga de trabajo es mucha debes trabajar con gente externa, la cual a su vez tambien presta servicios a tu competencia.
Te imaginas si trabajas 3 meses en un programa y dejas el codigo fuente a la vista, todo tu trabajo. En realidad tus herramientas llegaran a tu competencia muy facil.
Sin embargo, si tu programa esta compilado y te gerera una salida con tu identificacion, la persona ya no podra usarla y debera realizarlo desde 0.
Lamentablemente el mundo es asi. cuando yo estuve en el suelo, hicieron leña del arbol caido.
Ademas, en estos momentos soy el unico que tiene acceso a estos sistemas de calculo. Por lo mismo.
Saludos.
Python se puede compilar... de distintas formas, además.
Además, si usas la versión comercial de PyQt (porque con la libre es GPL*, o sea, no puedes usarla para hacer cosas no-libres) puedes usar un intérprete de python especial y ligarlo a tu aplicación de tal forma que tu aplicación sólo funcionará en ese intérprete firmado, que será solo capaz de ejecutar tu aplicación...
En realidad no me interesa distribuir este software.
Te cuento trabajo en forma independiente, y realice algunos programas para poder desarrollar mi trabajo en c.
Como en ocasiones la carga de trabajo es mucha debes trabajar con gente externa, la cual a su vez tambien presta servicios a tu competencia.
Te imaginas si trabajas 3 meses en un programa y dejas el codigo fuente a la vista, todo tu trabajo. En realidad tus herramientas llegaran a tu competencia muy facil.
Sin embargo, si tu programa esta compilado y te gerera una salida con tu identificacion, la persona ya no podra usarla y debera realizarlo desde 0.
Lamentablemente el mundo es asi. cuando yo estuve en el suelo, hicieron leña del arbol caido.
Ademas, en estos momentos soy el unico que tiene acceso a estos sistemas de calculo. Por lo mismo.
Saludos.
Bueno, no todo el mundo piensa igual, por eso existe el software open-source... (véase openoffice, opensolaris, virtualbox, Darwin, Qt, PyQt y VMWares... son todo productos de empresas que son open-source)
Si no vas a distribuir este software, qué más da el lenguaje en que esté escrito? Si nadie va a tener acceso a él, no corres ningún peligro.
Además, con python no tienes por qué distribuir el código fuente, como ya te hemos indicado...
Y si a lo que le tienes miedo es a la descompilación, puede que CPython no sea el lenguage de programación que buscas. Pero ten en cuenta que siempre van a poder descompilar lo que hagas, aunque claro, con más o menos dificultad...
Además, no te has planteado la posibilidad de hacer la GUI open-source (en python) y la parte encargada de los algoritmos y la lógica esencial del programa escritos en C y con unos bindings a python? Así, aunque redistribuyeras tu programa sin compilar el código en python, lo único que verían en él sería cómo usar tus librerías... y nada más que sea útil, porque hacer GUIs con QtDesigner y unir señales y slots es algo bastante trivial. Creo que esta solución es la más versátil, ya que incluso te perm itiría usar la version GPL de PyQt4 con la parte de la GUI, en python, mientras nadie sería capaz de acceder directamente al código fuente de la parte escrita en C.
Además, no te has planteado la posibilidad de hacer la GUI open-source (en python) y la parte encargada de los algoritmos y la lógica esencial del programa escritos en C.
Si es lo que quiero
Creo que esta solución es la más versátil, ya que incluso te permitiría usar la version GPL de PyQt4 con la parte de la GUI, en python, mientras nadie sería capaz de acceder directamente al código fuente de la parte escrita en C.
Es como lo ideal ¿Se puede usar la version GPL de PyQt4?.
Lo pregunto porque el codigo de PyQt4 esta disponible. Pero el codigo en C esta compilado y si usas gcc o g++ para compilarlo No debiera ser GPL tambien. ¿Se pueden generar programas propietarios con gcc - g++ ?.
Yo no soy programador, soy un usuario del computador solamente. Llegue a Linux porque no me agradaba Windows.
Pero estoy tratando de optimizar mi forma de trabajo un poco, y lo unico que conozco un poco es C. Ademas, para aprender a programar en Python como se debe debes invertir tiempo que en estos momentos no dispongo.
Por esa razon, me interesa basicamente:
- generar la Gui en Python (tkinter, pygtk, pyqt4 o wxpython)
- usar un programa o libreria en C, para procesar la informacion.
Saludos y gracias.
Sí, se pueden compilar programas propietarios con ls GCC (GNU Compiler Collection).
Si ya sabes algo de C, puedes aprender python en un par de horas, o incluso menos. Precisamente es, para mucha gente, uno de los lenguages de programación más fáciles (y potentes).
Creo que, para tus necesidades, lo más fácil sería:
- Hacer un programa de línea de comandos en C. (Privativo, si quieres)
- Hacer una interfaz gráfica, con PyQt4, por ejemplo, que ejecute el programa en C pasándole los argumentos apropiados y tal.
Así, tendrías la interfaz lo máximo separada de la lógica posible, lo que te hace muy fácil cambiar radicalmente de interfaz (ya sea lenguage, toolkit, etc) sin mayores problemas, o también cambar el backend sin problemas, también. Incluso si haces más herramientas en C, puedes extender la interfaz para que te sirva para manejarlas todas.
Por otra parte... ¿si no quieres aprender python (que es un potentísimo lenguage de programación ;)), por qué no haces la interfaz en C también? Hay bindings de Qt a C, o hacerlo directamente en C++, aunque si no tienes tiempo de aprender c++, no sé cuán conveniente te puede resultar.