若该文为原创文章,转载请注明出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/128890324
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)
Qt开发专栏:项目实战(点击传送门)
需求
在Qt软件中实现部分终端控制命令行功能,使软件内可以又好的模拟终端控制,提升软件整体契合度。
Demo演示
运行包下载地址:
CSDNf粉丝0积分下载:https://download.csdn.net/download/qq21497936/87418829
QQ群:博客首页扫码进入技术群,点击“文件”搜索“terminator”,群内与博文同步更新)
功能描述 v1.0.0
- windows版本打开即可实时现实;
- centOS打开抓不到默认的输出只能抓到命令执行的输出结果;
- ubuntu等其他linux-arm没有测试;
- 可以执行单条指令;
- 可以清空模拟ctrl+c结束正在操作的命令;
项目模块化部署
源码
TerminatorWidget.h
#ifndef TERMINATORWIDGET_H
#define TERMINATORWIDGET_H
#include <QWidget>
#include <QThread>
#include <QTextCursor>
#include "TerminatorManager.h"
namespace Ui {
class TerminatorWidget;
}
class TerminatorWidget : public QWidget
{
Q_OBJECT
public:
explicit TerminatorWidget(QWidget *parent = 0);
~TerminatorWidget();
protected:
void initControl();
protected slots:
void slot_recvData(QByteArray byteArray);
void slot_recvDataError(QByteArray byteArray);
private slots:
void on_pushButton_exec_clicked();
void on_pushButton_stop_clicked();
void on_pushButton_clear_clicked();
private:
Ui::TerminatorWidget *ui;
private:
QThread *_pTerminatorManagerThread;
TerminatorManager * _pTerminatorManager;
};
#endif // TERMINATORWIDGET_H
TerminatorManager.h
#ifndef TERMINATORMANAGER_H
#define TERMINATORMANAGER_H
#include <QObject>
#include <QProcess>
#include <QTextCodec>
class TerminatorManager : public QObject
{
Q_OBJECT
public:
explicit TerminatorManager(QObject *parent = 0);
public:
bool getRunning() const;
void wirte(QByteArray byteArray);
void stop();
void ctrlC();
signals:
void signal_recvData(QByteArray byteArray);
void signal_recvDataError(QByteArray byteArray);
public slots:
void slot_start();
void slot_stop();
protected:
void initControl();
protected slots:
void slot_stateChanged(QProcess::ProcessState newState);
void slot_readyReadStandardOutput();
void slot_readyReadStandardError();
void slot_write(QByteArray byteArray);
void slot_ctrlC();
private:
bool _running; // 是否运行
QProcess *_pProcess; // 进程
QTextCodec *_pTextCodec; // 编码,读取数据转化编码时用
};
#endif // TERMINATORMANAGER_H
TerminatorManager.cpp
#include "TerminatorManager.h"
#include <QDebug>
#include <QDateTime>
//#define LOG qDebug()<<__FILE__<<__LINE__
//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__
//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()
//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")
#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")
TerminatorManager::TerminatorManager(QObject *parent)
: QObject(parent),
_running(false),
_pProcess(0),
_pTextCodec(0)
{
initControl();
}
bool TerminatorManager::getRunning() const
{
return _running;
}
void TerminatorManager::wirte(QByteArray byteArray)
{
QMetaObject::invokeMethod(this, "slot_write", Q_ARG(QByteArray, byteArray));
}
void TerminatorManager::ctrlC()
{
QMetaObject::invokeMethod(this, "slot_ctrlC");
}
void TerminatorManager::slot_start()
{
if(_running)
{
LOG << "It's already running!!!";
return;
}
// 初始化子线程中的相关类
if(!_pProcess)
{
_pProcess = new QProcess();
connect(_pProcess, SIGNAL(stateChanged(QProcess::ProcessState)),
this, SLOT(slot_stateChanged(QProcess::ProcessState)));
connect(_pProcess, SIGNAL(readyReadStandardOutput()),
this, SLOT(slot_readyReadStandardOutput()));
connect(_pProcess, SIGNAL(readyReadStandardError()),
this, SLOT(slot_readyReadStandardError()));
#ifndef LINUX
_pProcess->start("cmd");
_pProcess->waitForStarted();
#else
// _pProcess->start("bash");
_pProcess->start("sh");
_pProcess->waitForStarted();
#endif
}
_running = true;
}
void TerminatorManager::slot_stop()
{
if(!_running)
{
LOG << "It's not running!!!";
return;
}
if(_pProcess)
{
_pProcess->kill();
_pProcess->close();
_pProcess->waitForFinished();
_pProcess->deleteLater();
_pProcess = 0;
}
_running = false;
}
void TerminatorManager::initControl()
{
// linux下有可能获取失败
_pTextCodec = QTextCodec::codecForName("System");
}
void TerminatorManager::slot_stateChanged(QProcess::ProcessState newState)
{
LOG << newState;
}
void TerminatorManager::slot_readyReadStandardOutput()
{
QByteArray byteArray = _pProcess->readAllStandardOutput();
// QByteArray byteArray = _pProcess->readAll();
QString str;
// 转换为unicode
if(_pTextCodec)
{
str = _pTextCodec->toUnicode(byteArray);
}else{
str = QString(byteArray);
}
emit signal_recvData(str.toUtf8());
}
void TerminatorManager::slot_readyReadStandardError()
{
QByteArray byteArray = _pProcess->readAllStandardError();
QString str;
// 转换为unicode
if(_pTextCodec)
{
str = _pTextCodec->toUnicode(byteArray);
}else{
str = QString(byteArray);
}
emit signal_recvDataError(str.toUtf8());
}
void TerminatorManager::slot_write(QByteArray byteArray)
{
if(!_pProcess)
{
LOG << "Is't not running";
return;
}
LOG << QString(byteArray);
LOG << _pProcess;
_pProcess->write(byteArray);
LOG;
}
void TerminatorManager::slot_ctrlC()
{
if(!_running)
{
LOG << "It's not running!!!";
return;
}
slot_stop();
slot_start();
}
工程模板
若该文为原创文章,转载请注明出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/128890324