void ProcessTree::run(){ MyShell *test = new MyShell; //QTreeWidgetItemIterator iterator(tree, QTreeWidgetItemIterator::All); (*iterator)->setText(1, "YO!"); //проверка sleep(3); test->start(*iterator); //не успевает процесс выполниться, только на половину run(); //Вот так поток циклится}
delete test;
C++ (Qt)#ifndef DIALOG_H#define DIALOG_H #include <QDialog>#include <QThread> namespace Ui {class Dialog;} class Dialog : public QDialog{ Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); private: Ui::Dialog *ui; private slots: void pinged(const QString &ip, bool success);}; class Pinger: public QThread{ Q_OBJECT public: Pinger(QObject *parent = 0): QThread(parent) { } void ping(const QStringList &ips, const unsigned int timeout); private: QStringList addrs; unsigned int timeout; protected: void run(); signals: void pinged(const QString &ip, bool success);}; #endif // DIALOG_H
C++ (Qt)#include "dialog.h"#include "ui_dialog.h"#include <QDebug> #ifdef Q_OS_WIN# include <WinSock2.h># include <IPHlpApi.h># include <IcmpAPI.h>#endif #ifdef _MSC_VER# pragma comment(lib, "ws2_32.lib")# pragma comment(lib, "iphlpapi.lib")#endif Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog){ ui->setupUi(this); Pinger *pinger = new Pinger; connect(pinger, SIGNAL(finished()), pinger, SLOT(deleteLater())); connect(pinger, SIGNAL(pinged(QString,bool)), this, SLOT(pinged(QString,bool))); pinger->ping(QStringList() << "192.168.0.1" << "192.168.0.5" << "87.118.94.143", 1000);} Dialog::~Dialog(){ delete ui;} void Dialog::pinged(const QString &ip, bool success){ qDebug() << ip << success;} void Pinger::ping(const QStringList &ips, const unsigned int timeout){ if (!isRunning()) { this->addrs = ips; this->timeout = timeout; start(); }} void Pinger::run(){#ifdef Q_OS_WIN HANDLE hIcmpFile = IcmpCreateFile(); if (hIcmpFile != INVALID_HANDLE_VALUE) { char RequestData[] = "ping"; DWORD ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(RequestData); char *ReplyBuffer = new char[ReplySize]; for (int i = 0, count = addrs.count(); i < count; i++) { bool success = false; const QString ip = addrs.at(i); const int addr = inet_addr(ip.toAscii().data()); if (addr != INADDR_NONE) { if (IcmpSendEcho(hIcmpFile, addr, RequestData, sizeof(RequestData), 0, ReplyBuffer, ReplySize, timeout) != 0) { PICMP_ECHO_REPLY icmpReply = (PICMP_ECHO_REPLY)ReplyBuffer; success = icmpReply->Status == IP_SUCCESS; } } emit pinged(ip, success); } delete []ReplyBuffer; IcmpCloseHandle(hIcmpFile); exit(0); }#endif exit(-1);}
C++ (Qt)run(){exec() // запускаем цикл обработки событий, так называемый QEventLoop, то есть класс может принимать сигналы из "внешнего мира" }
#include "processtree.h"#include <QTreeWidget>#include <QTreeWidgetItemIterator>#include <QProcess>void ProcessTree::run(){ iterator = new QTreeWidgetItemIterator(tree, QTreeWidgetItemIterator::All); process = new QProcess; connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(takeOutput())); connect(this, SIGNAL(pingResult(bool)), this, SLOT(finalize(bool))); connect(this, SIGNAL(requestNext()), this, SLOT(processNext())); process->start("cmd /C ping "+(**iterator)->text(0)); exec();}void ProcessTree::setTree(QTreeWidget *item){ tree = item;}void ProcessTree::takeOutput(){ QString *output = new QString(process->readAllStandardOutput()); process->kill(); if(output->indexOf("TTL") > 0) emit pingResult(true); else emit pingResult(false); delete output;}void ProcessTree::finalize(bool result){ /* Заморочки с базой и.т.п. будут здесь */ if(result) (**iterator)->setText(1, "OK!"); else (**iterator)->setText(1, "FAIL :("); emit requestNext();}void ProcessTree::processNext(){ if(**iterator){ ++(*iterator); process->start("cmd /C ping "+(**iterator)->text(0)); } else exit(0);}
C++ (Qt)#include "processtree.h"#include <QProcess> ProcessTree::ProcessTree( void ) : mProcess(0){} ProcessTree::~ProcessTree( void ) { delete mProcess;} // void ProcessTree::run() // не нужно перекрывать // пришел сигнал от запущенного процессаvoid ProcessTree::SlotReadProcess( void ){ assert(mProcess); QString output = mProcess->readAllStandardOutput()); delete mProcess; mProcess = 0; emit SignalReply(reply_Output, output); // ответили боссу} // пришла команда (от кто создал экземпляр ProcessTree) void ProcessTree::SlotCommand( int cmd, QString param ){ switch (cmd) { case cmd_GetStatus: if (mProcess) emit SignalReply(reply_Busy, "Waiting for process"); else emit SignalReply(reply_Ready, "Ready"); break; case cmd_RunProcess: if (mProcess) emit SignalReply(reply_Busy, "Waiting for process"); else { mProcess = new QProcess(); connect(mProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(slotReadProcess())); mProcess->start("cmd /C ping " + param); emit SignalReply(reply_Running, "Running"); } default: emit SignalReply(reply_Error, "Unknown command"); }}