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

如图所示

总结

善于总结,多进一步。

相关推荐
努力的小雨2 分钟前
快速上手 KSQL:轻松与数据库交互的利器
数据库·经验分享
何曾参静谧3 分钟前
「Py」Python基础篇 之 Python都可以做哪些自动化?
开发语言·python·自动化
Gentle5865 分钟前
labview中连接sql server数据库查询语句
数据库·labview
Gentle5866 分钟前
labview用sql server数据库存取数据到一个单元格
数据库·labview
Prejudices7 分钟前
C++如何调用Python脚本
开发语言·c++·python
2401_857636399 分钟前
共享汽车管理新纪元:SpringBoot框架应用
数据库·spring boot·汽车
菲兹园长9 分钟前
表的设计(MYSQL)
数据库·mysql
我狠狠地刷刷刷刷刷20 分钟前
中文分词模拟器
开发语言·python·算法
wyh要好好学习23 分钟前
C# WPF 记录DataGrid的表头顺序,下次打开界面时应用到表格中
开发语言·c#·wpf
AitTech24 分钟前
C#实现:电脑系统信息的全面获取与监控
开发语言·c#