Buscar en el Blog

Mostrando entradas con la etiqueta Qt. Mostrar todas las entradas
Mostrando entradas con la etiqueta Qt. Mostrar todas las entradas

lunes, 31 de octubre de 2016

OpenGL con Qt



En esta ocasión veremos un ejemplo de como usar OpenGL en Qt. Vale recalcar que solo se verá como usarlo, no se va a profundizar sobre el tema de OpenGL.


Primero vamos a crear un proyecto común y corriente(no se explicará esta parte por ser muy sencillo).
Una vez que tenemos nuestro proyecto, vamos a agregar una clase.
Clic derecho sobre el proyecto agregar nuevo... seleccionamos C++ Class

Le ponemos un nombre a nuestro Widget, por ejempo WidgetOpenGL 
y en Base class Custom. Luego colocamos QOpenGLWidget y siguiente.
 
 Finalmente les pedirá finalizar.

 Ya tenemos nuestro proyecto con nuestra clase. Ahora vamos a modificar el archivo ".pro" para agregar las referencias a opengl. Agregaremos QT +=opengl y LIBS += -lOpengl32.




Ahora nos dirigimos a la clase que habiamos agregado y agregaremos las siguientes librerias.

#include <QOpenGLWidget>
#include <QOpenGLFunctions>

#include <QGLFramebufferObjectFormat>
 
 
Modificaremos la definicion de la clase.
 
class WidgetOpenGL : public QOpenGLWidget,protected QOpenGLFunctions
 
Agregamos las funciones virtuales que vamos a reimplementar.
void initializeGL() Q_DECL_OVERRIDE;//reimplementando las funciones virtuales
void resizeGL(int w, int h)Q_DECL_OVERRIDE;
void paintGL()Q_DECL_OVERRIDE;

Al final su archivo de cabecera widgetopengl.h se vera de la siguiente manera.
 
#ifndef WIDGETOPENGL_H
#define WIDGETOPENGL_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions>


#include <QGLFramebufferObjectFormat>


class WidgetOpenGL : public QOpenGLWidget,protected QOpenGLFunctions
{
public:
    WidgetOpenGL();
explicit WidgetOpenGL(QWidget *parent = 0);
protected:
void initializeGL() Q_DECL_OVERRIDE;//reimplementando las funciones virtuales
void resizeGL(int w, int h)Q_DECL_OVERRIDE;
void paintGL()Q_DECL_OVERRIDE;


};


#endif // WIDGETOPENGL_H

Las funciones que hemos declarado van a ser implementadas.Asi que nos dirigimos 
al archivo widgetopengl.cpp
 
 
Modificamos el archivo modificando el constructor.
WidgetOpenGL::WidgetOpenGL(QWidget *parent):QOpenGLWidget(parent)
 
 Agregando las funciones declaradas. 
void WidgetOpenGL::initializeGL()
{
   

}


void WidgetOpenGL::resizeGL(int w, int h)
{


}


void WidgetOpenGL::paintGL()
{

}

 En la funcion initializeGL()vamos a agregar el siguiente código 
 //esta parte sirve para poder usar las funciones de opengl
 initializeOpenGLFunctions(); 
 //Para habilitar o deshabilitar el buffer de profundidad
      glEnable(GL_DEPTH_TEST); 
  
la fucion deberia quedar asi.
void WidgetOpenGL::initializeGL()
{
    initializeOpenGLFunctions();
      glEnable(GL_DEPTH_TEST);


}
 
la fucion resizeGL no la tocaremos por ahora, esta sirve como su mismo nombre 
lo dice para redimensionar el contenido cuando la ventana cambia de tamaño.
 
Ahora vamos con el painGL. Aqui codificaremos nuestras instrucciones openGL.
Por ejemplo, si deseamos mostrar un rectangulo, usaremos la GL_POLYGON. Si han 
usado openGL con glut, esto es lo mismo.
 
void WidgetOpenGL::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glDepthFunc(GL_LESS);
    glEnable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);
    // Resetear transformaciones
    glLoadIdentity();


    // LADO IZQUIERDO: lado verde
    glBegin(GL_POLYGON);


    glColor3f( 1.0, 0.0, 0.0 );
    glVertex3f(  0.5, -0.5, -0.5 );      // P1 es rojo
    glColor3f( 0.0, 1.0, 0.0 );
    glVertex3f(  0.5,  0.5, -0.5 );      // P2 es verde
    glColor3f( 0.0, 0.0, 1.0 );
    glVertex3f( -0.5,  0.5, -0.5 );      // P3 es azul
    glColor3f( 1.0, 0.0, 1.0 );
    glVertex3f( -0.5, -0.5, -0.5 );      // P4 es morado

    glEnd();
    glFlush();
      this->makeCurrent();
}

 
 
 Con esto ya tenemos lista nuestra clase. Ahora vamos a usarla en nuesta ventana.
En nuestra ventana(formulario) insertamos un widget.
 
 una vez agregado el widget hacemos clic derecho sobre el y elegimos Promote to...
 



En promoted class name ingresamos el nombre de la clase que  habiamos creado.





Luego le damos clic en Add.

Finalmente click en Promote.

Ejecutamos el proyecto y este es el resultado.


Aqui podran descargar el codigo fuente de este ejemplo y el ejemplo del cubo.

martes, 18 de octubre de 2016

Qt - Graficos en 2D QPainted



Ahora vamos a ver un ejemplo sencillo de como crear graficos  2D en Qt. Para esto haremos uso de la clase QPainter y del evento paintEvent.

Para esto ya debemos tener un proyecto vacio creado y dentro del proyecto una ventana.

Dentro del archivo de cabecera incluimos las siguientes lineas de código.

#include <QPaintEvent>//para el evento
#include <QPainter>//para el pintor con el cual crearemos nuestros gráficos.


Entonces la parte superior de nuestro archivo quedaria así.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#include <QMainWindow>
#include <QPaintEvent>
#include <QPainter>
 
 
En la seccion de protected  colocamos 
 void paintEvent(QPaintEvent *) ;//para implementar la creación
 de los gráficos dentro del evento.
 
 
class MainWindow : public QMainWindow
{
    Q_OBJECT


public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();


private:
    Ui::MainWindow *ui;


 
protected:
   void paintEvent(QPaintEvent *) ;

};

 Ahora vamos a nuestro archivo cpp a implementar dentro del evento paint.
 
 
 
void MainWindow::paintEvent(QPaintEvent *)
{
   
    QPainter pintor(this);  


    pintor.translate(300,300);
 
 
    pintor.drawRect(0,0,100,100);





} 


Explicacion del código.

QPainter pintor(this).
Aqui tenemos nuestro objeto pintor que recibe en su constructor 
el dispositivo en donde se va a realizar el pintado.En este caso será la misma 
ventana, por eso le pasamos "this", haciendo referencia a esta misma clase.

   pintor.translate(300,300);
Aqui le indicamos que se realizará una transformación, concretamenta una 
traslacion de 300 unidades en x y 300 unidades en y.
 
 pintor.drawRect(0,0,100,100);
 
Aqui le indicamos que dibuje un rectangulo en donde:
 
 pintor.drawRect(x,y,ancho,alto);
 
Si ejecutamos el codigo veremos lo siguiente.

 
 
 
Si comentamos la linea   pintor.translate(300,300). Entonces se veria así.
 
 
  Esto se debe a que por defecto el tamaña y las coordenas de ventana 
de pintado es el mismo que la ventana que la contiene(No confundir). Para
esto pueden revisar mas a fondo sobre viewport y window(esto referente a graficos
 por computadora). Entonces el origen (0,0) estaria en la ezquina supeior
 izquierda(desde mi perspectiva)
 
 
 
Con lo cual para traslador un objeto tanto dentro de la parte visible, 
tanto "x" como "y" deberan ser positivos.

¿Que pasará si a la figura que tenemos le agregamos una rotación?

Empezaremos con 10 grados, luego con 20 y finalmente con 45.
Comentamos la linea de traslacion y deberia quedar así.

void MainWindow::paintEvent(QPaintEvent *)
{
   
    QPainter pintor(this);  


    // pintor.translate(300,300);
    pintor.rotate(10);
 
    pintor.drawRect(0,0,100,100);


} 
 
 
 
Resultado de 10 grados.
Resultado de 20 grados

Resultado de 45
 
 
 
 
 
 Como vemos esta rotando segun la coordenado (0,0). No esta rotando desde su
 centro.
Si al momento de crear el rectangulo cambiamos las coordenadas por 300,300.
 
 
void MainWindow::paintEvent(QPaintEvent *) { QPainter pintor(this); // pintor.translate(300,300); pintor.rotate(45); pintor.drawRect(300,300,100,100); }   
 Resultado en 45 grados 
 
Como vemos tiene el mismo angulo de rotacion, pero está mas abajo. Esto 
ocurre porque toma como centro de giro el eje de coordenadas (0,0).

Si quisieramos que rote segun su centro de masa, entonces deberiamos ubicar 
su centro de masa en las coordenadas (0,0). Esto se puede hacer de dos formar.
Forma 1: 
Cambiando los parametros de la ventana del pintor y colocando desde su creacion 
en el origen.
pintor.setWindow(-50,-50,100,100);
 
El -50,-50 ahora sera la esquina superior izquierda y la ventana ahora
 mide 100 de alto, por 100 de ancho.
 
Aqui tenemos un ejemplo en donde se estipuló que la esquina superior izquierda es 
la coordenada (-50,-50) y como tiene 100 de ancho por 100 de alto, la coordenada
de la esquina inferior derecha es (+50,+50).
 


 

  
 Si se desea ubicar el rectangulo en el centro (coodenada 0,0), debo restar a la 
coordena "X" menos la mitad del largo y  a la coordenada "Y" menos la mitad del alto. 
Es decir,Si mi rectangulo será de 10x10, entonces la mitada es 5 y 0 - 5 es igual 
a -5 para "X" y para "Y" seria igual a -5. 
pintor.drawRect(-5,-5,10,10); 

 
 

Ahora aplicamos la rotación.
void MainWindow::paintEvent(QPaintEvent *)
{

   
    QPainter pintor(this);


   pintor.setWindow(-50,-50,100,100);
 
    pintor.rotate(45);
    pintor.drawRect(-5,-5,10,10);




    

} 


Forma 2:
Trasladando al origen, luego rotar y nuevamente trasladar a la posicion inicial.

void MainWindow::paintEvent(QPaintEvent *)
{
  
    
    QPainter pintor(this);


 
     pintor.translate(150,150);// se posiciona en la ubicacion inicial
     pintor.rotate(angulo);//tercero rota
    pintor.translate(-150,-150);//segundo se traslada al origen
    pintor.drawRect(100,100,100,100);//primero se dibuja




    

}
Como vemos esto opera como una pila. La ultima instrucción es la primera 
en realizarse.

Resultado.





Para profundizar mas sobre gráficos por computadora,
 les recomiendo el siguiente libro graficos por computadora con opengl


lunes, 17 de octubre de 2016

Qt - Expresiones Regulares - Validar LineEdit Solo numeros

Para validar un lineEdit usaremos la clase QRegExp.
En nuestra ventana debemos tener un lineEdit agregado.

QRegExp expresion("[0-9]{1,8}"); 
  
    ui->lineEdit->setValidator(new QRegExpValidator(expresion,this));

Este código lo insertamos en el constructor de la ventana y despues de la sentencia setupUI;

Deberia quedar así.
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{


    ui->setupUi(this);

    QRegExp expresion("[0-9]{1,8}");

    ui->lineEdit->setValidator(new QRegExpValidator(expresion,this));

}

MainWindow::~MainWindow()
{
    delete ui;
}

Ejecutamos la aplicacion y miren lo que sucede.

Si desean que solo admita letras pueden usar la siguiente linea de código.
 QRegExp expresion("[A-Z]{1,8}"); 
En donde solo admitirá hasta 8 caracteres.
 

martes, 1 de marzo de 2016

Game Programming Using Qt


Game Programming Using Qt
Programacion de Juegos Usando Qt
Witold Wysota
Lorenz Hass

Idioma: Ingles
Páginas: 512

Programacion de juegos usando  Qt y Qt Quick


domingo, 21 de febrero de 2016

Qt | Cambiar el fondo de un boton cuanto se hace click sobre este.





Vamos a ver como cambiamos de color de fondo de un boton cuando presionamos sobre este. Cuando se suelte el mouse, el boton retoma su color por defecto.


Para esto haremos uso de setStyleSheet para darle la aparencia que deseamos y dentro de las comillas, antes de indicar el formato colocamos QPushButton:pressed para indicar que cambie de color cuando el boton esté presionado.

this->setStyleSheet(" QPushButton:pressed {background-color: blue;yellow}");

Esta instrucción se puede colocar en el constructor de la clase y eso seria todo.



 Si desean tener la misma aparecian del boton de la imagen, pueden hacerlo con el siguiente codigo.


this->setStyleSheet("QPushButton {background-color: green;border-style: outset;border-width: 2px;border-radius: 10px;font: bold 14px;min-width: 4em; padding: 6px;} QPushButton:pressed {background-color: yellow;}");