[Kde-devel-es] Tutorial: p4

Antonio Larrosa Jiménez kde-devel-es@mail.kde.org
Mon, 21 Oct 2002 14:41:37 +0200


--Boundary-00=_BY/s9ZOVMD6QUE1
Content-Type: text/plain;
  charset="iso-8859-15"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Hola,

Ante todo, perdonad el retraso, he estado bastante liado entre otros=20
trabajos en KDE,  las Jornadas de ADALA y preparando la presentaci=F3n all=
=ED=20
junto con el tutorial de Qt Designer y KDevelop (ya lo tengo planteado y=20
el c=F3digo fuente hecho, s=F3lo me queda escribirlo :) ).

En cualquier caso, aqu=ED llega p4, que es la primera versi=F3n de nuestro=
=20
navegador web. Como siempre, teneis la p=E1gina en=20
http://devel-home.kde.org/~larrosa/es/tutorial/p4.html
El c=F3digo fuente para compilarlo mejor baj=E1rselo de=20
http://devel-home.kde.org/~larrosa/tutorial.html
y para cualquier duda hacedla en la lista (espero que haya m=E1s que con p2=
 y=20
p3 que no tuvieron ninguna pregunta).

Saludos,

=2D-
Antonio Larrosa Jimenez
KDE core developer - larrosa@kde.org
http://devel-home.kde.org/~larrosa/
With a rubber duck,one's never alone --The Hitchhiker's Guide to the Galaxy
--Boundary-00=_BY/s9ZOVMD6QUE1
Content-Type: text/html;
  charset="iso-8859-15";
  name="p4.html"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename="p4.html"

<HTML>
<HEAD>
<TITLE>
Tutorial de KDE - p4
</TITLE>
</HEAD>
<BODY BGCOLOR=3Dwhite COLOR=3Dblack>
<H2><CENTER>p4</CENTER></H2> =20
<P ALIGN=3D"RIGHT">
<A HREF=3D"p5.html">Siguiente</A>
<A HREF=3D"p3.html">Anterior</A>
<A HREF=3D"index.html">Tabla de Contenidos</A></P>
Ahora que sabemos crear un men&uacute; haremos una aplicaci&oacute;n casi r=
eal en p4.
Gracias al trabajo de Lars Knoll, Dirk Mueller, Antti Koivisto, Waldo Basti=
an y muchos otros, podemos=20
usar un objeto KHTML, un widget que es capaz de mostrar una p&aacute;gina H=
TML, y que usando=20
la libreria KIO es capaz de traer esa p&aacute;gina de la red. Veamos como =
funciona.
<P>
<HR>
<BLOCKQUOTE><PRE>
#include &lt;kapp.h&gt;
#include "p4.h"
=20
int main( int argc, char **argv )
{
    KApplication a( argc, argv, "p4" );
=20
    MainWindow *window=3Dnew MainWindow( "Tutorial - p4" );
    window-&gt;resize( 300, 200 );
=20
    a.setMainWidget( window );
    window-&gt;show();
=20
    return a.exec();
}=20
</PRE></BLOCKQUOTE>
<HR>
<DIV ALIGN=3DRIGHT>main.cpp</DIV>
<P>
<HR>
<BLOCKQUOTE><PRE>
#include &lt;kmainwindow.h&gt;
#include &lt;kurl.h&gt;
#include &lt;kparts/browserextension.h&gt;


class QLineEdit;
class KHTMLPart;
=20
class MainWindow : public KMainWindow
{
  Q_OBJECT
=20
  public:
    MainWindow ( const char * name );
=20
  public slots:
    void changeLocation();
    void openURLRequest(const KURL &amp;url, const KParts::URLArgs &amp; );
=20
  private:
    QLineEdit *location;
    KHTMLPart *browser;
=20
};=20
</PRE></BLOCKQUOTE>
<HR>
<DIV ALIGN=3DRIGHT>p4.h</DIV>
<P>
<HR>
<BLOCKQUOTE><PRE>
#include "p4.h"
#include &lt;qvbox.h&gt;
#include &lt;qlineedit.h&gt;
#include &lt;kapp.h&gt;
#include &lt;kmenubar.h&gt;
#include &lt;klocale.h&gt;
#include &lt;kpopupmenu.h&gt;
#include &lt;khtml_part.h&gt;

MainWindow::MainWindow ( const char * name ) : KMainWindow ( 0L, name )
{
    setCaption("KDE Tutorial - p4");
   =20
    QPopupMenu * filemenu =3D new QPopupMenu;
    filemenu-&gt;insertItem( i18n( "&amp;Quit" ), kapp, SLOT( quit() ) );
    QString about =3D
            i18n("p4 1.0\n\n"
                 "(C) 1999-2002 Antonio Larrosa Jimenez\n"
                 "larrosa@kde.org\t\tantlarr@supercable.es\n"
                 "Malaga (Spain)\n\n"
                 "Simple KDE Tutorial\n"
                 "This tutorial comes with ABSOLUTELY NO WARRANTY \n"
                 "This is free software, and you are welcome to redistribut=
e it\n"
                 "under certain conditions\n");
=20
    QPopupMenu *helpmenu =3D helpMenu(about);
    KMenuBar * menu =3D menuBar();
    menu-&gt;insertItem( i18n( "&amp;File" ), filemenu);
    menu-&gt;insertSeparator();
    menu-&gt;insertItem(i18n("&amp;Help"), helpmenu);
=20
    QVBox * vbox =3D new QVBox ( this );
=20
    location =3D new QLineEdit ( vbox );
    location-&gt;setText( "http://localhost" );
=20
    browser=3Dnew KHTMLPart( vbox );
    browser-&gt;openURL( location-&gt;text() );
=20
    connect( location , SIGNAL( returnPressed() ),
                this, SLOT( changeLocation() ) );
=20
    connect( browser-&gt;browserExtension(),
       SIGNAL( openURLRequest( const KURL &amp;, const KParts::URLArgs &amp=
; ) ),
       this, SLOT( openURLRequest(const KURL &amp;, const KParts::URLArgs &=
amp; ) ) );

    setCentralWidget( vbox );
}                                                                          =
    =20

void MainWindow::changeLocation()
{
    browser-&gt;openURL( location-&gt;text() );
}=20

void MainWindow::openURLRequest(const KURL &amp;url, const KParts::URLArgs =
&amp; )
{
    location-&gt;setText(url.url());
    changeLocation();
}
</PRE></BLOCKQUOTE>
<HR>
<DIV ALIGN=3DRIGHT>p4.cpp</DIV>
<P>
La primera diferencia que vemos con p3 esta en p4.h . Solo vamos a usar los=
 men&uacute;s para=20
salir de la aplicaci&oacute;n, as&iacute; que hemos quitado los dos slots q=
ue usabamos para=20
los di&aacute;logos de Open y Save.
<P>
<PRE>
  public slots:
    void changeLocation();
    void openURLRequest(const KURL &amp;url, const KParts::URLArgs &amp; );

  private:
    QLineEdit *location;
    KHTMLPart *browser;
</PRE>=20
<P>
Estamos definiendo un slot <CODE>changeLocation()</CODE> para que sea llama=
do cuando el
usuario quiera cargar una p&aacute;gina pulsando Enter en la barra de direc=
ci=F3n .
El m=E9todo openURLRequest es un slot que se llama cuando el usuario pulsa =
en un enlace
en la p=E1gina html, y la p=E1gina html "nos pide" que abramos esa direcci=
=F3n (que se pasa
como par=E1metro). Ahora vamos a usar dos widgets, uno es un widget QLineEd=
it
y el otro un KHTMLPart. QLineEdit implementa una linea en la que el usuario=
 puede editar
texto, en este caso la direcci&oacute;n de la p&aacute;gina html que va a m=
ostrar KHTMLPart.
<P>
<PRE>
    QVBox * vbox =3D new QVBox ( this );
</PRE>=20
<P>
Estamos usando un QVBox para manejar la disposici&oacute;n (layout) de los =
widgets. Como queremos
mostrar el widget QLineEdit y el KHTMLPart uno bajo el otro, esta es una mi=
si&oacute;n
perfecta para QVBox. Este widget autom&aacute;ticamente pone todos sus hijo=
s en una disposici&oacute;n
vertical (asi como un QHBox los pone horizontalmente), y actualiza su dispo=
sici&oacute;n siempre
que el QVBox es redimensionado. Hay que fijarse que podemos usar disposicio=
nes mas complejas=20
usando otras clases, como QGridLayout, para manejar su geometr&iacute;a, o =
incluso manejarlo
manualmente como hacen otros toolkits. Pero todo esto simplifica el c&oacut=
e;digo, a la vez=20
que lo hacen m=E1s flexible. Hay que observar que cada vez que el usuario r=
edimensiona la
ventana, el widget KHTMLPart ocupa la altura m&aacute;xima que puede mientr=
as
que el QLineEdit siempre ocupa una altura fija, y entre los dos siempre ocu=
pan el=20
tama&ntilde;o total de la ventana principal de la aplicaci&oacute;n.
<P>
<PRE>
    location =3D new QLineEdit ( vbox );
    location-&gt;setText( "http://localhost" );
</PRE>=20
<P>
Creamos un objeto QLineEdit, location, como un hijo de vbox y le ponemos al=
go de
texto que sera el que muestre por defecto.
<P>
Ahora se puede navegar con internet con esta aplicaci&oacute;n, pero como m=
uchas personas
solamente lo podran testear con su servidor local web, por estar realizando=
 las=20
pruebas sin conexi&oacute;n a internet, es el que hemos puesto por defecto.=
 Asegurate de=20
estar ejecutando apache en tu m&aacute;quina para que esta aplicaci&oacute;=
n (=A1 y las siguientes !)
funcionen.
<P>
<PRE>
    browser=3Dnew KHTMLPart( vbox );
    browser-&gt;openURL( location-&gt;text() );
</PRE>=20
<P>
Con este c&oacute;digo creamos el objeto navegador como un hijo de vbox, co=
n lo que ser&aacute;
a&ntilde;adido debajo de location (la barra que contiene la direcci&oacute;=
n).
<P>
Llamando a <CODE>openURL</CODE> le pedimos a KHTMLPart que descargue la url=
 que est&aacute;
escrita en la linea de edici=F3n de location, y que lo muestre.
<P>
<PRE>
    connect( location , SIGNAL( returnPressed() ),
                this, SLOT( changeLocation() ) );
</PRE>=20
<P>
Cuando el usuario presiona enter en la barra de la direcci&oacute;n, &eacut=
e;sta emite una se&ntilde;al
<CODE>returnPressed()</CODE>, con este c&oacute;digo conectamos esa se&ntil=
de;al al slot
<CODE>changeLocation()</CODE> en este (<CODE>this</CODE>) objeto. Podemos l=
lamar
a <CODE>connect</CODE> directamente (sin usar QObject::)  ya que estamos en
una clase que hereda de QObject ( indirectamente, ya que heredamos de KMain=
Window,
que a su vez hereda de QWidget, que a su vez hereda de QObject).
<P>
<PRE>
    connect( browser-&gt;browserExtension(),
           SIGNAL( openURLRequest( const KURL &amp;, const KParts::URLArgs =
&amp; ) ),
           this, SLOT( openURLRequest(const KURL &amp;, const KParts::URLAr=
gs &amp; ) ) );
=20
</PRE>=20
<P>
Estamos ahora conectando otra se&ntilde;al a un slot. Lo bueno ahora es que=
 el <CODE>browser</CODE>
emite una se&ntilde;al <CODE>openURLRequest( const KURL &amp;, const KParts=
::URLArgs &amp; )</CODE> cuando quiere abrir una URL (por ejemplo, porque e=
l usuario haya pulsado en un enlace). De hecho, la
se=F1al no la emite el propio objeto KHTMLPart, sino su objeto browserExten=
sion, y es por eso que lo
ponemos como primer par&aacute;metro (el objeto que emite la se=F1al).
<P>
Por cierto, el segundo par=E1metro no lo usamos, as=ED que vamos a ignorarl=
o pues s=F3lo se usa
en ocasiones muy especiales.
<P>
<PRE>
    setCentralWidget( vbox );
</PRE>=20
<P>
Ahora ponemos el widget vbox como el widget central del objeto KMainWindow.
<P>
<PRE>
    browser-&gt;openURL( location-&gt;text() );
</PRE>=20
<P>
El slot <CODE>changeLocation</CODE> simplemente pide al <CODE>browser</CODE>
que abra el url que esta escrito en la barra de direcci&oacute;n.
<P>
<PRE>
void MainWindow::openURLRequest(const KURL &amp;url, const KParts::URLArgs =
&amp; )
{
    location-&gt;setText(url.url());
    changeLocation();
}
</PRE>
<P>
&Eacute;ste es el c=F3digo que se llama cuando el navegador quiere abrir un=
a nueva direcci=F3n.
Como recordar=E1, el m=E9todo url() de la clase KURL nos devuelve la url co=
mpleta, as=ED
que la escribimos en la barra de direcci=F3n. Entonces llamamos a changeLoc=
ation(), para
abrir la url que hay en la barra de direcci=F3n dentro de la "parte" html.
<P>
Piense en todo lo que hemos hecho con s&oacute;lo 96 lineas. =A1Imagine lo =
que se
puede conseguir con 1000! :-)
<P ALIGN=3D"RIGHT">
<A HREF=3D"p5.html">Siguiente</A>
<A HREF=3D"p3.html">Anterior</A>
<A HREF=3D"index.html">Tabla de Contenidos</A></P>
<HR>
<CENTER>&copy; 1999-2002 <A HREF=3D"mailto:larrosa@kde.org">Antonio Larrosa=
</A></CENTER>
<CENTER>Traducido por <A HREF=3D"mailto:rafael@picasso.scai.uma.es">Rafael =
Larrosa</A> y <A HREF=3D"mailto:larrosa@kde.org">Antonio Larrosa</A></CENTE=
R>
</BODY>
</HTML>

--Boundary-00=_BY/s9ZOVMD6QUE1--