Wie zu verwenden einen Prozess (QProcess) in einen neuen thread (QThread)?
Ich habe den folgenden code:
void Processmethod()
{
QDialog *ProcessMessage = new QDialog;
Ui::DialogProcessMessage Dialog;
Dialog.setupUi(ProcessMessage);
ProcessMessage->setModal(true);
ProcessMessage->setAttribute(Qt::WA_DeleteOnClose);
ProcessMessage->show();
qApp->processEvents();
processmethodONE();
processmethodTWO();
processmethodTHREE();
}
void processmethodONE()
{
QString ProcessCommand = "w8 " + blablubli";
Prozess.setWorkingDirectory(Path); //QProcess "Prozess" is globaly defined
Prozess.setStandardOutputFile(Path); //in my class
QThread* thread = new QThread;
Prozess.moveToThread(thread);
Prozess.start(ProcessCommand);
while(!Prozess.waitForFinished(2000))
{
std::cerr << "Process running " << std::endl;
}
QProcess::ExitStatus Status = Prozess.exitStatus();
if (Status == 0)
{
std::cout << "File created!" << std::endl;
}
}
In diesem source-code, den ich versuchen, öffnen Sie ein popup-dialog, bevor einige Prozesse gestartet werden. problem ist, dass das Dialogfeld ist nicht anklickbar, sondern auf den dialog, ich möchte eine Schaltfläche erstellen, die zum Abbruch der Laufenden Methode. Wie Sie sehen können ich habe versucht, mit QThread den Vorgang ausführen(es) in einem anderen thread, aber noch kann ich nicht auf den dialog. Außerdem, wenn ich öffne meine Anwendung (GUI) mit der "application/x-executable"-file die Dialoge Inhalte fehlen, die bei der Aktivierung der oben gezeigten Methode. Wie kann ich diese Probleme beheben? Wo bin ich falsch? Grüße
- Ich habe ein paar Fragen... 1) Wie rufst du
Processmethod()
? 2) Warum glauben Sie, dass müssen Sie erstellen eine QThread und bewegen Sie den QProcess hinein? Und auch, warum sind Sie dann nicht den Beginn des neuen QThread? 3) verwenden Sie diese Globale QProcess für alle IhreprocessmethodX()
? - es passt nicht mit der Frage, aber ich würde vorschlagen, Sie schreiben von Variablen-Namen in lowerCamelCase. Es ist sehr schnell lesbar. Aber ich Stimme mit jdi, benötigen Sie weitere Informationen zu beantworten.
- Normalerweise gibt es keine Notwendigkeit zum ausführen von QProcess in einem thread, wie die API ist nicht blockiert, es sei denn, Sie verwenden die waitForStarted/Fertige Methoden.
- Ich Wette, dass sobald die OP gibt uns die Antworten auf meine Fragen, wird es klar sein, dass es extra cruft hier (man wird richtig in nicht zu brauchen QProcess in einem thread)
- 1)ich nenne Processmethod (), wenn eine Taste geklickt wird. 2)ich dachte, um die Ausführung des Prozesses in einem anderen thread würde verlassen Sie den dialog anklickbar/zur Verfügung. Du hast Recht ich habe nicht angefangen der QThread - mein Fehler - muss ich haben, um eine Verbindung-Methode und schließen Sie den thread auf eine Methode in der ich definieren Sie den Prozess? 3.Ich habe einen QProcess für jeden Prozess - wäre es besser, genau das gleiche wieder? Ich bin sorry für meine Fehler, aber ich hatte Probleme mit dem Verständnis der QThread Methoden wahrscheinlich weil mein Englisch ist nicht gut genug. @Frank: Wie Sie sehen können, ich benutze jetzt waitForFinished - bearbeitet meine Frage.
- Ja, Sie sollten mit separaten QProcess Instanzen, so ist das in Ordnung. QThread würde es erlauben, den dialog am laufen zu halten, und so würde QProcess, aber nur, wenn Sie nicht gehen, und blockieren der Haupt-thread wartet für Sie zu beenden. Wählen Sie eine oder das andere: QThread, oder QProcess, und Ihre Signale zu sagen, Ihre Haupt-thread, wenn Sie fertig sind. Siehe die Antworten, die wir gegeben haben
- Das problem ist, dass ich will, dass die Haupt-thread (GUI-Hauptfenster zu erfrieren in der Erwägung, dass die Prozesse ausgeführt werden, nur die popup-Dialogfeld angeklickt werden. Also, weiß jemand, wie das zu erreichen ist?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier bewegten sich die QProcess zu einem anderen thread. Aber dann Sie rufen start() auf. Das ist schon nicht thread-safe.
Diese Blöcke und macht einen thread nutzlos. Auch, es ist nicht thread-safe.
Stattdessen sollten Sie nicht verwenden threads, aber:
Ich würde dir auch raten gegen die Wiederverwendung von QProcess-Objekte und nur eine neue erstellen, einen für jeden Schritt.
Während ich noch nicht ganz verstehen, Ihre vor kurzem aktualisierten code-Beispiel, ich denke, dies könnte dein Problem:
Überall dort, wo Sie wirklich fordern, diese in Ihrem ursprünglichen code blockiert beim warten auf Prozess beenden.
Verwendung einer Marke neue QProcess-Instanz für jeden ein, und schließen Sie Ihre fertig() Signale mit einem SLOT, die aufgerufen wird, wenn Sie fertig sind. Nicht manuell poll Ihnen und block. Dies ermöglicht es Ihnen, vollständig loszuwerden QThreads insgesamt.
one QProcess Prozess for processmethodONE();
,one QProcess Prozess2 for processmethodTWO();
... DiewaitForFinished()
Methode, die ich brauche, weil die Prozesse, die einige Zeit brauchen, und der Vorherige Prozess muss immer abgeschlossen sein, bevor die nächste beginnt.finished()
signal von der einen in diestart()
slot des nächsten, und so weiter.connect(Prozess, SIGNAL(finished()),processmethodTWO(),(SLOT(start())));
, aber ich bekomme die Fehlermeldung "invalid use of void expression". -> wahrscheinlich eine noob-fail :).SLOT(Procezz2.start())
nichtprocessmethodTWO()
. Was Sie tun, ist zu versuchen, es zu nennen. Um ehrlich zu sein, ich bin auch nicht sicher, ob diese syntax richtig ist. Im python-guyconnect(Prozess, SIGNAL(finished()), this,(SLOT(processmethodTWO.start())));
, aber jetzt bekomme ich die FehlermeldungError: no matching function for call to 'GUI :: connect (qprocess &, const char *, const GUI *, const char *) "
undCandidates are: / usr/include/qt4/QtCore/qobject.h: 198:17: note: static bool QObject :: connect (const QObject *, const char *, const QObject *, const char *, Qt :: Connection Type)............
connect(Prozess, SIGNAL(finished()), Prozess2, SLOT(start()))