使用类 QProcess,允许将一个进程堪称一个顺序IO设备。
在Qt中,QProcess类是用于启动外部进程的类。它可以启动任何可执行文件,包括命令行工具和图形用户界面(GUI)应用程序。
启动一个线程分4步
1、在 窗口 类中添加一个私有成员类 QProcess myProcess;
#include <QProcess>...namespace Ui {class c;}class c : public QDialog{Q_OBJECTpublic:explicit c(QWidget *parent = nullptr);~c();QProcess myProcess;private:Ui::c *ui;};2、在 ui 中添加一个 button 按钮,然后添加信号槽。
3、信号槽中增加启动进程
void c::on_pushButton_clicked(){this->myProcess.start("xfce4-appfinder");// You can optionally wait for the program to finish by calling waitForFinished() // process->waitForFinished(); } 1.2 QProcess 还可以对一些信号进行关联例如将 一个进程的信号和主页面进程的槽关联,实现进程信息显示到主进程。
1、在 主进程中添加私有槽申明
private slots:void showResult();void showState(QProcess::ProcessState);void showError();void showFinished(int,QProcess::ExitStatus);在C++中,private slots: 和 private: 是用于定义类成员访问权限的关键字,但它们的作用略有不同。 private: 关键字用于将成员声明为私有访问权限,这意味着这些成员只能在类的内部访问,包括类的构造函数、方法等。在类的外部,这些成员是不可见的,即使用户试图访问它们也会导致编译错误。 而 private slots: 则是一种特殊的私有成员,用于在Qt框架中实现信号与槽机制。在这里,slots 是指明一个成员函数是一个Qt槽,它可以在类的外部通过信号调用。虽然这些槽函数是私有的,但它们可以通过信号从类的外部调用。 因此,将 private slots: 替换为 private: 将导致无法从外部调用槽函数,从而无法实现信号与槽机制。所以,这两个关键字是不能互换的。
2、构造函数中增加槽和信号的关联
c::c(QWidget *parent) :QDialog(parent),ui(new Ui::c){ui->setupUi(this);//sign combine with slotconnect(&myProcess,&QProcess::readyRead,this,&c::showResult);connect(&myProcess,&QProcess::stateChanged,this,&c::showState);connect(&myProcess,&QProcess::errorOccurred,this,&c::showError);connect(&myProcess,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(showFinished(int,QProcess::ExitStatus)));3、然后在 单击按钮的的槽中启动程序的代码
void c::on_pushButton_3_clicked(){this->myProcess.start("gzip",QStringList()<<"-c");// wating to Startif (!myProcess.waitForStarted()){return;}// processthis->myProcess.write("qt",100);myProcess.closeWriteChannel();// wating ro finishif(!myProcess.waitForFinished()){return;}QByteArray result = myProcess.readAll();qDebug()<<"showresult2"<< result;}完成其他槽showResult()、showState()、showError()、showFinished()的代码
void c::showResult(){debug::log("\n\n" \" This is a Empty project. \n" \" print some vals:\n" \" int = {0}\n" ,std::string{"myProcess.readAll()"});QTextCodec *codec = QTextCodec::codecForLocale();qDebug()<<"showresult"<< codec->toUnicode(myProcess.readAll());}void c::showState(QProcess::ProcessState state){qDebug()<<"showState";if(state == QProcess::NotRunning){qDebug()<<"NotRunning";}else if (state == QProcess::Starting){qDebug()<<"Starting";}else{qDebug()<<"Runing";}}void c::showError(){qDebug()<<"showError";}void c::showFinished(int,QProcess::ExitStatus exitStatus){qDebug()<<"showFinished";}实现了进程间的信号和槽的“互动”。
2 进程间通信1、使用 TCP/IP 2、共享内存 3、 D-BUS 4、QProcess 5、会话管理
2.1 使用共享内存实现进程通信1、使用QShareMemory 类,为其指定一个 key,拥有这个 key 就可以使用这个内存。 2、在 共享内存中加入数据loadFromFile();:
进程和共享内存分离;申请一个 QBuffer,将图像数据导入QBuffer QString fileName = QFileDialog::getOpenFileName(0,QString(),QString(),"*.jpg");QImage image;QBuffer buffer;buffer.open(QBuffer::ReadWrite);QDataStream out(&buffer);out << image; 创建共享内存。使用create函数创建指定大小的共享内存段,单位是字节,该函数会自动将共享内存段连接到本进程。 int size =buffer.size();sharedMemory.create(size);// 如果对其具有管理权限,每次都可创建,会删除旧的数据。 对内存进行加锁。然后使用memcpy 进行数据拷贝。完成后解锁。数据加载到内存完成。 sharedMemory.lock();char *to = (char *)sharedMemory.data();const char * from = buffer.data().data();memcpy(to,from,qMin(sharedMemory.size(),size));sharedMemory.unlock();// sharedMemory.detach();如果现在断开了这个连接,因为没有其他人在使用这个对象,就会被释放掉,因此不应该断开连接。3、从共享内存中读取数据LoadFromMemory();
和内存进行连接。然后使用 QBuffer 进行读取,记得这个过程需要加锁和解锁。进程和内存进行分离。 sharedMemory.attach());QBuffer buffer;QDataStream in(&buffer);QImage image;sharedMemory.lock();buffer.setData((char *)sharedMemory.constData(),sharedMemory.size());buffer.open(QBuffer::ReadOnly);in >> image;sharedMemory.unlock();sharedMemory.detach();我们启动两个程序,是两个进程。 左边的进程上运行:在 共享内存中加入数据loadFromFile();; 右边的进程上运行:从共享内存中读取数据LoadFromMemory();。
可以在2.2 的演示中看到效果。
需要注意的是,我们左边进程,如果运行LoadFromMemory();,会导致共享内存直接被释放掉,就会导致右边的进程无法使用这个共享进程了。 如果把LoadFromMemory(); 中释放内存的代码删除,会导致,两个进程都不释放共享内存。在左边进程想更新这个内存sharedMemory.create(size);时可能会报错。
需要设计这个状态机过程,起始还是有点琐碎的。
2.2 演示 代码仓库https://gitee.com/hiyanyx/qt5.14-cpp_dds_-project/tree/QTProcess 分支:QTProcess
参考《Qt Creator快速入门_第三版__霍亚飞编著.pdf》