Programando en GNU/Linux con
QT4 y C++
José Armando Acencio
http://www.arcacsl.col.nu/
colharmando@gmail.com
29 de Abril de 2008
ÍNDICE
INTRODUCCION............................................................................2
INSTALACIÓN................................................................................3
1. HOLA MUNDO...........................................................................3
2. CALCULADORA........................................................................7
INTRODUCCIÓN
El manual esta dedicado a las personas que desean programar sin importar si tienen conocimiento en programación orientada a Objetos en C++. El único requisito para este manual es el interés de cada uno de ustedes para aprender.
Qt Open Source Edition está destinado para el desarrollo de aplicaciones de código abierto. Y si usted necesitad hacer algo en código cerrado necesita una licencia de QT.
INSTALACIÓN
Para comenzar necesitaremos:
QT4 Designer
QT4 Assistant
QT4 Linguist
Todo esto lo pueden buscar en el Gestor de paquetes (Synaptic) para el caso de Ubuntu y PCLinuxOS.
Cuando ejecuten QT4-Designer aparecerá varias ventanas, pero si prefieren pueden unirlas solo hay que hacer lo siguiente: ir al menú edit->preferences y en User interface mode seleccionar Docked window.
1. HOLA MUNDO
El primer ejemplo sera un típico hola mundo. Al abrir QT4-Designer aparece una ventana principal donde muestra y escogemos donde dice Widget, con esto saldrá una ventana y como es un hola mundo acomodamos la ventana al gusto de cada uno.
En la parte izquierda están las herramientas que podemos usar al hacer una aplicación y en la parte derecha las propiedades de cada herramienta widget solo hay que seleccionarla dando un click y verán las propiedades de esta.
En propiedades de la ventana hacemos esto:
objectName -----FrmHola (es el nombre significativo del widget)
windowTitle-----Hola Mundo (titulo de la ventana)
el resto de las propiedades las dejo a ustedes.
En la parte de herramientas widget buscamos un Label y lo llevamos a la ventana y en propiedades:
objectName-----labelHola
text--------------- (en blanco)
Ahora vamos al menu File->Save Form para guardar. Crear una carpeta que se llame holaMundo y dentro de esta guardar como frmhola.ui (es importante que lleve el nombre de la ventana widget pero todo en minuscula, es solo para llevar un orden) y ya podemos cerrar QT4-Designer.
Abrimos una terminal y entramos hasta el directorio holaMundo:
$ uic -o ui_frmhola.h frmhola.ui
Si no les funciona solo el uic prueben esto:
$ /usr/lib/qt4/bin/uic -o ui_frmhola.h frmhola.ui
Con esto creamos la clase ui_frmhola.h que tendrá esto:
#ifndef UI_FRMHOLA_H
#define UI_FRMHOLA_H
#include
#include
#include
#include
#include
#include
class Ui_FrmHola
{
public:
QLabel *labelHola;
void setupUi(QWidget *FrmHola)
{
if (FrmHola->objectName().isEmpty())
FrmHola->setObjectName(QString::fromUtf8("FrmHola"));
FrmHola->resize(400, 128);
labelHola = new QLabel(FrmHola);
labelHola->setObjectName(QString::fromUtf8("labelHola"));
labelHola->setGeometry(QRect(20, 20, 361, 71));
QFont font;
font.setPointSize(20);
labelHola->setFont(font);
retranslateUi(FrmHola);
QMetaObject::connectSlotsByName(FrmHola);
} // setupUi
void retranslateUi(QWidget *FrmHola)
{
FrmHola->setWindowTitle(QApplication::translate("FrmHola", "Hola Mundo", 0, QApplication::UnicodeUTF8));
labelHola->setText("Hola Mundo"); /* Aca escribimos el mensaje*/
Q_UNUSED(FrmHola);
} // retranslateUi
};
namespace Ui {
class FrmHola: public Ui_FrmHola {};
} // namespace Ui
#endif // UI_FRMHOLA_H
Desde un editor de texto que prefieran escribir esto y guardar como main.cpp:
#include
#include
#include "ui_frmhola.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Ui::FrmHola ui;
QDialog *ver = new QDialog;
ui.setupUi(ver);
ver->show();
return app.exec();
}
Volvemos a la terminal:
$ qmake -project
$ /usr/lib/qt4/bin/qmake -project
Esto creara un archivo .pro, también lo podemos hacer nosotros.
$ qmake
$ /usr/lib/qt4/bin/qmake
Hace el Makefile y por ultimo:
$ make
creara el ejecutable y ya podemos verlo con el nombre de la carpeta holaMundo
2. CALCULADORA
La calculadora es un ejemplo claro de como usar una clase base algo que hace mas entendible este tema en programación orientada a objetos.
Estos van hacer los archivo iniciales
frmcalculadora.ui ui_frmcalculadora.h
calculara.h calcular.cpp main.cpp
Como se muestra la imagen hacemos la calculadora con un Line Edit y 20 PushButton.
En las propiedades de la ventana widget:
objectName------------------FrmCalculadora
windowTitle-----------------'Calculadora QT4'
En la parte de propiedades del Line Edit hacer esto:
objectName------------------lineEdit
alignment (horizontal)------Qt::AlignRight
readOnly----------------------true
Propiedad de cada uno de los PushButton:
Botón retroceder:
objectName-------------------pushButtonRetroceder (si lo prefieren pueden dejar el nombre mas corto)
text-----------------------------'Retroceder'
Botón borrar:
objectName-------------------pushButtonBorrar
text-----------------------------'Borrar'
Botón borrar todo:
objectName-------------------pushButtonBorrarTodo
text--------------------------'Borrar Todo'
Todos lo botones numéricos:
objectName------------------pushButton_0 (1, 2, 3, 4, 5, 6, 7, 8, 9)
text-------------------------'0 (1, 2, 3, 4, 5, 6, 7, 8, 9)'
Botones de operación:
objectName-------------------pushButtonIgual (Por, Divive, Mas, Menos)
text--------------------------'= (x, ÷, +, -)'
Boton de Signo:
objectName-------------------pushButtonSigno
text--------------------------'±'
Boton de coma:
objectName-------------------pushButtonComa
text--------------------------'.'
Guardamos como frmcalculadora.ui en una carpeta llamada 'calculadora'
hacemos nuestra clase:
$uic -o ui_frmcalculadora.h frmcalculadora.ui
$ /usr/lib/qt4/bin/uic -o ui_frmcalculadora.h frmcalculadora.ui
Desde un editor hacemos la clase calcular.h en base a la clase ui_frmcalculadora.h
#ifndef CALCULADORA_H
#define CALCULADORA_H
#include
#include "ui_frmcalculadora.h"
class FrmCalculadora : public QDialog, public Ui::FrmCalculadora
{
Q_OBJECT
public:
FrmCalculadora(QWidget *parent = 0);
private slots: //Los signal y slots se utilizan para la comunicación entre objetos
void signo();
void button0();
void button1();
void button2();
void button3();
void button4();
void button5();
void button6();
void button7();
void button8();
void button9();
void multiplicativo();
void sumaOResta();
void igual();
void buttonComa();
void retroceder();
void borrar();
void borrarTodo();
private: //las funciones y variables
double numMemoria;
double factor;
double numExtremo;
QString addOperador;
QString oper;
bool calcular(double operador, const QString &esperaOperador);
bool operadorEnEspera;
void abortarOperacion();
};
#endif
Ahora calcular.cpp
#include
#include
#include
#include "calcular.h"
FrmCalculadora::FrmCalculadora(QWidget *parent)
: QDialog(parent)
{
numMemoria = 0.0;
factor = 0.0;
numExtremo = 0.0;
operadorEnEspera = true;
setupUi(this);
connect( pushButton_1, SIGNAL( clicked() ), this , SLOT( button1() ) );
connect( pushButton_2, SIGNAL( clicked() ), this , SLOT( button2() ) );
connect( pushButton_3, SIGNAL( clicked() ), this , SLOT( button3() ) );
connect( pushButton_4, SIGNAL( clicked() ), this , SLOT( button4() ) );
connect( pushButton_5, SIGNAL( clicked() ), this , SLOT( button5() ) );
connect( pushButton_6, SIGNAL( clicked() ), this , SLOT( button6() ) );
connect( pushButton_7, SIGNAL( clicked() ), this , SLOT( button7() ) );
connect( pushButton_8, SIGNAL( clicked() ), this , SLOT( button8() ) );
connect( pushButton_9, SIGNAL( clicked() ), this , SLOT( button9() ) );
connect( pushButton_0, SIGNAL( clicked() ), this , SLOT( button0() ) );
connect(pushButtonComa, SIGNAL( clicked() ), this, SLOT( buttonComa() ) );
connect( pushButtonMas, SIGNAL( clicked() ), this, SLOT( sumaOResta() ) );
connect(pushButtonMenos,SIGNAL(clicked() ), this, SLOT( sumaOResta() ) );
connect( pushButtonPor, SIGNAL( clicked() ), this, SLOT( multiplicativo() ) );
connect(pushButtonDivide,SIGNAL(clicked()),this, SLOT( multiplicativo() ) );
connect( pushButtonSigno, SIGNAL( clicked() ), this, SLOT( signo() ) );
connect(pushButtonRetroceder,SIGNAL(clicked()),this, SLOT( retroceder() ) );
connect( pushButtonBorrar, SIGNAL( clicked() ), this, SLOT( borrar() ) );
connect(pushButtonBorrarTodo,SIGNAL(clicked()),this,SLOT(borrarTodo()) );
connect( pushButtonIgual, SIGNAL( clicked() ), this, SLOT( igual() ) );
}
void FrmCalculadora::button1()
{
if(operadorEnEspera) {
lineEdit->clear();
operadorEnEspera = false;
}
QString valor=lineEdit->text();
valor+="1";
lineEdit->setText(valor);
}
void FrmCalculadora::button2()
{
if(operadorEnEspera) {
lineEdit->clear();
operadorEnEspera = false;
}
QString valor=lineEdit->text();
valor+="2";
lineEdit->setText(valor);
}
void FrmCalculadora::button3()
{
if(operadorEnEspera) {
lineEdit->clear();
operadorEnEspera = false;
}
QString valor=lineEdit->text();
valor+="3";
lineEdit->setText(valor);
}
void FrmCalculadora::button4()
{
if(operadorEnEspera) {
lineEdit->clear();
operadorEnEspera = false;
}
QString valor=lineEdit->text();
valor+="4";
lineEdit->setText(valor);
}
void FrmCalculadora::button5()
{
if(operadorEnEspera) {
lineEdit->clear();
operadorEnEspera = false;
}
QString valor=lineEdit->text();
valor+="5";
lineEdit->setText(valor);
}
void FrmCalculadora::button6()
{
if(operadorEnEspera) {
lineEdit->clear();
operadorEnEspera = false;
}
QString valor=lineEdit->text();
valor+="6";
lineEdit->setText(valor);
}
void FrmCalculadora::button7()
{
if(operadorEnEspera) {
lineEdit->clear();
operadorEnEspera = false;
}
QString valor=lineEdit->text();
valor+="7";
lineEdit->setText(valor);
}
void FrmCalculadora::button8()
{
if(operadorEnEspera) {
lineEdit->clear();
operadorEnEspera = false;
}
QString valor=lineEdit->text();
valor+="8";
lineEdit->setText(valor);
}
void FrmCalculadora::button9()
{
if(operadorEnEspera) {
lineEdit->clear();
operadorEnEspera = false;
}
QString valor=lineEdit->text();
valor+="9";
lineEdit->setText(valor);
}
void FrmCalculadora::button0()
{
if(lineEdit->text() == "0") return;
else {
QString valor=lineEdit->text();
valor+="0";
lineEdit->setText(valor);
}
}
void FrmCalculadora::sumaOResta() //void Calculator::additiveOperatorClicked()
{
QPushButton *clickButton= qobject_cast(sender());
QString operador=clickButton->text();
double valor=lineEdit->text().toDouble(); //.toDouble() convierte la cadena a double
if( !oper.isEmpty() ) { //.isEmpty verifica que este vacio el string
if( !calcular(valor, oper) ){
abortarOperacion();
return;
}
lineEdit->setText( QString::number(factor) );
valor=factor;
factor= 0.0;
oper.clear();
}
if( !addOperador.isEmpty() ) {
if( !calcular(valor, addOperador) ) {
abortarOperacion();
return;
}
lineEdit->setText( QString::number(numExtremo) );
}
else numExtremo = valor;
addOperador = operador;
operadorEnEspera = true;
}
void FrmCalculadora::multiplicativo()
{
QPushButton *clickButton= qobject_cast(sender());
QString operador=clickButton->text();
double valor=lineEdit->text().toDouble();
if( !oper.isEmpty() ) {
if( !calcular(valor, oper) ) {
abortarOperacion();
return;
}
lineEdit->setText( QString::number(factor) );
valor=factor;
factor=0.0;
oper.clear();
}
if( !addOperador.isEmpty() ) {
if( !calcular(valor, addOperador) ) {
abortarOperacion();
return;
}
lineEdit->setText( QString::number(numExtremo) );
}
else numExtremo = valor;
addOperador = operador;
operadorEnEspera = true;
}
void FrmCalculadora::igual()
{
double valor=lineEdit->text().toDouble();
if( !oper.isEmpty() ) {
if( !calcular(valor, oper) ) {
abortarOperacion();
return;
}
valor = factor;
factor = 0.0;
oper.clear();
}
if( !addOperador.isEmpty() ) {
if( !calcular(valor, addOperador) ) {
abortarOperacion();
return;
}
addOperador.clear();
}
else numExtremo = valor;
lineEdit->setText( QString::number(numExtremo) );
numExtremo = 0.0;
operadorEnEspera = true;
}
void FrmCalculadora::buttonComa()
{
if(operadorEnEspera) lineEdit->setText("0");
if( !lineEdit->text().contains(".") ) lineEdit->setText( lineEdit->text() + tr(".") );
operadorEnEspera = false;
}
void FrmCalculadora::signo()
{
QString texto = lineEdit->text();
double valor = texto.toDouble();
if( valor>0.0 ) texto.prepend( tr("-") );
else if( valor<0.0>
lineEdit->setText(texto);
}
void FrmCalculadora::retroceder()
{
if( operadorEnEspera) return;
QString texto = lineEdit->text();
texto.chop(1); //.chop(1) borra la ultima letra que esta en la cola del string
if( texto.isEmpty() ) {
texto = "0";
operadorEnEspera = true;
}
lineEdit->setText(texto);
}
void FrmCalculadora::borrar()
{
if( operadorEnEspera ) return;
lineEdit->setText("0");
operadorEnEspera = true;
}
void FrmCalculadora::borrarTodo()
{
numExtremo=0.0;
factor=0.0;
addOperador.clear();
oper.clear();
lineEdit->setText("0");
operadorEnEspera=true;
}
void FrmCalculadora::abortarOperacion()
{
borrarTodo();
lineEdit->setText("####");
}
bool FrmCalculadora::calcular(double operador, const QString &esperaOperador)
{
if( esperaOperador == tr("+") ) numExtremo += operador;
else if( esperaOperador == tr("-") ) numExtremo -= operador;
else if( esperaOperador == tr("x") ) numExtremo *= operador;
else if( esperaOperador == tr("\367") ) { // \367 compara con ÷
if(operador == 0.0) {
return false;
}
numExtremo /= operador;
}
return true;
}
Y por ultimo main.cpp
#include
#include "calcular.h"
int main( int argc, char *argv[] )
{
QApplication app(argc, argv);
FrmCalculadora ver;
ver.show();
return app.exec();
}
Guardamos todos los archivos y desde la terminal dentro del directorio 'calculadora':
$qmake -project
$ /usr/lib/qt4/bin/qmake -project
$qmake
$ /usr/lib/qt4/bin/qmake
$make