miércoles, 17 de diciembre de 2014

Mover objetos con transiciones en Qt con QPropertyAnimation

Aqui explicaremos como mover un objeto de Qt de un lugar a otro de la pantalla y que este se valla deslizando:
Basta con crear una animación de movimiento con QPropertyAnimation.


// Se crea la animación 
// el parámetro OBJETO es el objeto que queremos mover
// Puede ser un QLabel, QGraphicsWidget, etc
QPropertyAnimation *animation = new QPropertyAnimation(OBJETO, "pos"); 


// Duración de la animación. El tiempo desde que sale hasta que llega
animation->setDuration(1000); 

// Posición inicial de donde va a partir
animation->setStartValue(QPointF(this->x(), this->y()));

// Posición final a donde va a llegar
// En este caso le estoy diciendo que se mantenga en el mismo
// valor de x pero que varie el valor de Y en 100 px
animation->setEndValue(QPointF(this->x(), this->y()+100));

// Inicia la animación
animation->start(QAbstractAnimation::DeleteWhenStopped);


Este es un ejemplo compilable:

#include <QtCore>
#include <QtWidgets>
#include <QObject>
#include <QCoreApplication>

/** @brief Representa una figura cuadrada **/
class Cuadrado : public QGraphicsWidget
{
public:

    /** Constructor
     *  @param colorDeseado Color que el usuario desea
     *         Puede ser "azul" o "rojo". En caso contrario
     *         la pieza se dibujará gris
     **/
    Cuadrado(QString colorDeseado):QGraphicsWidget(){

        // Asigna el color segun el color deseado
        color= colorDeseado=="rojo"? Qt::red : (colorDeseado=="azul"?
               Qt::blue : Qt::gray);
    }

    ~Cuadrado(){}

    /** Pinta la pieza segun el color **/
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *, 
               QWidget *){
        painter->fillRect(rect(), color);
    }

    void mover(qreal xEnd,qreal yEnd){
 // Aqui crea la animación
        QPropertyAnimation *animation = new QPropertyAnimation(this
                                                               "pos"); 
        animation->setDuration(8000); // 8 Segundos
        animation->setStartValue(QPointF(this->x(), this->y()));
        animation->setEndValue(QPointF(xEnd, yEnd));
        animation->start(QAbstractAnimation::DeleteWhenStopped);
    }

private:

    /** Color del cuadrado **/
    Qt::GlobalColor color;
};


int main(int argc, char **argv)
{ 
    QApplication app(argc, argv);

    // Creamos un cuadro rojo y uno azul
    Cuadrado *cuadroAzul=new Cuadrado("azul");
    Cuadrado *cuadroRojo=new Cuadrado("rojo");

    // Los movemos a la posición inicial
    cuadroAzul->moveBy(60,10);
    cuadroRojo->moveBy(10,10);

    // Se crea la escena
    QGraphicsScene scene(0, 0,600, 600);

    // Se agrega los cuadros a la escena
    scene.addItem(cuadroAzul);
    scene.addItem(cuadroRojo);

   // Se mueve con animación
    cuadroAzul->mover(200,500);
    cuadroRojo->mover(100,500);

    QGraphicsView window(&scene);
    window.show();
    return app.exec();
}




Manejo de Procesos y señales POSIX con Qt


Qt no integra ninguna solución que encapsule y simplifique la gestión de señales POSIX, puesto que éstas no están disponibles en sistemas operativos que no soporten dicha especificación.

Aun así en la documentación de Qt se describe una forma de usar manejadores de señales POSIX. Realmente basta con que el manejador de señal haga algo que provoque que Qt emita una señal y después retorne. Al volver a la secuencia normal de ejecución del programa, se emitiría la señal de Qt invocando el slot al que está conectada, desde donde se ejecutarían de forma segura las operaciones que fueran necesarias.

Para esta entrada he creado una clase en C++ llamada QPosixSignalListener que permite abstraer todo el proceso de gestión de señales. Me basé en el artículo de la documentación oficial que trata sobre manejo de señales.

Diagrama de uso de la clase:



Interfaz de la clase:

class QPosixSignalListener : public QObject
{
    Q_OBJECT
public:
    /** Constructor. Setea las señales y crea
     *  los sockets correspondientes
     *
     *  @param parent Padre del objeto
     ***/
    QPosixSignalListener(QObject *parent = 0);

    ~QPosixSignalListener(){}

    // Unix signal handlers.
    static void hupSignalHandler(int);
    static void termSignalHandler(int);
    static void usr1SignalHandler(int);
    static void usr2SignalHandler(int);

    // Set the Unix signal handlers
    static int setup_unix_signal_handlers();

private slots:

    // Qt signal handlers.
    void handlerQt_SIGHUP();
    void handlerQt_SIGTERM();
    void handlerQt_SIGUSR1();
    void handlerQt_SIGUSR2();

signals:

    // Signals
    void sigHUP();
    void sigTERM();
    void sigUSR1();
    void sigUSR2();

private:

    // sockets
    static int socketSIGHUP[2];
    static int socketSIGTERM[2];
    static int socketSIGUSR1[2];
    static int socketSIGUSR2[2];

    // Socket Notifiers
    QSocketNotifier *skNotifierHUP;
    QSocketNotifier *skNotifierTERM;
    QSocketNotifier *skNotifierUSR1;
    QSocketNotifier *skNotifierUSR2;
};

La clase puede manejar las señales SIGHUP, SIGTERM, SIGUSR1 y SIGUSR2. Puedes modificarla para que soporte otras.


USO:





Cuando el proceso recibe una señal (soportada) el objeto emite una señal de Qt.

Para usar la clase solo basta con instanciar un objeto y conectar una de sus señales a un slot cualquiera. Ejemplo:


    QPosixSignalListener *signalListener=new QPosixSignalListener();
    
    QObject::connect(signalListener,SIGNAL(sigUSR1()),cuadroAzul,SLOT(mover()));


En este caso cuando se reciba la señal SIGUSR1 entonces se ejecuta el slot mover()




Para probar la clase te puedes descargar este proyecto de Qt que ya tiene un main listo para correr: 
https://github.com/Eitol/QPosixSignalListener/archive/master.zip

Abrelo con QtCreator (recuerda eliminar antes el archivo QPosixSignalListener.pro.user)

Córrelo y envíale señales desde una terminal. 

kill -s SIGUSR1 PID // donde PID es el pid del proceso




Si quieres enviarle señales desde otro programa en Qt puedes ver como se hace aqui:
http://wannabe-programmer.blogspot.com/2014/12/enviar-senales-unix-con-qt.html

Este es el vídeo de la corrida del proyecto



















Links relacionados:

martes, 16 de diciembre de 2014

Enviar señales Unix con Qt

En esta entrada haremos un ejemplo ultra sencillo de un programa gráfico que envía señales Unix cuando se pulsan sus botones.



Cuando pulsamos un botón se ejecuta la función kill con el pid indicado y la señal que corresponde al botón


void MainWindow::on_boton_SIGTERM_clicked()
{
    kill(ui->lineEdit_PID->text().toInt(),SIGTERM);

}


Puedes descargar el proyecto desde aqui

viernes, 8 de agosto de 2014

Realtek 8185L con Linux Fedora 20

Me he comprado un tarjeta wifi extremadamente barata.
El detalle es que no funciona en mi Fedora 20 x86_64.

La marca es advantek y Tiene un chip Realtek 8185L.





Para solucionarlo basta con instalar el paquete dkms-rtl818x.


32 bits: 
http://rpm.pbone.net/index.php3/stat/4/idpl/12064525/dir/redhat_el_5/com/dkms-rtl818x-1.0.1b-1.nodist.rf.noarch.rpm.html


64bits:
http://rpm.pbone.net/index.php3/stat/4/idpl/12086822/dir/redhat_el_5/com/dkms-rtl818x-1.0.1b-1.nodist.rf.noarch.rpm.html

Luego que lo descargues lo instalas:

yum install ./dkms-rtl818x-1.0.1b-1.nodist.rf.noarch.rpm

luego reinicias y listo

esta solución deberia funcionar para toda la serie 818x (8185 , 8587 etc)

lunes, 21 de abril de 2014

Instalar Oracle JDK 8 en Fedora 20 / 19

Primero descargamos de la pag oficial la versión .rpm dependiendo de la arquitectura de su SO. 
En este tuto usaremos la x64. Para saber la arquitectura de su SO ejecute : uname -r


Ahora nos movemos en la terminal al lugar donde está el .rpm y ejecutamos

rpm -Uvh jre-8*-x64.rpm



Luego buscamos el nombre del directorio del oracle jdk y ejecutamos la siguiente:

alternatives --install /usr/bin/java java /usr/java/jdk1.8.0_05/bin/java 2

Note que el nombre del directorio del jdk puede variar dependiendo de su versión. En este caso el nombre es jdk1.8.0_05


Por último ejecutamos y seleccionamos la opción 2

alternatives --config java


y listo. Ya deberias tener configurado el JDK

domingo, 16 de marzo de 2014

Generar diagramas ER para postgresql con SchemaSpy

Antes de empezar primero debemos tener instalado graphviz y java (opendjk o el de oracle).


Para instalar graphviz en ubuntu o debian prueba con: sudo apt-get install graphviz

1- Luego de tener java y graphviz instalado entonces nos descargamhos este fichero ya preparado que tiene el driver de postgres 9.3 para java y el programa que genera los diagramas (SchemaSpy).

Si tienes una versión distinta de postgres entonces debes descargar el driver adecuado desde este sitio y substituir dicho fichero .jar por driver.jar



2- Lo descomprimimos en un directorio y ejecutamos en el:

java -jar schemaSpy -t pgsql -cp ./driver.jar -db NOMBREDB -host HOST -port PUERTO -u USUARIO -p CONTRASEÑA -o DESTINO -schemas "public,something,else"

Donde:
 ./driver.jar: Es el nombre del driver de JDBC para postgres

NOMBREDB: Es el nombre de la base de datos

HOST: Es el host de la base de datos

* PUERTO: Es el puerto de la BD

USUARIO: Es el usuario de la BD

* CONTRASEÑA: El pass de la BD

* DESTINO: Es donde queremos ubicar los ficheros que se van a generar (diagramas, etc)

Por ejemplo:


java -jar schemaSpy -t pgsql -cp ./driver.jar -db 'tienda_virtual' -host 'localhost' -port '5432' -u 'postgres' -p '1234' -o destino -schemas "public,something,else"


Debería arrojar algo como esto:






En la carpeta de destino estará la documentación generada.



Un gráfico generado:




miércoles, 8 de enero de 2014

Programando en Lenguaje C, Una Visión Compilable



Aprender a programar en Lenguaje C es un arte que lleva su tiempo, requiere esfuerzo y dedicación, expongo aquí un material que escribí en archivos de formato *.CPP tomando en cuenta los dos tipos de programadores.

   a) Los que les gusta el código para experimentar
   b) Los que les gusta tener documentación a la mano para poder comprender

Es un TEMARIO totalmente COMPILABLE que comprende 15 capítulos, en el cual encontraran código y explicaciones sencillas.



Repositorios


Nota

-  Si sólo estas interesado en ojear un tema, dando click en el archivo bastara para revisar la información comodamente.

-   Para descargarlo sólo hace falta dar click en "Download ZIP", esté botón se encuentra en la parte central derecha.


Índice:

    1.   Introducción
    2.   Operadores
    3.   Ciclos Repetitivos
    4.   Estructuras Condicionales
    5.   Funciones y Procedimientos
    6.   Arreglos (Memoria Estática)
    7.   Manejo de Cadenas <string.h>
    8.   Apuntadores
    9.   Memoria Dinámica
 10.I   Listas Enlazadas
 10.II  Listas Enlazadas Avanzadas
   11.  Recursividad
   12.  Árboles Binarios
   13.  Manejo de Archivos de Texto y Binarios
 14.I   Hilos o Procesos Ligeros [Linux]
 14.II  Hilos o Procesos Ligeros [Windows]
   15.  Sockets TCP/IP, UDP/IP, (Servidor y Cliente) [Linux]