[C con Clase] Gui python para programa C

Linux Linux linux_mv en hotmail.com
Mie Dic 15 17:04:12 CET 2010


Hola a todos, finalmente despues de leerme varias paginas de internet sobre el tema, he conseguido parcialmente comunicar una aplicacion python GUI con un programa en C.
Pero lamentablemente tengo algunos problemas que no he podido solucionar.

Para compilar el programa uso: gcc ccalc.c -g -fPIC -I/usr/include/python2.6 -shared -L/usr/bin -lpython2.6 -o ccalc.so
Para ejecutar el programa lanzo: python calc_fx.py

Adjunto codigos fuentes de archivos.

Este archivo queda intacto, no se modifica.
calc.py
*********
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'calc.ui'
#
# Created: Wed Oct 14 02:06:16 2009
#      by: PyQt4 UI code generator 4.4.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

class Ui_calc(object):
    def setupUi(self, calc):
        calc.setObjectName("calc")
        calc.resize(400, 180)
        self.label = QtGui.QLabel(calc)
        self.label.setGeometry(QtCore.QRect(20, 13, 80, 31))
        self.label.setObjectName("label")
        self.label_2 = QtGui.QLabel(calc)
        self.label_2.setGeometry(QtCore.QRect(20, 60, 80, 18))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtGui.QLabel(calc)
        self.label_3.setGeometry(QtCore.QRect(20, 100, 70, 18))
        self.label_3.setObjectName("label_3")
        self.num1 = QtGui.QLineEdit(calc)
        self.num1.setGeometry(QtCore.QRect(100, 14, 113, 30))
        self.num1.setObjectName("num1")
        self.num2 = QtGui.QLineEdit(calc)
        self.num2.setGeometry(QtCore.QRect(100, 55, 113, 28))
        self.num2.setObjectName("num2")
        self.result = QtGui.QLineEdit(calc)
        self.result.setGeometry(QtCore.QRect(100, 96, 113, 28))
        self.result.setObjectName("result")
        self.sum = QtGui.QPushButton(calc)
        self.sum.setGeometry(QtCore.QRect(240, 10, 106, 27))
        self.sum.setObjectName("sum")
        self.res = QtGui.QPushButton(calc)
        self.res.setGeometry(QtCore.QRect(240, 40, 106, 27))
        self.res.setObjectName("res")
        self.mul = QtGui.QPushButton(calc)
        self.mul.setGeometry(QtCore.QRect(240, 70, 106, 27))
        self.mul.setObjectName("mul")
        self.div = QtGui.QPushButton(calc)
        self.div.setGeometry(QtCore.QRect(240, 100, 106, 27))
        self.div.setObjectName("div")
        self.salir = QtGui.QPushButton(calc)
        self.salir.setGeometry(QtCore.QRect(130, 140, 106, 27))
        self.salir.setObjectName("salir")

        self.retranslateUi(calc)
        QtCore.QObject.connect(self.salir, QtCore.SIGNAL("clicked()"), calc.close)
        QtCore.QMetaObject.connectSlotsByName(calc)

    def retranslateUi(self, calc):
        calc.setWindowTitle(QtGui.QApplication.translate("calc", "Calculadora", None, QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate("calc", "Número 1", None, QtGui.QApplication.UnicodeUTF8))
        self.label_2.setText(QtGui.QApplication.translate("calc", "Número 2", None, QtGui.QApplication.UnicodeUTF8))
        self.label_3.setText(QtGui.QApplication.translate("calc", "Resultado", None, QtGui.QApplication.UnicodeUTF8))
        self.sum.setText(QtGui.QApplication.translate("calc", "Sumar", None, QtGui.QApplication.UnicodeUTF8))
        self.res.setText(QtGui.QApplication.translate("calc", "Restar", None, QtGui.QApplication.UnicodeUTF8))
        self.mul.setText(QtGui.QApplication.translate("calc", "Multiplicar", None, QtGui.QApplication.UnicodeUTF8))
        self.div.setText(QtGui.QApplication.translate("calc", "Dividir", None, QtGui.QApplication.UnicodeUTF8))
        self.salir.setText(QtGui.QApplication.translate("calc", "Salir", None, QtGui.QApplication.UnicodeUTF8))

********* 

Archivo python con las funciones, problemas que tengo:
1.- valor recibido desde C es: <class '__main__.calc'>
si se imprime el valor como texto (por eso he usado "%s" % (cresult) ) es: <__main__.calc object at 0x7f7aee08f848>
el codigo 0x7f... siempre cambia en cada ejecucion.
2.- En la funcion ccalc.triggerEvent(5, 2), le he pasado los valores iniciales para comprobar el funcionamiento del archivo C.
Pero necesito que tome los valores que tienen self.num1 = QtGui.QLineEdit(calc) y self.num2 = QtGui.QLineEdit(calc) del archivo calc.py
he tratado con calc.num1.setText(), setupUi.num1.setText(), Ui_calc.num1.setText() pero no es reconocido.

calc_fx.py
*********
# -*- coding: utf-8 -*-

import sys
from PyQt4.QtCore import SIGNAL
from PyQt4.QtGui import *
from calc import Ui_calc

class calc(QWidget, Ui_calc):
  def __init__(self, parent = None):
    QWidget.__init__(self, parent)
    self.setupUi(self)
    self.connect(self.sum, SIGNAL("clicked()"),self.sumar)
    self.connect(self.res, SIGNAL("clicked()"),self.restar)
    self.connect(self.mul, SIGNAL("clicked()"),self.multiplicar)
    self.connect(self.div, SIGNAL("clicked()"),self.dividir)

  def sumar(cresult):
    return cresult.result.setText("%s" % (cresult))
  
  def restar(cresult):
    return cresult.result.setText('')

# Python calls a C extension module to register handlers, trigger events
import ccalc
ccalc.setHandler(calc.sumar)
ccalc.triggerEvent(5, 2)

if __name__ == "__main__":
  app = QApplication(sys.argv)
  window = calc()
  window.show()
  sys.exit(app.exec_())

*********


Archivo C, dudas que tengo:
El archivo al parecer esta trabajando bien a excepcion del valor que devuelve a python.
Si se agrega un printf bajo las lineas:
args = Py_BuildValue("d", cresult);
pyresult = PyEval_CallObject(Handler, args);
se aprecia que el valor de args y pyresult son correctos.
El problema esta en Py_BuildValue("d", cresult); al parecer no esta pasando el valor en forma adecuada.

ccalc.c
*********
#include <Python.h>
#include <stdlib.h>

static PyObject *Handler = NULL;     // keep Python object in C

void Route_Event(double cresult) {
    double *cres;
    PyObject *args, *pyresult;
    
    args = Py_BuildValue("d", cresult);   /* make arg-list */
    pyresult = PyEval_CallObject(Handler, args);      /* apply: run a call */
    Py_DECREF(args);                              /* add error checks */

    if (pyresult != NULL) {
        PyArg_Parse(pyresult, "f", &cres);
        printf("%f\n", cres);
        Py_DECREF(pyresult);
    }
}

static PyObject *
Register_Handler(PyObject *self, PyObject *args) {
    /* save Python callable object */
    Py_XDECREF(Handler);                 /* called before? */
    PyArg_Parse(args, "O", &Handler);    /* one argument? */
    Py_XINCREF(Handler);                 /* add a reference */
    Py_INCREF(Py_None);                  /* return 'None': success */
    return Py_None;
}

// let Python simulate event caught by C
static PyObject *
Trigger_Event(PyObject *self, PyObject *args) {
    double num1 = 0, num2 = 0;
    double cresult;
    PyArg_ParseTuple(args,"dd", &num1, &num2);    // carga variables python en punteros de C.
    cresult = num1 + num2;
    Route_Event(cresult);
    Py_INCREF(Py_None);
    return Py_None;
}

static struct PyMethodDef ccalc_methods[] = {
    {"setHandler", Register_Handler},
    //{"triggerEvent", Trigger_Event},
    {"triggerEvent",  Trigger_Event, METH_VARARGS},
    {NULL, NULL}
};

// this is called by Python on first "import ccalc"
void initccalc() {
    (void) Py_InitModule("ccalc", ccalc_methods);
}

*********

Saludos y muchas gracias por vuestra ayuda.

 		 	   		  
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20101215/99b51e58/attachment.html>


Más información sobre la lista de distribución Cconclase