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

如图所示

总结

善于总结,多进一步。

相关推荐
爱编程的鱼13 分钟前
C# 参数详解:从基础传参到高级应用
开发语言·microsoft·c#
Michael_lcf15 分钟前
Java的UDP通信:DatagramSocket和DatagramPacket
java·开发语言·udp
道之极万物灭16 分钟前
Python操作word实战
开发语言·python·word
凉栀お_20 分钟前
MySQL相关知识查询表中内容(第二次作业)
数据库·mysql
moringlightyn42 分钟前
c++11可变模版参数 emplace接口 新的类功能 lambda 包装器
开发语言·c++·笔记·其他·c++11·lambda·包装器
Laplaces Demon43 分钟前
Spring 源码学习(十四)—— HandlerMethodArgumentResolver
java·开发语言·学习
郝学胜-神的一滴1 小时前
使用Linux系统函数递归遍历指定目录
linux·运维·服务器·开发语言·c++·软件工程
guygg881 小时前
Java 无锁方式实现高性能线程
java·开发语言
ss2731 小时前
手写Spring第7弹:Spring IoC容器深度解析:XML配置的完整指南
java·前端·数据库
PFinal社区_南丞1 小时前
PostgreSQL-10个鲜为人知的强大功能
数据库·后端