source: tests/process/process-async/process-async.cpp@ 903

Last change on this file since 903 was 903, checked in by Dmitry A. Kuminov, 14 years ago

tests/process: Renamed the process part to process-async.

File size: 11.0 KB
Line 
1#include <QtCore>
2
3//#include <QtGui>
4#include <QApplication>
5#include <QWidget>
6#include <QTextEdit>
7#include <QLineEdit>
8#include <QLabel>
9#include <QTabWidget>
10#include <QLayout>
11
12#include <QDebug>
13
14#define STR(expr) #expr
15#define DBG(expr) STR(expr) << "=" << (expr)
16
17class MyWidget : public QWidget
18{
19 Q_OBJECT
20
21public:
22
23 MyWidget(QWidget *aParent)
24 : QWidget(aParent), mOtherProcess(0), mRedirectedToOtherProcess(false)
25 {
26 // children
27
28 mProcess = new QProcess(this);
29
30 mEditor = new QTextEdit();
31 mEditor->setReadOnly(true);
32
33 mLineEdit = new QLineEdit();
34 mStatusLabel = new QLabel();
35
36 // connections
37
38 connect(mProcess, SIGNAL(stateChanged(QProcess::ProcessState)),
39 this, SLOT(process_stateChanged(QProcess::ProcessState)));
40 connect(mProcess, SIGNAL(error(QProcess::ProcessError)),
41 this, SLOT(process_error(QProcess::ProcessError)));
42 connect(mProcess, SIGNAL(started()),
43 this, SLOT(process_started()));
44 connect(mProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
45 this, SLOT(process_finished(int, QProcess::ExitStatus)));
46 connect(mProcess, SIGNAL(readyReadStandardOutput()),
47 this, SLOT(process_readyReadStandardOutput()));
48 connect(mProcess, SIGNAL(readyReadStandardError()),
49 this, SLOT(process_readyReadStandardError()));
50
51 connect(mLineEdit, SIGNAL(returnPressed()),
52 this, SLOT(lineEdit_returnPressed()));
53
54 // layout
55
56 QVBoxLayout *l1 = new QVBoxLayout();
57 l1->addWidget(mEditor);
58 l1->addWidget(mLineEdit);
59 l1->addWidget(mStatusLabel);
60
61 QHBoxLayout *mainLayout = new QHBoxLayout();
62 mainLayout->addLayout(l1);
63
64 setLayout(mainLayout);
65
66 mLineEdit->setFocus();
67
68 // initial values
69
70 mLineEdit->setText("D:\\Coding\\qt\\smplayer_test\\mplayer.ex");
71
72 process_stateChanged(mProcess->state());
73
74 // other
75 }
76
77 QProcess *process() const { return mProcess; }
78 void setOtherProcess(QProcess *aOtherProcess) { mOtherProcess = aOtherProcess; }
79
80private slots:
81
82 void lineEdit_returnPressed()
83 {
84 QString text = mLineEdit->text();
85 if (text.isEmpty())
86 return;
87
88 mLineEdit->clear();
89
90 text = text.trimmed();
91
92 QString cmd;
93 if (text.startsWith('>'))
94 {
95 int ws = text.indexOf(' ');
96 if (ws < 0)
97 ws = text.length();
98 cmd = text.mid(1, ws - 1);
99
100 text = text.mid(ws);
101 text = text.trimmed();
102 }
103
104 // @todo support for quoted strings
105 QStringList words = text.split(' ');
106
107 if (cmd.isNull() && mProcess->state() == QProcess::NotRunning)
108 cmd = "s";
109
110 if (cmd.isNull())
111 {
112 Q_ASSERT(mProcess->state() != QProcess::NotRunning);
113
114 /* send the line to standard input */
115 QByteArray data = (text + "\n").toLocal8Bit();
116 mProcess->write(data);
117 }
118 else if (cmd == "s" || cmd == "ss" || cmd == "scd" || cmd == "sscd")
119 {
120 /* start process (..cd changes to its directory) */
121
122 if (words.count() < 1)
123 {
124 mEditor->append(tr("> ERROR: '%1' requires one argument").arg(cmd));
125 return;
126 }
127 if (mProcess->state() != QProcess::NotRunning)
128 {
129 mEditor->append(tr("> ERROR: Process is already running"));
130 return;
131 }
132
133 QString workDir;
134 if (cmd.endsWith("cd"))
135 {
136 QDir dir = QDir(QFileInfo(words[0]).path());
137 workDir = dir.absolutePath();
138 mProcess->setWorkingDirectory(workDir);
139 }
140 else
141 {
142 workDir = QDir::currentPath();
143 mProcess->setWorkingDirectory(QString());
144 }
145 mEditor->append(tr("> Working directory: '%1'").arg(workDir));
146
147 mEditor->append(tr("> Starting: '%1'").arg(text));
148 mProcess->start(text);
149 }
150 else if (cmd == "rso" || cmd == "rse")
151 {
152 /* redirect stdout & stderr */
153
154 if (mProcess->state() != QProcess::NotRunning)
155 {
156 mEditor->append(tr("> ERROR: Process is already running"));
157 return;
158 }
159
160 bool output = cmd == "rso";
161 output ? mProcess->setStandardOutputFile(text)
162 : mProcess->setStandardErrorFile(text);
163
164 if (!text.isEmpty())
165 mEditor->append(tr("> Redirected standard %1 stream to: '%2'")
166 .arg(output ? "output" : "error").arg(text));
167 else
168 mEditor->append(tr("> Canceled redirection of standard %1")
169 .arg(output ? "output" : "error"));
170 }
171 else if (cmd == "term")
172 {
173 /* terminate */
174
175 if (mProcess->state() == QProcess::NotRunning)
176 {
177 mEditor->append(tr("> ERROR: No process is running"));
178 return;
179 }
180
181 mEditor->append(tr("> Sent terminate process request"));
182 mProcess->terminate();
183 }
184 else if (cmd == "kill")
185 {
186 /* kill */
187
188 if (mProcess->state() == QProcess::NotRunning)
189 {
190 mEditor->append(tr("> ERROR: No process is running"));
191 return;
192 }
193
194 mEditor->append(tr("> Sent kill process request"));
195 mProcess->kill();
196 }
197 else if (cmd == "rtp")
198 {
199 /* redirect stdout to stdin of the other process */
200
201 if (mProcess->state() != QProcess::NotRunning)
202 {
203 mEditor->append(tr("> ERROR: Process is already running"));
204 return;
205 }
206
207 if (!mRedirectedToOtherProcess)
208 {
209 mRedirectedToOtherProcess = true;
210 mProcess->setStandardOutputProcess(mOtherProcess);
211 mEditor->append(tr("> Redirected standard output to standard "
212 "input of another process"));
213 }
214 else
215 {
216 mRedirectedToOtherProcess = false;
217 mProcess->setStandardErrorFile(QString::null);
218 mEditor->append(tr("> Canceled redirection of standard output"));
219 }
220 }
221 else if (cmd == "d" || cmd == "dcd")
222 {
223 QString workDir;
224 if (cmd.endsWith("cd"))
225 {
226 QDir dir = QDir(QFileInfo(words[0]).path());
227 workDir = dir.absolutePath();
228 }
229 else
230 {
231 workDir = QDir::currentPath();
232 }
233 mEditor->append(tr("> Working directory: '%1'").arg(workDir));
234
235 mEditor->append(tr("> Detaching: '%1'").arg(text));
236 QStringList args = words;
237 QString prg = args.takeFirst();
238 qint64 pid;
239 if (QProcess::startDetached(prg, args, workDir, &pid))
240 mEditor->append(tr("> Detached successfully (pid '%1')").arg(pid));
241 else
242 mEditor->append(tr("> Detach failed"));
243 }
244 else
245 {
246 mEditor->append(tr("> ERROR: '%1' command is unknown").arg(cmd));
247 return;
248 }
249 }
250
251 void process_stateChanged(QProcess::ProcessState aState)
252 {
253 QString state;
254 switch (aState)
255 {
256 case QProcess::NotRunning: state = tr("NotRunning"); break;
257 case QProcess::Starting: state = tr("Starting"); break;
258 case QProcess::Running: state = tr("Running"); break;
259 }
260 mStatusLabel->setText(tr("%1 (PID: %2)").arg(state).arg((ulong)mProcess->pid()));
261 }
262
263 void process_error(QProcess::ProcessError aError)
264 {
265 QString error;
266 switch (aError)
267 {
268 case QProcess::FailedToStart: error = tr("FailedToStart"); break;
269 case QProcess::Crashed: error = tr("Crashed"); break;
270 case QProcess::Timedout: error = tr("Timedout"); break;
271 case QProcess::WriteError: error = tr("WriteError"); break;
272 case QProcess::ReadError: error = tr("ReadError"); break;
273 case QProcess::UnknownError: error = tr("UnknownError"); break;
274 }
275 mEditor->append(tr("> ERROR: %1: %2").arg(error).arg(mProcess->errorString()));
276 }
277
278 void process_started()
279 {
280 mEditor->append(tr("> Started: PID is %1").arg((ulong)mProcess->pid()));
281 }
282
283 void process_finished(int aExitCode, QProcess::ExitStatus aExitStatus)
284 {
285 QString exitStatus;
286 switch (aExitStatus)
287 {
288 case QProcess::NormalExit: exitStatus = tr("NormalExit"); break;
289 case QProcess::CrashExit: exitStatus = tr("CrashExit"); break;
290 }
291 mEditor->append(tr("> Finished: %1 with code %2").arg(exitStatus).arg(aExitCode));
292 }
293
294 void process_readyReadStandardOutput()
295 {
296 QByteArray data = mProcess->readAllStandardOutput();
297 mEditor->append(QString::fromLocal8Bit(data));
298 }
299
300 void process_readyReadStandardError()
301 {
302 QByteArray data = mProcess->readAllStandardError();
303 mEditor->append(QString::fromLocal8Bit(data));
304 }
305
306private:
307
308 QProcess *mProcess;
309 QProcess *mOtherProcess;
310 bool mRedirectedToOtherProcess;
311
312 QTextEdit *mEditor;
313 QLineEdit *mLineEdit;
314 QLabel *mStatusLabel;
315};
316
317////////////////////////////////////////////////////////////////////////////////
318
319class MyDialog : public QWidget
320{
321 Q_OBJECT
322
323public:
324
325 MyDialog() : QWidget(0, Qt::Window)
326 {
327 // children
328
329 QTabWidget *tabs = new QTabWidget();
330
331 mWidget1 = new MyWidget(tabs);
332 mWidget2 = new MyWidget(tabs);
333
334 mWidget1->setOtherProcess(mWidget2->process());
335 mWidget2->setOtherProcess(mWidget1->process());
336
337 tabs->addTab(mWidget1, QLatin1String("Process 1"));
338 tabs->addTab(mWidget2, QLatin1String("Process 2"));
339
340 // connections
341
342 // layout
343
344 QHBoxLayout *mainLayout = new QHBoxLayout();
345 mainLayout->addWidget(tabs);
346
347 setLayout(mainLayout);
348
349 // initial values
350
351 tabs->currentWidget()->setFocus();
352
353 // other
354 }
355
356private:
357
358 MyWidget *mWidget1;
359 MyWidget *mWidget2;
360};
361
362////////////////////////////////////////////////////////////////////////////////
363
364int main(int argc, char *argv[])
365{
366#if 1
367
368 QApplication app(argc, argv);
369
370 MyDialog dialog;
371 dialog.resize(800, 400);
372 dialog.show();
373
374 return app.exec();
375
376#else
377
378 qDebug() << "Starting...";
379
380 QProcess proc;
381#if defined(Q_OS_OS2)
382 //proc.start("cmd.exe /c dir >bbb");
383 //proc.start("cmd /c start /n newview.exe");
384 proc.start("test");
385#elif defined(Q_OS_WIN)
386 proc.start("notepad.exe");
387#endif
388
389 qDebug() << "Waiting for finished...";
390 proc.waitForFinished();
391
392 qDebug() << "DONE";
393
394#endif
395}
396
397#include "process-async.moc"
398
Note: See TracBrowser for help on using the repository browser.