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

如图所示

总结

善于总结,多进一步。

相关推荐
whcyhhh4 分钟前
头歌实践教学平台:大数据存储2023(十三3)
大数据·开发语言·python
2601_9620652519 分钟前
2.启动mysql容器
java·数据库·mysql
Freak嵌入式1 小时前
树莓派 Pico GPIO 深度解析:从 MCU 架构到寄存器控制,底层原理与实践指南
java·开发语言·科技·单片机·嵌入式硬件·架构
张人玉1 小时前
基于 Python + PyQt5 的水果目标检测与分割可视化系统——水果深度学习识别可视化大屏
python·深度学习·qt·目标检测·sqlite·echarts
啊啊啊啊啊!!!!1 小时前
【c++】map和set的使用
开发语言·c++
hu9245195591 小时前
Matlab保护源代码—P文件和exe文件详细解析
开发语言·matlab
for_ever_love__1 小时前
python爬虫: GET请求与POST请求
开发语言·爬虫·python·网络编程
Freak嵌入式1 小时前
实战对比:用 mpremote/Putty/MobaXterm 连接树莓派 Pico REPL,谁更省心?
java·大数据·开发语言·科技·单片机·嵌入式硬件
ttwuai1 小时前
Go 后台管理系统组件库文档怎么写,才不会坑后续维护?
开发语言·javascript·golang
茉莉玫瑰花茶1 小时前
知识库的构建 [ 3 ]
开发语言·python