Login
Newsletter
Werbung

Mo, 16. August 1999, 00:00

KDE-Programmierung: KProcess

In diesem Teil des Workshops wird Word2HTML erstmals eine sinnvolle Aufgabe erfüllen.

Wie geht's weiter?

In diesem Teil des Workshops wird Word2HTML erstmals eine sinnvolle Aufgabe erfüllen. Wir werden das Kommandozeilenprogramm mswordview ausführen und ihm den Pfad einer DOC-Datei übergeben, die der Anwender in einem Dateiauswahldialog auswählen kann. Diese Datei wird dann von mswordview in eine HTML-Datei konvertiert. Die Ausgabe von mswordview lassen wir im Programmfenster anzeigen. Wir haben also ein klassisches Frontend, das die Funktionalität eines Kommandozeilenprogrammes über eine grafische Oberfläche bereitstellt.

Was ist KProcess?

Normalerweise müssten wir auf Systemaufrufe zurückgreifen, um mswordview aus Word2HTML heraus auszuführen. Da das sehr unkomfortabel und fehlerträchtig ist, stellen die KDE-Libs die Klasse KProcess zur Verfügung. Sie erlaubt es auf einfache Weise, fremde Programme zu starten und auf ihre Ausgaben zu reagieren. Unter http://developer.kde.org finden Sie eine Referenz mit allen Klassen der KDE-Libs.

Der Code

Laden Sie einfach die neuen Quellen herunter und überschreiben die alten damit. Achten Sie aber darauf, dass Sie in KDevelop unter ProjektOptionen auf der Registrierkarte Linker-Optionen »kfm« und »kfile« ausgewählt haben.

/* toplevel.h */
#ifndef _TOPLEVEL_H_
#define _TOPLEVEL_H_
#include <kapp.h>
#include <ktmainwindow.h>
#include <kmenubar.h>
#include <qpopupmenu.h>
#include <qmessagebox.h>
#include <kfiledialog.h>
#include <qmultilinedit.h>
#include <kprocess.h>
#include <qfileinfo.h>
class TopLevel : public KTMainWindow
{
 Q_OBJECT
public:
 TopLevel();
 void closeEvent(QCloseEvent *);
private slots:
 void aboutApp();
 void openFile();
 void getOutput(KProcess *, char *, int);
private:
 QMultiLineEdit *outputDisplay;
 KProcess proc;
};
#endif

Erklärung

 void openFile();
 void getOutput(KProcess *, char *, int);

Es werden zwei neue Slots deklariert. Der erste wird ausgeführt werden, um einen Dateiauswahldialog zu öffnen und die ausgewählte Datei zu konvertieren. Der zweite wird die Ausgaben von mswordview entgegennehmen und innerhalb des Programmfensters anzeigen.

 QMultiLineEdit *outputDisplay;
 KProcess proc;

Hier wird ein Zeiger auf die Klasse QMultiLineEdit und ein Objekt der Klasse KProcess deklariert. Die Klasse QMultiLineEdit ist ein ganz gewöhnliches Editorfeld, wie es z.B. in KEdit Verwendung findet. Wir verwenden sie um die Ausgaben von mswordview darzustellen.

/* toplevel.cpp */
#include "toplevel.h"
TopLevel::TopLevel()
{
 QPopupMenu *file = new QPopupMenu;
 file->insertItem(i18n("Open ..."), this, SLOT(openFile()));
 file->insertSeparator();
 file->insertItem(i18n("&Quit"), kapp, SLOT(quit()));
 QPopupMenu *help = new QPopupMenu;
 help->insertItem(i18n("&About"), this, SLOT(aboutApp()));
 KMenuBar *menu = new KMenuBar(this);
 menu->insertItem(i18n("&File"), file);
 menu->insertSeparator();
 menu->insertItem(i18n("&Help"), help);
 setMenu(menu);
 outputDisplay = new QMultiLineEdit(this);
 outputDisplay->setReadOnly(true);
 setView(outputDisplay);
 connect(&proc, SIGNAL(receivedStdout(KProcess *, char *, int)),
 this, SLOT(getOutput(KProcess *, char *, int)));
 connect(&proc, SIGNAL(receivedStderr(KProcess *, char *, int)),
 this, SLOT(getOutput(KProcess *, char *, int)));
 resize(500,400);
 setCaption("Word2HTML");
}
void TopLevel::closeEvent(QCloseEvent *)
{
 kapp->quit();
}
void TopLevel::aboutApp()
{
 QMessageBox::about(this, "About Word2HTML","Hello World");
}
void TopLevel::openFile()
{
 QString filename = KFileDialog::getOpenFileName(NULL, "*.doc");
 if (filename == NULL)
 return;
 QFileInfo file(filename);
 if (!file.exists())
 return;
 if (file.isDir())
 return;
 proc << "mswordview";
 proc << filename;
 proc.start(KProcess::NotifyOnExit, KProcess::AllOutput);
}
void TopLevel::getOutput(KProcess *, char *data, int len)
{
 char dst[len+1];
 memmove(dst,data,len);
 dst[len]=0;
 outputDisplay->append(dst);
}

Erklärung

 file->insertItem(i18n("Open ..."), this, SLOT(openFile()));

Im Menü File wird der Eintrag Open... hinzugefügt und mit unserem neuen Slot openFile() verbunden.

 outputDisplay = new QMultiLineEdit(this);
 outputDisplay->setReadOnly(true);

Unser Ausgabefeld für mswordview wird erzeugt. Da es nicht editierbar sein soll, wird es auf »read only« gesetzt.

 setView(outputDisplay);

Das Ausgabefeld wird innerhalb des Fensters maximiert. Bei jeder Veränderung des Fensters wird es angepasst.

 connect(&proc, SIGNAL(receivedStdout(KProcess *, char *, int)),
 this, SLOT(getOutput(KProcess *, char *, int)));

Das Objekt proc von der Klasse KProcess sendet ein Signal aus, sobald das von ihm gestartete Programm eine Ausgabe auf den Standard-Ausgabekanal macht. Diese Ausgabe liefert es in Form eines Zeigers auf char und eines Integerwertes, der die Länge angibt, auch gleich mit. Dieses Signal wird nun mit unserem Slot getOutput(KProcess *, char *, int) verbunden. Er nimmt diese Daten entgegen und zeigt sie auf unserem Ausgabefeld an.

 connect(&proc, SIGNAL(receivedStderr(KProcess *, char *, int)),
 this, SLOT(getOutput(KProcess *, char *, int)));

Dasselbe noch einmal, diesmal eben für die Standard-Fehlerausgabe.

void TopLevel::openFile()
{
 QString filename = KFileDialog::getOpenFileName(NULL, "*.doc");
 if (filename == NULL)
 return;

Mit der Funktion getOpenFileName() der Klasse KFileDialog wird ein Dateiauswahldialog angezeigt. Sein Rückgabewert, also die ausgewählte Datei, wird in einem Objekt filename vom Typ QString gespeichert. Wenn der Inhalt von filename NULL ist, also wenn der Anwender Abbrechen gewählt hat, wird die komplette Funktion mit return abgebrochen.

 QFileInfo file(filename);
 if (!file.exists())
 return;
 if (file.isDir())
 return;

Es wird geprüft, ob filename auf eine existierende Datei verweist. Wenn nicht, wird die Funktion abgebrochen.

 proc << "mswordview";
 proc << filename;
 proc.start(KProcess::NotifyOnExit, KProcess::AllOutput);
}

Das Objekt wird mit dem Namen des auszuführenden Programms und seinen Parametern (in diesem Fall nur dem Namen der zu konvertierenden Datei) »gefüttert« und gestartet.

void TopLevel::getOutput(KProcess *, char *data, int len)
{
 char dst[len+1];
 memmove(dst,data,len);
 dst[len]=0;

Die Ausgaben von mswordview werden entgegengenommen. Da wir nur den Zeiger auf einen String bekommen, der zu dem Zeitpunkt, wo er angezeigt werden soll, nicht mehr existiert, wird er in ein Array vom Typ char kopiert.

 outputDisplay->append(dst);
}

Der String, den wir so eben kopiert haben, wird auf dem Ausgabefeld ausgegeben.

Kommentare (Insgesamt: 0 )
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung