需求
在Qt软件中实现部分终端控制命令行功能,使软件内可以又好的模拟终端控制,提升软件整体契合度。
Demo演示
功能描述 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(); }
工程模板