程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Qt學習之路(58): 進程間交互

Qt學習之路(58): 進程間交互

編輯:關於C語言

所謂 IO 其實不過是與其他設備之間的數據交互。在 Linux 上這個概念或許會更加清楚一些。Linux 把所有設備都看作是一種文件,因此所有的 IO 都歸結到對文件的數據交互。同樣,與其他進程之間也存在著數據交互,這就是進程間交互。

為什麼需要進程間交互呢?Qt 雖然是一個很龐大的庫,但是也不能面面俱到。每個需求都提供一種解決方案是不現實的。比如操作系統提供了查看當前文件夾下所有文件的命令(Windows 下是 dir, Linux 下是 ls),那麼 Qt 就可以通過調用這個命令獲取其中的信息。當然這不是一個很恰當的例子,因為 Qt 同樣提供了相同的操作。不過,如果你使用版本控制系統,比如 SVN,然後你希望通過 SVN 的版本號生成自己系統的 build number,那麼就不得不調用 svn 命令獲取當前倉庫的版本號。這些操作都涉及到進程間交互。

Qt 使用 QProcess 類完成進程間交互。我們從例子開始看起。由於比較簡單,所以沒有把 main() 函數貼上來,大家順手寫下就好的啦!

mainwindow.h

  1. #ifndef MAINWINDOW_H  
  2. #define MAINWINDOW_H  
  3.  
  4. #include <QtGui>  
  5.  
  6. class MainWindow : public QMainWindow  
  7. {  
  8.     Q_OBJECT  
  9.  
  10. public:  
  11.     MainWindow(QWidget *parent = 0);  
  12.     ~MainWindow();  
  13.  
  14. private slots:  
  15.     void openProcess();  
  16.  
  17. private:  
  18.     QProcess *p;  
  19. };  
  20.  
  21. #endif // MAINWINDOW_H 

mainwindow.cpp

  1. #include "mainwindow.h"  
  2.  
  3. MainWindow::MainWindow(QWidget *parent)  
  4.     : QMainWindow(parent)  
  5. {  
  6.     p = new QProcess(this);  
  7.     QPushButton *bt = new QPushButton("execute notepad", this);  
  8.     connect(bt, SIGNAL(clicked()), this, SLOT(openProcess()));  
  9. }  
  10.  
  11. MainWindow::~MainWindow()  
  12. {  
  13.  
  14. }  
  15.  
  16. void MainWindow::openProcess()  
  17. {  
  18.     p->start("notepad.exe");  

這個窗口很簡單,只有一個按鈕,當你點擊按鈕之後,程序會調用 Windows 的記事本。這裡我們使用的是

  1. p->start("notepad.exe"); 

語句。QProcess::start() 接受兩個參數,第一個是要執行的命令或者程序,這裡就是 notepad.exe;第二個是一個 QStringList 類型的數據,也就是需要傳遞給這個程序的運行參數。注意,這個程序是需要能夠由系統找到的,一般是完全路徑。但是這裡為什麼只有 notepad.exe 呢?因為這個程序實際是放置在 Windows 系統文件夾下,是已經添加到了系統路徑之中,因此不需要再添加本身的路徑。

下面我們再看一個更復雜的例子,調用一個系統命令,這裡我使用的是 Windows,因此需要調用 dir;如果你是在 Linux 進行編譯,就需要改成 ls 了。

mainwindow.h

  1. #ifndef MAINWINDOW_H  
  2. #define MAINWINDOW_H  
  3.  
  4. #include <QtGui>  
  5.  
  6. class MainWindow : public QMainWindow  
  7. {  
  8.     Q_OBJECT  
  9.  
  10. public:  
  11.     MainWindow(QWidget *parent = 0);  
  12.     ~MainWindow();  
  13.  
  14. private slots:  
  15.     void openProcess();  
  16.     void readResult(int exitCode);  
  17.  
  18. private:  
  19.     QProcess *p;  
  20. };  
  21.  
  22. #endif // MAINWINDOW_H 

mainwindow.cpp

  1. #include "mainwindow.h"  
  2.  
  3. MainWindow::MainWindow(QWidget *parent)  
  4.     : QMainWindow(parent)  
  5. {  
  6.     p = new QProcess(this);  
  7.     QPushButton *bt = new QPushButton("execute notepad", this);  
  8.     connect(bt, SIGNAL(clicked()), this, SLOT(openProcess()));  
  9. }  
  10.  
  11. MainWindow::~MainWindow()  
  12. {  
  13.  
  14. }  
  15.  
  16. void MainWindow::openProcess()  
  17. {  
  18.     p->start("cmd.exe", QStringList() << "/c" << "dir");  
  19.     connect(p, SIGNAL(finished(int)), this, SLOT(readResult(int)));  
  20. }  
  21.  
  22. void MainWindow::readResult(int exitCode)  
  23. {  
  24.     if(exitCode == 0) {  
  25.         QTextCodec* gbkCodec = QTextCodec::codecForName("GBK");  
  26.         QString result = gbkCodec->toUnicode(p->readAll());  
  27.         QMessageBox::information(this, "dir", result);  
  28.     }  
  29. }  

我們僅增加了一個 slot 函數。在按鈕點擊的 slot 中,我們通過 QProcess::start() 函數運行了指令

cmd.exe /c dir

這裡是說,打開系統的 cmd 程序,然後運行 dir 指令。如果有對參數 /c 有疑問,只好去查閱 Windows 的相關手冊了哦,這已經不是 Qt 的問題了。然後我們 process 的 finished() 信號連接到新增加的 slot 上面。這個 signal 有一個參數 int。我們知道,對於 C/C++ 程序而言,main() 函數總是返回一個 int,也就是退出代碼,用於指示程序是否正常退出。這裡的 int 參數就是這個退出代碼。在 slot 中,我們檢查退出代碼是否是0,一般而言,如果退出代碼為0,說明是正常退出。然後把結果顯示在 QMessageBox 中。怎麼做到的呢?原來,QProcess::readAll() 函數可以讀出程序輸出內容。我們使用這個函數將所有的輸出獲取之後,由於它的返回結果是 QByteArray 類型,所以再轉換成 QString 顯示出來。另外注意一點,中文本 Windows 使用的是 GBK 編碼,而 Qt 使用的是 Unicode 編碼,因此需要做一下轉換,否則是會出現亂碼的,大家可以嘗試一下。

好了,進程間交互就說這麼說,通過查看文檔你可以找到如何用 QProcess 實現進程過程的監聽,或者是令Qt 程序等待這個進程結束後再繼續執行的函數。

本文出自 “豆子空間” 博客,請務必保留此出處http://devbean.blog.51cto.com/448512/305116

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved