Inicio

Glosario

Signals_Slots
Widget

Categorías del FAQ


Visitantes en linea:3
Visitantes de hoy:29
Total de visitantes:11975

Qt-src

Hay veces que se tiene la necesidad de marcar ciertos eventos en un calendar widget y Qt nos provee una forma muy fácil de hacerlo.

Esta clase de ejemplo aclara todo. Lo único que hago es extender QCalendarWidget y agregarle un método appendDate que marcará nuestros eventos( sacado del core de zmviewer ) Ademaś utilizo el método setDateTextFormat( const QDate & date, const QTextCharFormat & format ) de QCalendarWidget para setear el formato que quiera ( por ahora solo un background en amarillo y el texto subrayado )

class CameraEventCalendar : public QCalendarWidget{
public:
    CameraEventCalendar( QWidget * parent ): QCalendarWidget ( parent ){};
    void appendDate( const QDate & date ){
        QTextCharFormat fmt;
        fmt.setBackground( QBrush( Qt::yellow ) );
        fmt.setToolTip(tr("Click here to view events of this day"));
        fmt.setFontUnderline( true );
        setDateTextFormat( date , fmt );
        m_eventsDateList.append( date );
    }

    QList <QDate> eventsDateList() const{
        return m_eventsDateList;
    }
private:
    QList <QDate> m_eventsDateList;

};
 

Por lo que utilizar este widget sería tan sencillo como:

//instanciar
CameraEventCalendar * cameraEventsCalendar = new CameraEventCalendar( this );
// a modo de ejemplo instanciar un modelo
// que su fuente de datos es la tabla Events
QSqlTableModel * model = new QSqlTableModel ( this , QSqlDatabase::database () );
model->setTable ( "Events" );
model->select();
//recorrer el modelo y setear los eventos al calendario
for ( int i = 0 ; i < m_model->rowCount(); i++ ){
         cameraEventsCalendar->appendDate ( model->record( i ).value( "StartTime" ).toDate() );
    }

 

leo | Qt-src | 3 Julio, 4:39pm | Comentar acerca de esto

El otro día me vi en la necesidad de hacer que un texto sea vertical... Leyendo un poco antes de empezar a programar me encontre con este FAQ en Qt La idea es muy sencilla solo dibujar un texto y rotarlo 90 grados en el paintEvent, o sea siempre que el widget sea dibujado. Acá dejo un ejemplo para hacer esto:

#include <QApplication>
#include <QWidget>
#include <QPainter>

class VerticalText : public QWidget
{
public:
    VerticalText(QWidget *parent = 0)
    : QWidget(parent){ text = "No text";}

    void paintEvent(QPaintEvent *)
    {
        QPainter p(this);
        drawRotatedText(&p, 90, width() / 2, 0, text);
    }
    void drawRotatedText(QPainter *painter, float degrees, int x, int y, const QString &text)
    {
        painter->save();
        painter->drawImage( QPoint( x  , y ) , QImage("/usr/share/icons/crystalsvg/32x32/apps/colors.png") );
        //comenzar a dibujar a la posicion de y + 35 ( la imagen ocupa 32px y dejo 3px de espacio )
        painter->translate(x, y + 35);
        painter->rotate(degrees);
        painter->drawText(0, 0, text);
        painter->restore();
    }
    QString text;
};

int main(int argc, char *argv[])
{
      QApplication app(argc, argv);
      VerticalText text;
      text.text = "Hola, soy un texto vertical :)";
      text.show();
      return app.exec();
}
 

Ahora bien, este widget es muy sencillo si queremos cambiar el texto deberiamos hacer algo así:
text.text = "Otro texto vertical"
text.repaint();
 
También estoy dibujando una imagen para que se vea la posibilidad de dibujar más cosas :)

leo | Qt-src | 2 Junio, 12:09pm | Comentar acerca de esto

La versión Qt4.4 ha incorporado el fabuloso webkit. WebKit es un proyecto open source para armar un motor para un navegador web. Asi mismo, webkit es el motor de safary y un muchas aplicaciones populares en OS X. WebKit nacio de un branch de KHTML.

Gracias a esto podremos renderizar páginas web con solo estas lineas de código:

#include <Qt/QtGui>
#include <QtWebKit/QWebView>

int main(int argc, char *argv[])
{
      QApplication app(argc, argv);
       QWebView *view = new QWebView( );
       view->load(QUrl("http://www.lugoroverde.com.ar"));
       view->show();

      return app.exec();
}
 

¿No les parece impresionante? A mi si :p
Abajo un screenshot de la aplicacion compilada:
Y no solo eso, también pasa el test acid por si alguien quiere saber:
Pueden descargar el snapshot de qt4.4 desde aquí: http://trolltech.com/developer/downloads/qt/qt44-preview-download

leo | Qt-src, Qt-info | 16 Febrero, 1:16pm | Comentar acerca de esto

También dedicaré un espacio a mi proyecto favorito.

ZMViewer es un front-end de zoneminder ( http://www.zoneminder.com ) el cual es un sistema de video vigilancia exelente. Hoy lanze una nueva versión del zmviewer, en esta versión incorporé una nueva clase para manejar el stream, más que nada para leer los boundary, ya que zoneminder envia frames del tipo: Content-Type: multipart/x-mixed-replace;boundary=ZoneMinderFrame , lo que significa que cada "--ZoneMinderFrame" viene un paquete. La versión anterior de zmviewer hacia esto un poco desprolijo. Ahora creo que con la nueva versión esto será casi perfecto :); para esto agregue una clase llamada QMultiPartReader ya que creo que puede leer casi cualquier tipo de frames multipartes.

ZMViewer permite lo siguiente:

  • Conexión con muchos servidores zoneminder en simultaneo.
  • Cambiar la apariencia con un sistema de temas
  • Visualizar los eventos que ocurrieron en las cámaras... por ej. Grabación por detección de movimiento de una cámara
  • y muchas otras cosas más...

La página del proyecto esta en http://sourceforge.net/projects/zmviewer

leo | General, Qt-src, Qt-info | 1 Febrero, 1:38am | Comentar acerca de esto

Este pequeño artículo surge de una necesidad mía de poder mostrar un número calculado ( por ej. int total = 23 + 6 ) en un QLabel, QLineEdit o un widget en especial. Entonces el tema acá es pasar de número(int,float,double) a QString, porque para setear el texto de un QLabel usamos la funcíon setText ( &QString ). Mostraré dos formas posibles de hacer esto y una tercera usando simplemente "C".

De int,float,short o double a QString.

QString nos nos provee de el método sobrecargado setNum() el cual nos devuelve un QString del número pasado; de la siguiente manera: QString numero;

 int total = 23 + 6;
 numero = numero.setNum( total ); // numero = "29"
 QString flotante;
 float total2 = 23 / 6.00;
 flotante = flotante.setNum( total2 );
 

Además se puede hacer lo mismo con QString con el método estático sobrecargado number(), el cual funciona exactamente a setNum con la diferencia de ser estático. Ejemplo:

QString numero = QString::number( 55 ); // numero vale "55"
 

La última forma es con C y muy sencillo también con la función sprintf() (que se encuentra definida en stdio.h), ejemplo:

char cadena[50];
 sprintf(cadena, "%6d", 125); // La cadena tendra el contenido "   232"
 sprintf(cadena, "%6.2f", 442.2); // La cadena tendra el contenido "332.20"
 sprintf(cadena, "%04x", 127); // La cadena tendra el contenido "007f"
 

Ahora de QString a número.

No detallaré mucho en esto porque es todavía más fácil. QString posee funciones para pasar QString a int,unsignerd int (uint), long,etc. las cuales son:

int toInt ( bool * ok = 0, int base = 10 ) const // a int
 double toDouble ( bool * ok = 0 ) const // a double
 float toFloat ( bool * ok = 0 ) const // a float
 long toLong ( bool * ok = 0, int base = 10 ) const // a Long

 /* etc */
 

Ejemplo:
QString num = "22";
 int entero = num.toInt();
 

Por último para lo mismo tendremos las siguientes funciones en C: int atoi(const char *numPtr); double atof(const char *numPtr); long int atol(const char *numPtr); Ejemplo:

QString num= "22";
 int entero = atoi(num.toAscii () );
 
leo | Qt-src | 19 Febrero, 10:38pm | Comentar acerca de esto

Está es una opción muy buena y fácil de usar. Si no saben utilizar la clase QTextDocument acá le dejo el link a la referencia de la clase: http://doc.trolltech.com/4.2/qtextdocument.html

Bueno, voy a suponer que se tiene un QTextDocument listo y andando y que de una forma o otra se tienen datos dentro de él.

Manos a la obra: Seguro en algún momento hiciste algo como esto:

QTextDocument * textDoc = new QTextDocument ( this );
 

Entonces sabiendo que la instancia de QTextDocument es textDoc creamos la función:

void ClasePadre::aPdf()
{
// no aseguramos de que posea soporte para impresora
#ifndef QT_NO_PRINTER
    // Llamamos un cuadro de dialogo de guardar archivo.
    QString fileName = QFileDialog::getSaveFileName(this, tr("Exportar a PDF"),QString(), tr("Archivos PDF(*.pdf)"));
    // Algunas comprobaciones
    if (!fileName.isEmpty()) {
        if (QFileInfo(fileName).suffix().isEmpty())
            fileName.append(".pdf");
       
        QPrinter printer(QPrinter::HighResolution);
        // Formato de salida = PDF
        printer.setOutputFormat(QPrinter::PdfFormat);
        // que imprima en fileName
        printer.setOutputFileName(fileName);
        // Imprimimos el PDF!!!
        textDoc->print(&printer);
    }//fin if
#endif
}

 

leo | Qt-src | 3 Noviembre, 11:24pm | Comentar acerca de esto

Este simple ejemplo consiste en llamar a un par de funciones de prueba y llamar a un formulario hecho en Qt Designer, por lo que primero hay que crearlo. Bueno el código es el siguiente:

import com.trolltech.qt.core.*;
import com.trolltech.qt.gui.*;

class Prueba{
        public static void main ( String args[] ){
                System.out.println("iniciando la app...");
                if (initConfig() != 0 )
                        System.out.println("error al cargar la configuracion");
                QApplication.initialize ( args );
                QMainWindow mw = new QMainWindow();
                Ui_MainWindow ui = new Ui_MainWindow();
                ui.setupUi( mw );
                mw.show();
                QApplication.exec();

        }
        private static int initConfig ( ){
                System.out.print( "cargando configuracion..." );
                return 0;
        }
}

 

Para compilarlo primero va a ver que bajar las QtJambi en www.trolltech.com y luego compilar la clase Prueba.java algo así:

export LD_LIBRARY_PATH=/usr/share/qtjambi-1.0:$LD_LIBRARY_PATH
export PATH=/usr/share/qtjambi-1.0/bin:$PATH
export CLASSPATH=/usr/share/qtjambi-1.0/qtjambi.jar:.
javac Prueba.java

Obviamente hay que reemplazar /usr/share/qtjambi-1.0 por el directorio en donde está instalado las qtjambi.

leo | Qt-src | 17 Septiembre, 4:13pm | Comentar acerca de esto

Habremos notado que al escribir una clase para que trabaje con las Qt y pueda usar señales y slots tendremos que agregar algo así:

  class miclase {
  Q_OBJECT
  public slots:
   /*...*/ 
  signals:
  /*...*/
  };

 

¿Pero qué es todo esto?

Podemos notar que tanto Q_OBJECT, public slots y signals no forman parte del ANSI C++ y ¿porquñe nuestro compilador lo compila?. Si vamos al código fuente de las Qt podremos ver que estos elementos están definidos como macros. En GNU/Linux dicho fichero puede verse en /usr/share/qt4/include/Qt/qobjectdefs.h en Qt versión 4 y en /usr/share/qt3/include/qobjectdefs.h en Qt versión 3, cabeceras que importamos indirectamente. En este archivo vamos a ver algo así:

/*...*/
#   define slots
#   define signals protected
/*...*/
#define Q_OBJECT \
public: \
    static const QMetaObject staticMetaObject; \
    virtual const QMetaObject *metaObject() const; \
    virtual void *qt_metacast(const char *); \
    QT_TR_FUNCTIONS \
    virtual int qt_metacall(QMetaObject::Call, int, void **); \
private:
/* tmake ignore Q_OBJECT */
#define Q_OBJECT_FAKE Q_OBJECT
/*... Corte el codigo por razones obvias */

 

Entonces podemos ver que el compilador nunca nos dará error al compilar debido a estas macros. Pero ahora se preguntaran ¿cómo hacen las Qt para relacionar las clases mediantes las señales y slots?. Muy sencillo "MOC", el Meta Object Compiler es el que parsea los archivos cuyas clases tienen definida la macro Q_OBJECT e ignarará las que no la tienen. Entonces este agarrará el código fuente de la clase y generará código extra a nuestro sistema. Seguro vieron archivos moc_xxx.cpp (xxx es el nombre del archivo) que aparecen al compilar, esto es el código que genera moc. Más adelante hablaré más sobre esto.

leo | Qt-src, Qt-doc | 8 Agosto, 8:55pm | Comentar acerca de esto

Amigos

ggerman
LugOroVerde
KDE
Qt on Freenode
Okular