QT学习之QTextBrowser加载脚本并动态展示执行到脚本哪行命令

测试读卡器和芯片时,执行一系列卡片APDU命令才能测试卡片是否正常,为了方便快速测试,希望根据脚本自动执行完所有命令;
效果如下:

在这里插入图片描述

1.加载脚本并设置到QTextBrowser中展示(文件读写不错的帖子:https://blog.csdn.net/HuanBianCheng27/article/details/125802513?spm=1001.2014.3001.5506)
点击选择脚本后代码如下:

// 选择脚本
void ICTestTools::on_selectScript_clicked() {
    scriptPath = QFileDialog::getOpenFileName(this, "打开脚本文件", "D:/"); // 弹出对话框
    ui.scriptPathlabel->setText(scriptPath); // 讲路径放到label中展示
    readCardThread.path = scriptPath;

    // 读取内容放到textBrowser中
    QFile file(scriptPath);
    // 设置打开方式
    file.open(QIODevice::ReadOnly);
    // QByteArray array = file.readAll(); // 一次读取所有文件内容
    QByteArray array;
    int lineCount = 0;
    while (!file.atEnd()) {    
        array += file.readLine();
        lineCount++;
    }

    ui.scriptCount->setText(QString::number(lineCount, 10));
    // 将文件内容设置到textBrowser中
    ui.scriptTxt->setText(array);
 
    // 关闭文件
    file.close();
}

file.readAll();是一次读取所有文件内容;
我希望知道每行的命令是什么,还有一共多少行,所以按行进行的读取(file.readLine());

2.新增线程执行脚本每行的命令;
新增ReadCardThread线程来执行具体脚本中的命令,执行命令中也可以选择停止执行;
.h


#ifndef THREAD01_H
#define THREAD01_H

#include <QThread>
#include <QMutex>

class ReadCardThread : public QThread
{
    Q_OBJECT;
public:
    ReadCardThread();
    void startThread();             //开启线程
    void stop();                    //停止线程

    void loadScript(); // 加载脚本

    QString path; // 脚本路径
    QList<QByteArray> baList; // 脚本内容列表
    int lineCount = 0;

signals:
    void runScriptLine(int ret);

protected:
    void run();                     //线程主执行函数
private:
    volatile bool stopped;          //线程停止位
    QMutex m_mutex;                 //互斥锁
};

#endif // THREAD01_Hcpp

.cpp

#include "ReadCardThread.h"
#include <QFileDialog>
#include <QDebug>
#include <iostream>
#include <Windows.h>

using namespace std;
ReadCardThread::ReadCardThread()
{
    stopped = false;
}

void ReadCardThread::loadScript()
{
    // 加载脚本
    QFile file(path);
    // 设置打开方式
    file.open(QIODevice::ReadOnly);
    QByteArray array;
    lineCount = 0;
    while (!file.atEnd()) {
        baList.append(file.readLine());
        lineCount++;
    }
    // 关闭文件
    file.close();
}

void ReadCardThread::run()
{
    // 加载脚本
    loadScript();

    int i = 0;
    while (!stopped && i < lineCount) {
        emit runScriptLine(i);
        Sleep(200);
        i++;
    }
    //exec();
}


void ReadCardThread::startThread()
{
    m_mutex.lock();
    stopped = false;
    m_mutex.unlock();
    start();
}

void ReadCardThread::stop()
{
    m_mutex.lock();
    stopped = true;
    m_mutex.unlock();
}

调用的exe中:
ReadCardThread readCardThread; 声明一个线程实例
// 线程读卡设置高亮
connect(&readCardThread, SIGNAL(runScriptLine(int)), this, SLOT(SetLineColor(int))); 绑定高亮某行命令的信号,如图
在这里插入图片描述

点击开始测试后,启动线程readCardThread.startThread(); 具体代码如下

// 开始跑脚本
void ICTestTools::on_startRunScript_clicked() {
    ui.scriptTxt->moveCursor(QTextCursor::Start); // 光标回到初始位置

    loginDoc = ui.scriptTxt->document();
    loginDocNum = loginDoc->blockCount();//返回文档中的文本块的数量,回车符是一个block

    // 1.清掉之前的设置
    extraSelections.clear();

    // 2.重置为黑色
    for (int i = 0; i < loginDocNum; i++) {
        QTextEdit::ExtraSelection selection1;
        selection1.cursor = QTextCursor(loginDoc->findBlockByNumber(i)); // 选择第11行(假设行号从0开始)
        selection1.cursor.select(QTextCursor::LineUnderCursor);
        selection1.format.setForeground(Qt::black);
        // 应用额外的选择
        extraSelections.append(selection1);
    }
    ui.scriptTxt->setExtraSelections(extraSelections);
    this->repaint(); // 重绘 

    // 3.起执行脚本的线程
    readCardThread.startThread();
}

高亮设置的代码:当线程执行命令时,会把执行好的行号通过runScriptLine信号发到主进程中,进程进行如下设置;repaint是实时刷新的关键(知识获取来源:https://zhuanlan.zhihu.com/p/612034860?utm_id=0);
ui.scriptTxt->moveCursor(QTextCursor::Down) 可以让QTextBrowser有自动往下滚动的效果,不过我目前还没跳好,和我的高亮不是很一致;还得再研究研究;https://doc.qt.io/qt-5/qdesignerformwindowcursorinterface.html
在这里插入图片描述


```cpp
void ICTestTools::SetLineColor(int lineNum) {   
    if (lineNum > 0) {
        extraSelections[lineNum-1].cursor = QTextCursor(loginDoc->findBlockByNumber(lineNum-1));
        extraSelections[lineNum-1].cursor.select(QTextCursor::LineUnderCursor);

        // 设置选择的格式(比如,蓝色背景)
        extraSelections[lineNum-1].format.setForeground(Qt::black); // 上一行重置为黑色
    }
    // 设置选择范围
   /* QTextEdit::ExtraSelection selection = extraSelections[lineNum];*/
    extraSelections[lineNum].cursor = QTextCursor(loginDoc->findBlockByNumber(lineNum)); // 选择第11行(假设行号从0开始)
    extraSelections[lineNum].cursor.select(QTextCursor::LineUnderCursor);

    // 设置选择的格式(比如,蓝色背景)
   // selection.format.setBackground(Qt::green);  // 设置背景
    extraSelections[lineNum].format.setForeground(Qt::green);

    // 光标移动
    ui.scriptTxt->moveCursor(QTextCursor::Down); 
    // ui.scriptTxt->moveCursor(QTextCursor::NextRow);

    // 应用额外的选择
    ui.scriptTxt->setExtraSelections(extraSelections);
    this->repaint(); // 重绘 
}

以下也可以设置滚动,需要计算每次滚动多少
// 设置滚动
int countLine = ui.scriptTxt->toPlainText().count();
QScrollBar* bar = ui.scriptTxt->verticalScrollBar();
ui.scriptTxt->verticalScrollBar()->setValue(bar->value() + num);

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值