方法1:system
system("gnome-terminal -- bash -c '/home/xx/myssh/my.sh'&");//chmod a+x /home/xx/my.sh;
my.sh
#!/bin/bash
cd /home/xx/myssh
./helloworld
echo "sleep:4秒"
sleep 4
exit 0
helloworld.cpp
#include<iostream>
using namespace std;
int main(){
cout<<"hello world"<<endl;
return 0;
}
然后运行:
g++ helloworld.cpp -o helloworld
【如果想要输入参数,sh脚本中可以用“$1”"$2"占位】
注意:当“sleep 4秒”结束后窗口会退出
方法2:QProcess::startDetached
它与start不同,它是以分离进程的方式启动 没有子父进程关系
QProcess::startDetached("/home/xx/myssh/bash.sh");
bash.sh
#!/bin/bash
gnome-terminal -- bash -c 'source /home/xx/catkin_ws/devel/setup.bash && rosrun cam_laser_calib pcd_points_gps 1 0 111.pcd'&
#source /home/xx/catkin_ws/devel/setup.bash
#rosrun cam_laser_calib pcd_points_gps 1 0 111.pcd
exit 0
[pcd_points_gps是自己写的一个程序哈]
方法3:QProcess::start
process->start("bash"); //启动终端(Windows下改为cmd)
process->waitForStarted(); //等待启动完成
process->write("/home/xx/myssh/my.sh\n"); //向终端写入命令,注意尾部的“\n”不可省略
process->write("ifconfig\n");
将输出信息读取到编辑框
ui->textEdit->append(process->readAllStandardOutput().data());
sleep4秒后会执行“ifconfig”(查看ip地址)
效果
完整代码
除了上述所用到的my.sh与bash.sh外,剩下的主要是qt代码
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include<QProcess>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void readoutput();
void readerror();
private:
Ui::MainWindow *ui;
QProcess *process;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QProcess>
#include<QMessageBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
process = new QProcess(this);
connect(process , &QProcess::readyReadStandardOutput, this , &MainWindow::readoutput);
connect(process , &QProcess::readyReadStandardError, this , &MainWindow::readerror);
}
MainWindow::~MainWindow()
{
delete ui;
if(process)
{
process->close();
process->waitForFinished();
}
}
void MainWindow::readoutput()
{
ui->textEdit->append(process->readAllStandardOutput().data()); //将输出信息读取到编辑框
}
void MainWindow::readerror()
{
QMessageBox::information(0, "Error", process->readAllStandardError().data()); //弹出信息框提示错误信息
}
void MainWindow::on_pushButton_clicked()
{
system("gnome-terminal -- bash -c '/home/xx/myssh/my.sh'&");//chmod a+x /home/xx/my.sh;
}
void MainWindow::on_pushButton_2_clicked()
{
QProcess::startDetached("/home/xx/myssh/bash.sh");//以分离进程的方式启动 没有子父进程关系
}
void MainWindow::on_pushButton_3_clicked()
{
process->start("bash"); //启动终端(Windows下改为cmd)
process->waitForStarted(); //等待启动完成
process->write("/home/xx/myssh/my.sh\n"); //向终端写入命令,注意尾部的“\n”不可省略
process->write("ifconfig\n");
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
界面搭建
三个按钮+一个文本框
向sh文件输入参数
有时需要向sh文件中输入参数,这时可以用‘$1’’$2’等占位
如改my.sh文件
#!/bin/bash
cd /home/xx/myssh
./helloworld
time=$1
echo "sleep:$time秒"
sleep $time
exit 0
【time=$1:是设置了变量‘time’,而time的值来于输入的第一个参数‘$1’,后面在用这个变量‘time’时也要写成‘ $time’的形式】
对qt的更改
需求1:直接在后面输入参数
或
需求2:获取在qt界面输入的参数作为输入
先获取‘lineEdit’输入的参数,然后将整个QString 指令转成char类型,然后写入process:
QString strget=ui->lineEdit->text();
QString str=QString("/home/xx/myssh/my.sh %1\n").arg(strget);
char *n;
QByteArray m=str.toLatin1();
n=m.data();
process->write(n);
运行ros指令的sh脚本注意事项
在运行含ros指令的sh脚本时如:“rosbag play xxx.bag”需要注意两点
1.“xxx.bag”路径要全:如“/home/xx/catkin_ws/xxx.bag”,或者先进入该文件夹“cd /home/xx/catkin_ws”
2.与运行roscore一样,要先设置环境变量:即在运行“rosbag play”指令前先要加“ source /opt/ros/kinetic/setup.bash”。同理,在运行自己写的“rosrun xxx xxx”时也要先source一下如:“source /home/xx/catkin_ws/devel/setup.bash”
例如:
bagplay.sh
#!/bin/bash
#source /opt/ros/melodic/setup.bash
rosbag play /home/$1/$2
sleep 20
exit 0
如果不加“source /opt/ros/melodic/setup.bash”
虽然能直接在终端运行bagplay.sh
但是通过qt运行时会报错