应用场景与问题描述
:
问题是这样的,我写了很多命令行程序用于处理遥感影像,这种方式很方便,可以通过dos或shell脚本来实现批处理。但这也引起一个问题,当我在集成时偷懒,不想做界面,而用户又必须要求有个界面时,我不得不做一个窗口来体现我是有界面的,于是我决定直接调用我的可执行程序或者批处理脚本,但这些命令和脚本不能在终端或dos窗口里执行。这个问题简单的抽象为执行一个"ping localhost"的命令,并且把输出重定向到我的消息窗口里。
我们习惯于先看看别人有没有做过这个事,于是先百度一下,就直接看到这篇博客:
点击打开链接
,参照这个博客的例子,我做了如下的实验:
#ifndef QTWINMSG_H
#define QTWINMSG_H
#include <QtWidgets/QMainWindow>
#include "ui_qtwinmsg.h"
#include "Worker.h"
class QtWinMsg : public QMainWindow
Q_OBJECT
public:
QtWinMsg(QWidget *parent = 0);
~QtWinMsg();
public slots:
void onTest();
private:
Ui::QtWinMsgClass ui;
#endif // QTWINMSG_H
#include "qtwinmsg.h"
#include <QMessageBox>
#include <conio.h>
#include <stdio.h>
#include <windows.h>
QtWinMsg::QtWinMsg(QWidget *parent)
: QMainWindow(parent)
ui.setupUi(this);
ui.lineEdit->setText(tr("ping localhost"));
ui.textEdit->setLineWrapMode(QTextEdit::NoWrap);
connect(ui.pushButton,SIGNAL(clicked()),this,SLOT(onTest()));
QtWinMsg::~QtWinMsg()
void QtWinMsg::onTest()
QString qsCmd = ui.lineEdit->text();
QByteArray qbCmd = qsCmd.toLocal8Bit();
char* pszCmd = qbCmd.data();
LPWSTR ppCmd = new TCHAR[100];
LPSTR p = pszCmd;
MultiByteToWideChar(CP_ACP, 0, p, -1, ppCmd, 100);
SECURITY_ATTRIBUTES sa;
HANDLE hRead,hWrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0))
return ;
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
//关键步骤,CreateProcess函数参数意义请查阅MSDN
if (!CreateProcess(NULL, ppCmd
,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
return ;
CloseHandle(hWrite);
char buffer[4096] = {0};
DWORD bytesRead;
//ofstream outfile("log.txt");
while (true)
if (ReadFile(hRead,buffer,4095,&bytesRead,NULL) == NULL)
break;
//buffer中就是执行的结果,可以保存到文本,也可以直接输出
//printf(buffer);
//outfile << buffer << endl;
//Sleep(1000);
QString qsMsg = QString::fromLocal8Bit(buffer);
ui.textEdit->append(qsMsg);
this->update();
//outfile.close();
运行效果:
这样可以实现目标,但是在Qt程序里使用了Win32 API,这是有点别扭,另外输出的消息并不是动态的输出,而是在执行完毕后一下子刷出来,即使我们通过QThread,把处理过程放到其它线程里,然后通过异步的事件来刷新消息输出也是实现不了动态消息效果。总体来说,这种方式是不完美的。
我想Qt应该有自己的方式。通过查看Qt的帮助,很快就可以找到做这个事情的类QProcess,QProcess可以同于执行外部程序和命令,并且支持消息重定向和标准输入、输出,有了QProcess类,前面讲到的问题就可以简单的通过下面的方式来实现了:
#ifndef TEST2_H
#define TEST2_H
#include <QWidget>
#include <QProcess>
#include "ui_Test2.h"
class Test2 : public QWidget
Q_OBJECT
public:
Test2(QWidget *parent = 0);
~Test2();
public slots:
void onTest();
void onOutput();
private:
Ui::Test2 ui;
QProcess *m_Process;
#endif // TEST2_H
#include "Test2.h"
#include <QTextEdit>
Test2::Test2(QWidget *parent)
: QWidget(parent),m_Process(new QProcess)
ui.setupUi(this);
ui.lineEdit->setText(tr("ping localhost"));
ui.textEdit->setLineWrapMode(QTextEdit::NoWrap);
m_Process->setProcessChannelMode(QProcess::MergedChannels);
connect(ui.pushButton,SIGNAL(clicked()),this,SLOT(onTest()));
connect(m_Process,SIGNAL(readyReadStandardOutput()),this,SLOT(onOutput()));
Test2::~Test2()
m_Process->terminate();
void Test2::onTest()
QString qsCmd = ui.lineEdit->text();
m_Process->start( qsCmd);
void Test2::onOutput()
QByteArray qbt = m_Process->readAllStandardOutput();
QString msg = QString::fromLocal8Bit(qbt);
ui.textEdit->append(msg);
ui.textEdit->update();
运行效果:
应用场景与问题描述:问题是这样的,我写了很多命令行程序用于处理遥感影像,这种方式很方便,可以通过dos或shell脚本来实现批处理。但这也引起一个问题,当我在集成时偷懒,不想做界面,而用户又必须要求有个界面时,我不得不做一个窗口来体现我是有界面的,于是我决定直接调用我的可执行程序或者批处理脚本,但这些命令和脚本不能在终端或dos窗口里执行。这个问题简单的抽象为执行一个"ping localhost...
获取文件单行内容类似于获取一个数组中的某个元素内容,把需要调用的数据、指令写入一个文件中可以减轻代码量,也方便外人管理。话不多说,主要代码如下:首先创建一个.txt文件,并输入你要调用的内容然后创建qt项目,ui界面设置如下: 在.h中添加相应头文件
在.cpp中
最终运行结果如下:...
目录一、项目介绍二、项目基本配置三、UI界面设计四、主程序实现4.1 widget.h头文件4.2 widget.cpp源文件五、效果演示
一、项目介绍
利用QProcess类实现启动进程的功能进阶(以dos命令dir为例)。
二、项目基本配置
新建一个Qt案例,项目名称为“ProcessTest”,基类选择“QWidget”,点击选中创建UI界面复选框,完成项目创建。
三、UI界面设计
UI界面布局如下:
界面中只创建了1个控件,其名称和类型如下:
HEADERS #头文件
FORMS #用到的ui文件(ui文件时用QT设计器生成的)
INCLUDEPATH #这个用来指定头文件路径, 例如:INCLUDEPATH += ./mitab
LIBS #加载动态库。例如:LIBS += ./mitab/libmita
在.pro 文件中添加 Config += console,qt 中将显示控制台窗口,并会将qDebug()中的信息输入到控制台中
等价于 在 项目配置中 ,qmake 额外参数项中加入 "CONFIG+=console",或者如下
qt .pro 工程文件中输出日志 使用message 函数message("ArcGIS Runtime...
在Qt中执行Linux命令可以使用QProcess类。该类允许您启动外部程序并与其进行交互。您可以使用QProcess类来执行Linux命令并获取其输出。以下是一个示例:
QProcess process;
process.start("ls", QStringList() << "-l" << "/home");
process.waitForFinished();
QString output = process.readAllStandardOutput();
qDebug() << output;
在此示例中,我们使用QProcess类启动了一个名为“ls”的外部程序,并向其传递了两个参数:“-l”和“/home”。然后,我们等待该进程完成,并使用readAllStandardOutput()函数获取其输出。最后,我们将输出打印到控制台。
请注意,使用QProcess类执行Linux命令可能会导致安全问题。因此,您应该仅在信任的环境中使用它。