Qt--命令行终端程序开发

提示:本文为学习记录,若有错误,请联系作者,谦虚受教。

文章目录


前言

Constant dropping wears the stone.


一、头文件

cpp 复制代码
#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

二、cpp文件

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();
    }
}

三、使用流程

主要使用process来命令行操作

代码如下(示例):

c 复制代码
int main(int argc,char *argv[])
{
QAPPlication a(argc,argv);
TerminalWidget w;
w.show();
return a,exec();
}

如图所示

总结

善于总结,多进一步。

相关推荐
Cx330❀5 小时前
【MySQL基础】一文吃透“表的约束”:从 Null/Default 到主外键的终极安全法则
linux·服务器·数据库·c++·mysql·安全
c238565 小时前
第二篇:《测试指挥官:可视化单题自测框架(含 assert 实操)》
java·数据库·c++·算法·安全性测试
我科绝伦(Huanhuan Zhou)5 小时前
MySQL极端场景数据丢失防护:从Crash-Safe到异地备份
数据库·mysql
辞旧 lekkk5 小时前
【Redis初阶】常见数据类型
开发语言·数据库·c++·redis·学习·缓存·bootstrap
帅次6 小时前
Kotlin 与 Java 互操作:混合工程里的平台类型与 API 边界
java·开发语言·kotlin·suspend·nullable
明志数科6 小时前
人形机器人格斗场景下的技术挑战:动力学控制、感知融合与实时决策
网络·数据库
酉鬼女又兒6 小时前
零基础入门 DeepSeek V4 Pro API 开发:从环境搭建、消息格式规范到翻译函数实战、少样本提示、多轮对话聊天机器人与常见报错全流程详解指南
大数据·网络·数据库·人工智能·macos·机器人·github
笨蛋不要掉眼泪6 小时前
MySQL架构揭秘:MVCC解决读一致性问题
数据库·mysql·架构
Navicat中国7 小时前
开发者入门:无服务器数据库
数据库·云原生·serverless·navicat
dtq04247 小时前
C语言-结构体详解
c语言·开发语言·学习