第十三课:QtCmd 命令行终端应用程序开发

功能描述:开发一个类似于 Windows 命令行提示符或 Linux 命令行终端的应用程序

一、最终演示效果 

QtCmd 不是因为它是 Qt 的组件,而是采用 Qt 开发了一个类似 Windows 命令提示符或者 Linux 命令行终端的应用程序,故取名为 QtCmd。

上述演示是在 Win10 操作系统下,模拟命令提示符的功能,输入错误的指令(如 windows 下输入 ls 指令),错误输出的字体颜色为红色;输入正确的指令(如 windows 下输入dir 指令),标准输出的字体颜色显示正常。

本应用程序原为一个项目的子功能,实现命令行终端的界面,现把这一功能单独封装了一个窗体类,分享给大家参考,可以直接集成到你的应用程序中。

具体功能使用就不多说了,和命令行终端的功能一模一样,只是说把这一功能集成到自己的应用程序中了,命令行终端支持的指令,本终端全部支持。


二、命令行终端程序开发

命令行终端程序主要在 terminalwidget.h 和 terminalwidget.cpp 中封装了 TerminalWidget 类,实现了有关命令输入和信息输出的所有功能。

terminalwidget.h 文件代码如下:

#ifndef TERMINALWIDGET_H
#define TERMINALWIDGET_H

#include <QTextEdit>
#include <QKeyEvent>
#include <QFont>
#include <QProcess>
#include <QByteArray>
#include <QLabel>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QTextLayout>
#include <QTextCursor>
#include <QTextBlock>
#include <QTextCodec>
#include <assert.h>

class TerminalWidget: public QTextEdit
{
    Q_OBJECT
public:
    TerminalWidget();

protected:
    void keyPressEvent(QKeyEvent *e);

private:
    // 字体
    QFont font;
    // 命令行终端进程
    QProcess * proc;
    // 光标位置
    long long lastPosition = 0;
    // 上一次的输入内容
    QByteArray lastInput;

public slots:
    /**
     * @brief readyReadStandardOutputSlot       标准输出
     */
    void readyReadStandardOutputSlot();
    /**
     * @brief readyReadStandardErrorSlot        错误输出
     */
    void readyReadStandardErrorSlot();
};

#endif // TERMINALWIDGET_H

terminalwidget.cpp 文件代码如下:

#include "terminalwidget.h"
#include <QDebug>

TerminalWidget::TerminalWidget()
{
    setStyleSheet("background-color:rgb(0,0,0); color:rgb(255,255,255); border:0px;");
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    resize(1000,700);
    setWindowTitle("命令行提示符");

    font.setFamily("Times New Roman");
    font.setPixelSize(14);
    setFont(font);

    proc = new QProcess();
    connect(proc,SIGNAL(readyReadStandardOutput()),this,SLOT(readyReadStandardOutputSlot()));
    connect(proc,SIGNAL(readyReadStandardError()),this,SLOT(readyReadStandardErrorSlot()));

#ifdef Q_OS_WIN
    proc->start("cmd");
#elif Q_OS_LINUX
    proc->start("bash");
#endif

    QTextCursor editCursor = textCursor();
    QTextBlockFormat textBlockFormat;
    textBlockFormat.setLineHeight(20, QTextBlockFormat::FixedHeight);
    editCursor.setBlockFormat(textBlockFormat);
    setTextCursor(editCursor);
}

void TerminalWidget::keyPressEvent(QKeyEvent *e)
{
    QTextCursor editCursor = textCursor();
    // Qt::Key_Enter 是小键盘(数字键盘)的 Enter,对应的虚拟键码为:0x01000005
    // Qt::Key_Return 是大键盘区的 Enter,对应的虚拟键码为:0x01000004
    if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter)
    {
        e->ignore();
        editCursor.setPosition(lastPosition, QTextCursor::MoveAnchor);
        editCursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
        QString string = editCursor.selectedText();
        editCursor.clearSelection();
#ifdef Q_OS_WIN
        lastInput =  string.toLocal8Bit() + '\r' + '\n';
#elif Q_OS_LINUX
        lastInput =  string.toLocal8Bit() + '\n';
#endif
        proc->write(lastInput);
        return;
    }
    else if(e->key() == Qt::Key_Backspace && editCursor.position() <= lastPosition)
        return;
    else if(e->key() == Qt::Key_Delete && editCursor.position() <= lastPosition)
        return;
    else
        return QTextEdit::keyPressEvent(e);
}

void TerminalWidget::readyReadStandardOutputSlot()
{
    QByteArray ba = proc->readAllStandardOutput();
    QTextCodec * textCodec = QTextCodec::codecForName("System");
    // assert 断言,如果 textCodec 为空,则编译报错
    assert(textCodec != nullptr);
    QString output = textCodec->toUnicode(ba);

    if (output.length() > 0 && output != QString::fromLocal8Bit(lastInput))
    {
        setTextColor(Qt::white);
        append(output.trimmed());
        moveCursor(QTextCursor::End);
        lastPosition = textCursor().position();
    }
}

void TerminalWidget::readyReadStandardErrorSlot()
{
    QByteArray ba = proc->readAllStandardError();
    QTextCodec* textCodec = QTextCodec::codecForName("System");
    // assert 断言,如果 textCodec 为空,则编译报错
    assert(textCodec != nullptr);
    QString output = textCodec->toUnicode(ba);

    if (output.length() > 0 && output != QString::fromLocal8Bit(lastInput))
    {
        setTextColor(Qt::red);
        append(output.trimmed());
        moveCursor(QTextCursor::End);
        lastPosition = textCursor().position();
    }
}

完整的代码已经贴上,每个函数的备注写的非常清楚,如有不清楚的地方可以私信我。

完整代码压缩包下载地址: 

https://download.csdn.net/download/tanou3212/88222855https://download.csdn.net/download/tanou3212/88222855如果出现中文乱码的问题,请参考我的另外一篇博客《第十课:Qt 字符编码和中文乱码相关问题》 ,百分百能解决你的问题!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/78002.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SSD202D-logo分区添加dtb

SSD202D-kernel-uimage后面加入dtb_旋风旋风的博客-CSDN博客 1.由于内核的uimage老是压缩解压缩,拿到压缩包里面dtb实在困难; 2.把dtb烧在后面又有安全隐患;而且还会有打包升级方法ota之类的很多;又毙掉了, 3.最后直接把dtb放在logo的包里,但是logo包要想添加好,也要深刻的理…

谷歌云 | BigQuery 现在支持用于查询开放表格式的清单文件

Cloud Ace 是谷歌云全球战略合作伙伴&#xff0c;拥有 300 多名工程师&#xff0c;也是谷歌最高级别合作伙伴&#xff0c;多次获得 Google Cloud 合作伙伴奖。作为谷歌托管服务商&#xff0c;我们提供谷歌云、谷歌地图、谷歌办公套件、谷歌云认证培训服务。 开放表格式依赖嵌…

Golang下载安装

目录 1. 下载压缩包 2. 解压 3. 查看SDK是否安装成功 4. 配置环境变量 5. 查看环境变量是否配置成功 1. 下载压缩包 官网下载地址&#xff1a; All releases - The Go Programming Language Windows64位选择如下下载&#xff1a; 2. 解压 解压后内容如下&#xff1a; …

开源数据库Mysql_DBA运维实战 (DDL语句)

DDL DDL语句 数据库定义语言&#xff1a;数据库、表、视图、索引、存储过程. 例如:CREATE DROP ALTER DDL库 定义库{ 创建业务数据库&#xff1a;CREAATE DATABASE ___数据库名___ ; 数据库名要求{ a.区分大小写 b.唯一性 c.不能使用关键字如 create select d.不能单独使用…

unity拓展 unity自带的类(Tranform为例)

因为我们使用了ILRuntime热更&#xff0c;unity 打出的WebGL包&#xff0c;运行就会报找不到DoTween里面的方法&#xff0c;所以吧DoTween拓展到tranform类里面&#xff0c;这样就不会报错了&#xff0c;下面是示例 using DG.Tweening; using System.Collections; using Syste…

【CSS动画01--登录】

CSS动画01--登录 介绍代码HTMLCSSJS 介绍 当鼠标不同方向的划过时展示不同效果的登录&#xff0c;以上是一个简单的图片展示 代码 HTML <!DOCTYPE html> <html> <head><meta http-equiv"content-type" content"text/html; charsetutf-8&…

【第二讲---初识SLAM】

SLAM简介 视觉SLAM&#xff0c;主要指的是利用相机完成建图和定位问题。如果传感器是激光&#xff0c;那么就称为激光SLAM。 定位&#xff08;明白自身状态&#xff08;即位置&#xff09;&#xff09;建图&#xff08;了解外在环境&#xff09;。 视觉SLAM中使用的相机与常见…

Linux命令200例:crontab详解及应用场景(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

编译老版本c++程序 报错 msvcrt.dll 以及 0x000000 内存 不能为 “read“ 问题已解决

一般 win10 编译 xp对应老版本软件 调试采用 虚拟机形式进行测试&#xff0c;但是虚拟机中&#xff0c;无独立显卡&#xff0c;运行程序提示有&#xff0c;无法调用动态库&#xff0c;或者 内存无法读取&#xff0c;炸一看以为 winxp32位 内存识别只能3.7G.其实是显存无法使用…

idea 使用debug 启动项目的时候 出现 Method breakpoints may dramatically slow down debugging

问题: 1. 写了一段时间的代码&#xff0c;在debug启动项目后提示&#xff1a;Method breakpoints may dramatically slow down debugging 但是正常启动是可以的&#xff0c;debug不行。 2. idea 里面的项目&#xff0c;很多地方都有断点&#xff0c;现在想要取消全部的断点…

重塑DTC规则:元气森林的全渠道转型

元气森林作为迄今为止用5-6年时间最快达到70亿年销售额的饮料品牌&#xff08;统一、可口可乐、东鹏特饮都花了15年左右&#xff0c;康师傅花了10年&#xff09;。元气森林于2016年在北京创立&#xff0c;凭借健康产品理念和新潮营销方式&#xff0c;一款主打“0糖0卡0脂”概念…

k8s 认证和权限控制

k8s 的认证机制是啥&#xff1f; 说到 k8s 的认证机制&#xff0c;其实之前咋那么也有提到过 ServiceAccouont &#xff0c;以及相应的 token &#xff0c;证书 crt&#xff0c;和基于 HTTP 的认证等等 k8s 会使用如上几种方式来获取客户端身份信息&#xff0c;不限于上面几种…

JDBC封装与设计模式

什么是 DAO &#xff1f; Data Access Object(数据存取对象) 位于业务逻辑和持久化数据之间实现对持久化数据的访问 DAO起着转换器的作用&#xff0c;将数据在实体类和数据库记录之间进行转换。 ----------------------------------------------------- DAO模式的组成部分 …

QGIS3.28的二次开发五:VS使用QT插件创建UI界面

前面我们说了在创建项目时创建的是一个空项目&#xff0c;即不使用 Qt 提供的综合开发套件 Qt Creator&#xff0c;也不使用 Qt Visual Studio Tools 这类工具。 但是后面发现&#xff0c;如果我想要有更加满意的界面布局&#xff0c;还是要自己写一个UI文件&#xff0c;如果不…

【Python】基础语法:变量类型和动态类型

文章目录 1. 常量2. 变量3. 动态类型特性 努力经营当下 直至未来明朗 1. 常量 浮点数在内存中表示使用的是IEEE754标准&#xff0c;这套规则下&#xff0c;在内存中表示该浮点数额时候可能会存在微小的误差 在进行运算的时候&#xff0c;最好可以将数字&#xff08;字面值常…

Transformer(二)(VIT,TNT)(基于视觉CV)

目录 1.视觉中的Attention 2.VIT框架&#xff08;图像分类&#xff0c;不需要decoder&#xff09; 2.1整体框架 2.2.CNN和Transformer遇到的问题 2.3.1CNN 2.3.2Transformer 2.3.3二者对比 2.4.公式理解 3TNT 参考文献 1.视觉中的Attention 对于人类而言看到一幅图可以立…

UglifyJS 和JShaman相比有什么不同?都可以进行js混淆加密吗?

UglifyJS 和JShaman相比有什么不同&#xff1f; UglifyJS主要功能是压缩JS代码&#xff0c;减小代码体积&#xff1b;JShaman是专门用于对JS代码混淆加密&#xff0c;目的是让JS代码变的不可读、混淆功能逻辑、加密代码中的隐秘数据或字符&#xff0c;是用于代码保护的。 因此…

行业追踪,2023-08-10

自动复盘 2023-08-10 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

【CSS】CSS 布局——弹性盒子

Flexbox 是一种强大的布局系统&#xff0c;旨在更轻松地使用 CSS 创建复杂的布局。 它特别适用于构建响应式设计和在容器内分配空间&#xff0c;即使项目的大小是未知的或动态的。Flexbox 通常用于将元素排列成一行或一列&#xff0c;并提供一组属性来控制 flex 容器内的项目行…

【ts】【cocos creator】excel表格转JSON

需要将表格导出为text格式放到项目resources/text文件夹下 新建场景&#xff0c;挂载到Canvas上运行 表格文件格式&#xff1a; 保存格式选text tableToJson : import CryptoJS require(./FileSaver);const { ccclass, property } cc._decorator;ccclass export default c…