Qt学习之路(58): 进程间交互

简介:

所谓 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 程序等待这个进程结束后再继续执行的函数。



本文转自 FinderCheng 51CTO博客,原文链接:

http://blog.51cto.com/devbean/305116
相关文章
|
26天前
|
存储 缓存 NoSQL
Redis系列学习文章分享---第十三篇(Redis多级缓存--JVM进程缓存+Lua语法)
Redis系列学习文章分享---第十三篇(Redis多级缓存--JVM进程缓存+Lua语法)
42 1
|
27天前
|
编解码 算法 程序员
老程序员分享:OpenGL学习进程(10)第七课:四边形绘制与动画基础
老程序员分享:OpenGL学习进程(10)第七课:四边形绘制与动画基础
|
1月前
|
存储 数据安全/隐私保护 Windows
逆向学习Windows篇:进程句柄操作详解
逆向学习Windows篇:进程句柄操作详解
14 0
|
2月前
|
Java 调度
【JAVA学习之路 | 提高篇】进程与线程(Thread)
【JAVA学习之路 | 提高篇】进程与线程(Thread)
|
2月前
|
存储 缓存 Linux
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(三)--实时与非实时数据交互
本文介绍了Xenomai中的XDDP(Xenomai Distributed Data Protocol)通信机制,XDDP用于实时和非实时进程之间的数据交换。XDDP在Xenomai内核中涉及的数据结构和管理方式,以及创建XDDP通道后的实时端和非实时端连接过程。
134 0
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(三)--实时与非实时数据交互
|
2月前
|
消息中间件 Unix Linux
Linux的学习之路:17、进程间通信(1)
Linux的学习之路:17、进程间通信(1)
39 1
|
2月前
|
自然语言处理 Java Linux
【Linux】开始学习进程替换吧!
通过学习进程替换,我们可以体会到多语言混搭的快乐,可以从C语言直接蹦到python ,也可以从c++里运行java代码。是不是很厉害!这是通过调度多个进程的效果,联系我们之前学习的进程,进程控制等概念。我们可以想要运行其他代码可以通过创建子进程来实现,但是这样也肯定是同一种语言,如果想要运行其他语言,那是不是有种方法可以调度一个进程来当做子进程呢??? 我们开始今天的学习吧!
19 0
|
2月前
|
人工智能 Linux Shell
Linux的学习之路:13、进程替代
Linux的学习之路:13、进程替代
30 0
|
2月前
|
存储 Linux 调度
Linux的学习之路:12、地址空间(续)与进程的创建、终止和等待
Linux的学习之路:12、地址空间(续)与进程的创建、终止和等待
28 0
|
2月前
|
Linux Shell
Linux的学习之路:10、进程(2)
Linux的学习之路:10、进程(2)
29 0

推荐镜像

更多