PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : KProcess, HowTo?



Hans-Georg Normann
20-01-2003, 21:25
So langsam dämmerts mir. Ist ja gar nicht schwer, C++ mit QT zu verbinden.

Ich habe mir ein kleines Programm ausgedacht, welches lediglich aus aus einer QTextLine Box besteht. Mit Klick auf OK soll ein ls -al an das System geschickt und in der Textbox ausgegeben werden. Währen das ls Kommando läuft, soll die LED-Farbe rot, sonst grün sein. (KLed wurde verwendet).

Das Programm macht eigentlich auch das was ich erwarte, aber das Umschlten der LED funtkioniert nicht. Kann es sein, dass während meine jetzige Routine abgearbeitet wird, die GUI nicht bearbeitet wird?

Aus diesem Grund möchte ich KProcess einbinden. Wenn da das Prob mit der Doku nicht wäre. Ich verstehe es nicht. Kann mir mal jemand eine Einstiegshilfe geben? (ich lese dafür auch anschließend die Doku nochmal durch :D )

Wenn ihr etwas seht, was man so nicht macht, bitte meckern. Besser man gewöhnt sich schlechten Stil erst garnicht an.


/* Die Schreibweise der selbstentwickelten Komponenten laesst noch zu wuenschen
uebrig, aber das bekomme ich noch hin */

#include "norcmd.h"

NorCmd::NorCmd(QWidget *parent, const char *name) : norcmdDlg(parent, name)
{
}

NorCmd::~NorCmd()
{
}

/** No descriptions */
void NorCmd::slotNorCmdSet(){
QColor c; /* Ich weiss, Delphi Progger definieren
erst alles */
FILE *fp;
char line[130]; /* line of data from unix command*/
char s[130]; /* muss ich den nochmal defieren
fuer den Gebrauch in sprintf? */

c.setNamedColor("red"); /* liefert die Farbe fuer morCmdLed */


/*** ab hier moechte ich einen Thread (Kprocess) haben ***/
this->norCmdLed->setColor(c);
this->norCmdLogBox->append("Start");


fp = popen("ls -l", "r"); /* Issue the command Read a line */
while ( fgets( line, sizeof line, fp))
{
sprintf(s, "%s", line);
this->norCmdLogBox->append(s);
}
pclose(fp);

c.setNamedColor("green");
this->norCmdLed->setColor(c);
}



Schon mal THX
Hans

anda_skoa
20-01-2003, 22:14
Also :)

vorne weg: für die Standardfarben gibt es in Qt vordefinierte Konstanten.
Wenn du zB QColor in Rot brauchst, kannst du einfach Qt::red schreiben.

Zum KProcess:

KProcess ist nicht so schwer, wie es zuerst aussieht.

Die wesentlichen Punkte sind:

1) Einen KProcess Pointer in der Klasse deklarieren.
2) zB im slot eine KProzess Instanz mit new erzeugen.
3) die gewünschten Signals verbinden
4) das Executale setzen.
5) die Parameter angeben
6) den Prozess starten

Ich versuchs mal in einem kleine Beispiel



class ProcessRunner : public QObject
{
Q_OBJECT
public:
ProcessRunner() : m_process(0) {};

void start();

public signals:
void finished(const QString& output);

protected:
KProcess* m_process;
QString m_buffer;

protected slots:
void slotProcessExited(KProcess* process);
void slotProcessOutput(KProcess* process, char* buffer, int buflen);
};




void ProcessRunner::start()
{
m_buffer = QString::null;
m_process = new KProcess();
connect(m_process, SIGNAL(processExited(KProcess*)),
this, SLOT(slotProcessExited(KProcess*)));
connect(m_process, SIGNAL(receivedStdout(KProcess*, char*, int),
this, SLOT(slotProcessOutput(KProcess*, char*, int)));

m_process->setExecutable("ls");
m_process << "-al";

m_process->start(KProcess::NotifyOnExit, KProcess::Stdout);
}

void ProcessRunner::slotProcessExited(KProcess* process)
{
if (process != m_process) return;

delete m_process;
m_process = 0;
emit finished(m_buffer);
}

void ProcessRunner::slotProcessOutput(KProcess* process, char* buffer, int len)
{
if (process != m_process) return;

m_buffer.append(QString::fromLocal8Bit(buffer, len));
}


Das ist mal so hingeschrieben, habs nicht versucht zu kompilieren :)

Hoffe es gibt dir eine Idee, wie es geht.

Ciao,
_

Hans-Georg Normann
21-01-2003, 21:56
Ihr seid mich noch nicht los:mad:

es ist zum Haare ausraufen (wenn ich denn noch welche hätte:D ) aber irgendwie bekomme ich den Kram nicht zum laufen.

/*processrunner.h*/
class ProcessRunner : public QObject {
Q_OBJECT
public:
ProcessRunner() : m_process(0) {};

/*procesrunner.cpp */
ProcessRunner::ProcessRunner(){
}
mag das Progrmm garnicht. Fehlermeldung:
processrunner.cpp:20: redefinition of `ProcessRunner::ProcessRunner()'
processrunner.h:32: `ProcessRunner::ProcessRunner()' previously defined here
processrunner.cpp:20: no `ProcessRunner::ProcessRunner()' member function


Und hier beisse ich mich auch fest.
connect(m_process,
SIGNAL(receivedStdout(KProcess*, char*, int),
this,
SLOT(slotProcessOutput(KProcess*, char*, int)));

Fehlermeldung: declared in class `ProcessRunner'
processrunner.cpp:34:59: macro "SIGNAL" passed 3 arguments, but takes just 1
processrunner.cpp: In member function `void ProcessRunner::start()':
processrunner.cpp:34: `SIGNAL' undeclared (first use this function)
processrunner.cpp:34: (Each undeclared identifier is reported only once for
each function it appears in.)
processrunner.cpp:34: parse error before `;' token
processrunner.cpp:37: invalid operands of types `KProcess*' and `const char[4]'
to binary `operator<<'
processrunner.cpp: In member function `void

Die Sache scheint in c / c++ doch nicht so einfach zu sein wie ich mir das vorgestellt hatte. Also Augen zu und durch.

Hans

anda_skoa
21-01-2003, 23:13
Original geschrieben von Hans-Georg Normann

mag das Progrmm garnicht. Fehlermeldung:
processrunner.cpp:20: redefinition of `ProcessRunner::ProcessRunner()'
processrunner.h:32: `ProcessRunner::ProcessRunner()' previously defined here
processrunner.cpp:20: no `ProcessRunner::ProcessRunner()' member function


Hmm, mach mal im Header folgendes:


#ifndef HEADERNAME_H
#define HEADERNAME_H
...
#endif


Dort wo die Punkte sind, kommt der bisherige Inhalt.



Und hier beisse ich mich auch fest.
connect(m_process,
SIGNAL(receivedStdout(KProcess*, char*, int),
this,
SLOT(slotProcessOutput(KProcess*, char*, int)));


Da fehlt eine schliessende Klammer


SIGNAL(...(...)),
this


Ciao,
_

Hans-Georg Normann
22-01-2003, 21:48
Endlich wieder ein Stück weiter.

Hab da noch Korrekturen gemacht, von denen ich nicht weiß, ob Änderungen Zulässig sind. Der Compiler meckert jedenfalls nicht mehr


ProcessRunner::ProcessRunner(){
}
ProcessRunner::~ProcessRunner(){
}

Müssen diese Einträge in der processrunner.cpp stehen? Ich hab sie dektiviert und der Compiler akzeptiert's.

m_process << "-al";
#habe ich erstezt durch
*m_process << "-al";
Der Compiler akzeptiert jetzt bis auf diesen Eintrag
public signals:
void finished(const QString& output);. Das public signals stört den Herrn Compiler doch ziemlich. Müßte ich in der Doku zu QObject etwas über finished() finden. Ich hab da nichts gesehen.

Hans

anda_skoa
22-01-2003, 22:24
Original geschrieben von Hans-Georg Normann
Endlich wieder ein Stück weiter.

Hab da noch Korrekturen gemacht, von denen ich nicht weiß, ob Änderungen Zulässig sind. Der Compiler meckert jedenfalls nicht mehr


ProcessRunner::ProcessRunner(){
}
ProcessRunner::~ProcessRunner(){
}

Müssen diese Einträge in der processrunner.cpp stehen? Ich hab sie dektiviert und der Compiler akzeptiert's

Braucht man in dem Fall nicht, weil man nichts machen muss.




m_process << "-al";
#habe ich erstezt durch
*m_process << "-al";


Mein Fehler, so passts.



Der Compiler akzeptiert jetzt bis auf diesen Eintrag
public signals:
void finished(const QString& output);. Das public signals stört den Herrn Compiler doch ziemlich.

Auch mein Fehler, das public ist zuviel.

Ciao,
_

Hans-Georg Normann
23-01-2003, 20:29
So langsam robben wir uns ran:rolleyes:
Nachdem wir ja entschieden haben, das im processrunner.cpp kein Konstruktor / Destruktor aufgerufen werden muß (Kompiler meckerte ja Redefinition an) wird das Programm ja jetzt schon ein Stück weiter compiliert, bricht aber dann wie folgt ab:

g++ -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/kde3/include -I/usr/lib/qt3/include \
-I/usr/X11R6/include -DQT_THREAD_SUPPORT -D_REENTRANT -Wnon-virtual-dtor \
-Wno-long-long -Wbad-function-cast -Wundef -Wall -pedantic -W -Wpointer-arith \
-Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE \
-Wcast-align -Wconversion -O2 -O0 -g3 -Wall -fno-exceptions -fno-check-new -c -o \
processrunner.o `test -f 'processrunner.cpp' || echo './'`processrunner.cpp /bin/sh \
../libtool --silent --mode=link --tag=CXX g++ -Wnon-virtual-dtor -Wno-long-long \
-Wbad-function-cast -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes \
-Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align \
-Wconversion -O2 -O0 -g3 -Wall -fno-exceptions -fno-check-new -o norcmd \
-L/usr/X11R6/lib -L/usr/lib/qt3/lib -L/opt/kde3/lib -R /opt/kde3/lib -R /usr/lib/qt3/lib -R \
/usr/X11R6/lib processrunner.o norcmd.o main.o norcmdDlg.o processrunner.moc.o \
norcmd.moc.o -lkdeui -lkdecore -lqt-mt -lpng -lz -lm -lXext -lX11 -lresolv -lSM -lICE \
-lpthread -lresolv
processrunner.moc.o:/usr2/data/hans/Projects/cpp/norcmd/norcmd/processrunner.moc.cpp:34:\
undefined reference to `ProcessRunner::~ProcessRunner [in-charge]()'
processrunner.moc.o:/usr2/data/hans/Projects/cpp/norcmd/norcmd/processrunner.moc.cpp:34:\
undefined reference to `ProcessRunner::~ProcessRunner [in-charge deleting]()'
collect2: ld returned 1 exit status
Ich habe hier die langen Zeilen wegen besserer Lesbarkeit umbrochen und wie in UNIX üblich ein Backslash an das Zeilenende gesetzt.

Eigentlich dachte ich, das wäre ne ganz kleine Sache die ich da anfing, :confused:

Hans

TheDodger
24-01-2003, 00:04
Pack doch deinen Code mal in ein tar.gz Archiv und häng es unten an ... das ganze Schnipselweise auseinanderzunehmen ist ziemlich mühsam und garantiert keine Fehlerfreiheit.
Ich setze QProzess sehr oft ein, und hab da (bis ganz am Anfang) kenerlei Probleme gehabt.

Wenn ich das ganz mal vor mir sehe, sehe ich wahrscheinlich auch den Fehler :)

Hans-Georg Normann
24-01-2003, 12:49
Original geschrieben von TheDodger
... Ich setze QProzess sehr oft ein, und hab da (bis ganz am Anfang) kenerlei Probleme gehabt.....

Das läßt mich ja wieder Hoffnung schöpfen, dass es doch noch was wird;)

Habe den Code als tar File mal in das Attachment gepackt. Ich hoffe das sind alle Files die ihr benötigt.

Hans

p.s. Warum akzeptiert mrunix kein tar.gz von mir (ungültiger Dateityp)?

TheDodger
24-01-2003, 15:26
ein Makefile wäre auch nicht schlecht gewesen! :)
qmake wird's schon richten, denk ich ...

TheDodger
24-01-2003, 15:40
After 2 minutes ...

Wenn du im Header 'ProcessRunner(); : m_process(0) {};' schreibst, brauchst du wirklich keine neudefinition in der .cpp Datei ...
Einen Konstruktor / Destruktor brauchst du aber trotzdem.

Also, dein Programm läuft ... :D
Aber deine KLed bleibt grün ...

TheDodger
24-01-2003, 16:05
grrrr beim editieren kann ich keine dateien anhängen ...

Also, das Programm läuft ... :D
Ich hab dir auch gleich noch deine Process Klasse eingebunden :)

Aber deine KLed bleibt grün ... darum willst du dich bestimmt auch selber kümmern, nich? ;)

(BTW. Ändere den Dateityp auf .tar.gz!)