项目实战:Qt终端命令模拟工具 v1.0.0(实时获取命令行输出,执行指令,模拟ctrl+c中止操作)
需求
在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();
}
工程模板

项目实战:Qt终端命令模拟工具 v1.0.0(实时获取命令行输出,执行指令,模拟ctrl+c中止操作)的更多相关文章
- 终端的乐趣--Linux下有趣的终端命令或者工具【转】
转自:https://blog.csdn.net/gatieme/article/details/52144603 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原 ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)]
[易学易懂系列|rustlang语言|零基础|快速入门|(25)|实战2:命令行工具minigrep(2)] 项目实战 实战2:命令行工具minigrep 我们继续开发我们的minigrep. 我们现 ...
- [易学易懂系列|rustlang语言|零基础|快速入门|(24)|实战2:命令行工具minigrep(1)]
[易学易懂系列|rustlang语言|零基础|快速入门|(24)|实战2:命令行工具minigrep(1)] 项目实战 实战2:命令行工具minigrep 有了昨天的基础,我们今天来开始另一个稍微有点 ...
- Vue CLI 是如何实现的 -- 终端命令行工具篇
Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供了终端命令行工具.零配置脚手架.插件体系.图形化管理界面等.本文暂且只分析项目初始化部分,也就是终端命令行工具的实现. 0. 用法 ...
- 项目实战:Qt文件改名工具 v1.2.0(支持递归检索,搜索:模糊匹配,前缀匹配,后缀匹配;重命名:模糊替换,前缀追加,后缀追加)
需求 在整理文件和一些其他头文件的时候,需要对其名称进行整理和修改,此工具很早就应该写了,创业后,非常忙,今天抽空写了一个顺便提供给学习. 工具和源码下载地址 本篇文章的应用包和源码包可在 ...
- Windows终端命令行工具Cmder
在IT这一行,大部分情况下都是推荐大家使用Linux或者类Unix操作系统去编程,Linux作为一代优秀的操作系统,已经人尽皆知,在IT行业已经成为核心.有条件的大佬都选择了使用mac编程,最优秀的莫 ...
- AJ学IOS 之微博项目实战(12)发送微博自定义工具条代理实现点击事件
AJ分享,必须精品 一:效果 二:封装好的工具条 NYComposeToolbar.h 带代理方法 #import <UIKit/UIKit.h> typedef enum { NYCom ...
- 今日头条、抖音、西瓜、火山、微视、陌陌等自媒体平台小视频批量下载工具v1.1.0(视频搬运福利)
前言 目前各大自媒体平台爆火,网络流量暴涨,各大自媒体平台的小视频为广大个广告主带来了如泉涌般的的视频流量,更给广大的自媒体小编带来了丰厚的利益回报,想要创做更多的自媒体内容着实不易,下面给广大的小视 ...
- Blend打不开wpf项目,提示无法识别的工具版本“12.0”
讲项目文件用记事本打开然后修改为“14.0”即可
- Android项目实战(四十):Andoird 7.0+ 安装APK适配
首先看一下安装apk文件的代码 /** * 通过隐式意图调用系统安装程序安装APK */ public static void install(Context context) { Intent in ...
随机推荐
- [转帖]ansible 安装 K8S
作者:山河已无恙链接:https://www.zhihu.com/question/315497851/answer/2898814729来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业 ...
- [转帖]JVM(3)之垃圾回收(GC垃圾收集器+垃圾回收算法+安全点+记忆集与卡表+并发可达性分析......)
<深入理解java虚拟机>+宋红康老师+阳哥大厂面试题2总结整理 一.堆的结构组成 堆位于运行时数据区中是线程共享的.一个进程对应一个jvm实例.一个jvm实例对应一个运行时数据区.一个运 ...
- [转帖]耗时几个月,终于找到了JVM停顿十几秒的原因
https://www.cnblogs.com/codelogs/p/16060792.html 原创:打码日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 最近我们系 ...
- Python设计模式:你的代码真的够优雅吗?
当涉及到代码优化时,Python作为一种高级编程语言,具有广泛的应用领域和强大的功能.在软件开发中,设计模式是一种被广泛采用的解决问题的方案,它提供了一种在特定情境中重复使用的可行方案.在Python ...
- selenium四种截图方式
1.get_screenshot_as_file() from selenium import webdriver driver = webdriver.Chrome() driver.get(&qu ...
- Protocol Buffer命名空间冲突
原文在这里. 什么是Protocol Buffer命名空间冲突? 所有链接到Go二进制文件的Protocol Buffer声明都被插入到一个全局注册表中. 每个Protocol Buffer声明(例如 ...
- P9805 [POI2022~2023R1] ply
1st思路 贪心 当遇到左括号深度加一,可如果当前深度大于 \(H\) 时深度减二,并且 \(ans\) 加一.相当于进行一次翻转操作. 当遇到右括号深度减一,当深度小于零时深度加二,并且 \(ans ...
- TienChin 渠道管理-更新渠道接口开发
ChannelController /** * 修改渠道 */ @PreAuthorize("hasPermission('tienchin:channel:edit')") @L ...
- 如何在 Linux 上使用 NPOI
由于 NPOI 使用 System.Drawing.Common,因此在 Linux 系统上必须安装 libgdiplus 和 libc6. Ubuntu 16.04+ apt-get install ...
- 开启中文智能之旅:探秘超乎想象的 Llama2-Chinese 大模型世界
"开启中文智能之旅:探秘超乎想象的 Llama2-Chinese 大模型世界" 1.国内Llama2最新下载地址 本仓库中的代码示例主要是基于Hugging Face版本参数进行调 ...