qt 调用cmd 并输入到界面

您所在的位置:网站首页 打开cmd后输入的代码 qt 调用cmd 并输入到界面

qt 调用cmd 并输入到界面

2024-03-04 07:48| 来源: 网络整理| 查看: 265

场景

Win10 QT5.9 使用QProcess调用cmd,利用qt自带的槽函数把原本打印到cmd的信息,打印到界面

界面

在这里插入图片描述 保存按钮 ui.pushButton:点击运行cmd,所以需要一个槽函数Slot_Test()

connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(Slot_Test()));

运行cmd是借助qt自带的QProcess (在头文件中定义 成员变量 m_Process)

QProcess 自带的信号:

读就绪-readyRead()标准读就绪-readyReadStandardOutput()产生错误-errorOccurred()进程完成-finished() 编写对应的槽函数即可输出到 界面 ui.textBrowser->append(msg); 在这里插入图片描述 参考文献:https://blog.csdn.net/Hxj_CSDN/article/details/89066330?spm=1001.2014.3001.5506 代码 logs.h #pragma once #include #include "ui_logs.h" #include class logs:public QDialog { Q_OBJECT public: logs(QWidget *parent = Q_NULLPTR); ~logs(); private slots: void Slot_errorProcess(); void Slot_finishedProcess(int exitCode); void Slot_value_changed(int nValue); void Slot_Test(); private: Ui::logs ui; QProcess m_Process; logs.cpp

首先是槽函数

logs::logs(QWidget *parent) : QDialog(parent) { ui.setupUi(this); init(); connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(Slot_Test()));//cmd connect(&m_Process, SIGNAL(readyRead()), this, SLOT(Slot_readData()));//读就绪 connect(&m_Process, SIGNAL(readyReadStandardOutput()), this, SLOT(Slot_readData()));//标准读就绪 connect(&m_Process, SIGNAL(errorOccurred()), this, SLOT(Slot_errorProcess()));//产生错误 connect(&m_Process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(Slot_finishedProcess(int, QProcess::ExitStatus)));//进程完成 }

启动cmd 使用start

void logs::Slot_Test() { QString strBasePath = QApplication::applicationDirPath() + "\\" + POSITIVESAMPLE_PATH; QString pythonCommand = QString("python main_test.py --pretrained_path %1 ").arg(m_strPretrainedModelPath); QString strBat = QString("positiveSampleTool.bat"); QFile file; file.setFileName(strBasePath + strBat); if (file.open(QIODevice::WriteOnly)) { file.write("@echo off\r\n"); file.write("cd ..\ \r\n"); file.write("cd bin/train/PaddleX_Train \r\n"); file.write("call activate\r\n"); file.write(pythonCommand.toLocal8Bit()); file.write("\r\n"); file.write("exit"); file.close(); } else { return; } m_Process.start(strBasePath+"\\positiveSample\\positiveSampleTool.bat"); }

打印到界面

void logs::Slot_readData() { QByteArray qbt = m_Process.readAllStandardOutput(); QString msg = QString::fromLocal8Bit(qbt); ui.textBrowser->append(msg); } void logs::Slot_errorProcess() { QString msg = m_Process.errorString(); ui.textBrowser->append("" + msg + + ""); } void logs::Slot_finishedProcess(int exitCode) { ui.textBrowser->append("finished"); ui.textBrowser->append("end"); InitDatas(); } 坑

我的QProcess 写为成员变量 m_Process; 在类的构造函数中 编写信号槽

logs::logs(QWidget *parent) : QDialog(parent) { ui.setupUi(this); init(); connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(Slot_Test()));//cmd connect(&m_Process, SIGNAL(readyRead()), this, SLOT(Slot_readData()));//读就绪 connect(&m_Process, SIGNAL(readyReadStandardOutput()), this, SLOT(Slot_readData()));//标准读就绪 connect(&m_Process, SIGNAL(errorOccurred()), this, SLOT(Slot_errorProcess()));//产生错误 connect(&m_Process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(Slot_finishedProcess(int, QProcess::ExitStatus)));//进程完成 }

然后就坑了,信号槽只有第一次好使,再启动进程就不行了 于是添加以下代码:

if (m_Process.atEnd()) { runTestFile(); disconnect(&m_Process, SIGNAL(readyRead()), this, SLOT(Slot_readData()));//读就绪 disconnect(&m_Process, SIGNAL(readyReadStandardOutput()), this, SLOT(Slot_readData()));//标准读就绪 disconnect(&m_Process, SIGNAL(errorOccurred()), this, SLOT(Slot_errorProcess()));//产生错误 disconnect(&m_Process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(Slot_finishedProcess(int, QProcess::ExitStatus)));//进程完成 connect(&m_Process, SIGNAL(readyRead()), this, SLOT(Slot_readData()));//读就绪 connect(&m_Process, SIGNAL(readyReadStandardOutput()), this, SLOT(Slot_readData()));//标准读就绪 connect(&m_Process, SIGNAL(errorOccurred()), this, SLOT(Slot_errorProcess()));//产生错误 connect(&m_Process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(Slot_finishedProcess(int, QProcess::ExitStatus)));//进程完成 }

如果是在类的构造函数中,定义QProcess 的信号槽。那么QProcess 第二次启动时,信号槽就失效了。 因为QProcess 的主体变了。‘所以每次有新的进程需要启动,都需要手动disconnect和connect一次 保存QProcess 每次都正确连上了信号槽

坑二: disconnect(&m_Process, SIGNAL(readyReadStandardError()), this, SLOT(Slot_readErrorData()));//错误就绪 connect(&m_Process, SIGNAL(readyReadStandardError()), this, SLOT(Slot_readErrorData()));//错误就绪 void xx::Slot_readErrorData() { QByteArray qbt = m_Process.readAllStandardError(); QString msg = QString::fromLocal8Bit(qbt); ui.textBrowser->append(msg); }

如果不加readyReadStandardError 相关操作,下面的信息就收不到:

Traceback (most recent call last): File "./semi/tools/train_ad.py", line 99, in AttributeError: module 'jcutils.base' has no attribute 'savepath' 坑三 实时显示

QT QProcess 使用及实时输出回显 网上都说 加 fflush(stdout) 但是我不管用,后来在被调用的pytho程序里 每一行print 后面后刷新一遍缓存,QProcess 就能实时显示了



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3