在Windows上为现有的基于控制台的应用程序创建QT应用程序作为GUI的GUI [英] Creating QT Application as GUI for existing console-based application on windows
问题描述
我正在尝试为要在Windows命令行中运行的现有应用程序使用Qt设置GUI。它不仅仅是使用
system()
命令运行应用程序,而且我还需要通过命令行与现有应用程序进行交互。
i'm trying to set up a GUI with Qt for an existing application which is meant to be run in the windows commandline. It's not just running the app with the
system()
command, but i need to interact with the existing application via command line.
当我启动现有的可执行文件时, system()
命令会阻塞GUI。如何在后台运行此可执行文件并通过自己的GUI元素(例如按钮)触发一些输入?
The system()
command blocks the GUI when i start the existing executable. How can i run this executable in the background and trigger some inputs via my own GUI-Elements such as a button?
我想为我的一些同事简化此命令行工具的用法。
I want to simplify the usage of this command line tool for some of my colleagues.
它主要用于Windows。
It would be mainly used on windows.
感谢您的帮助。
推荐答案
我找到了解决方案我的需求,可以做我想做的事。.实际上,我有点失望。我认为这会更复杂。
I found a solution for my needs and can do what i want to do.. Actually i'm a bit disappointed. I thought it would be something more complex.
首先我必须说这是一个QtQuick应用程序。也许我应该早一点说。
First i have to say it's an QtQuick Application .. Maybe i should have said that earlier.
我只是将过程函数外包给另一个类。此类通过 qmlRegisterType<>()
函数传递给QML。我将来自进程( QProcess
)的一些信号连接到我自己的类中的插槽中,并编写了自己的函数来处理从控制台应用程序读取数据或向控制台应用程序写入数据。通过QML- onClicked
事件,我可以将参数和字符串传递给控制台应用程序。借助某些应用程序逻辑,我可以处理输入/输出请求和计时。
I simply outsourced the process functions to another class. This class is passed to QML via the qmlRegisterType<>()
function. I connected some signals from the process ( QProcess
) to slots in my own class and wrote my own functions to handle reading/writing data from and to the console application. With the QML-onClicked
events i can pass my parameters and strings to the console app. And with some application logic i can handle the in/out requests and timings.
WrapperClass.h
class WrapperClass: public QObject
{
Q_OBJECT
public:
explicit WrapperClass(QObject *parent = nullptr);
QProcess *process;
QString str_proc_output;
Q_INVOKABLE void startProcess();
Q_INVOKABLE void stopProcess();
Q_INVOKABLE QString getOutput();
Q_INVOKABLE void writeByte(QString str);
Q_INVOKABLE QString getAllOutput();
private:
signals:
public slots:
void mReadyRead();
void mReadyReadStandardOutput();
void mFinished(int code);
void mBytesWritten(qint64 written);
};
WrapperClass.cpp
WrapperClass::WrapperClass(QObject *parent) : QObject(parent)
{
process = new QProcess();
process->setProgram("untitled.exe");
process->setProcessChannelMode(QProcess::MergedChannels);
str_proc_output = "";
connect(process, SIGNAL(readyRead()), this, SLOT(mReadyRead()));
connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(mReadyReadStandardOutput()));
connect(process, SIGNAL(finished(int)), this, SLOT(mFinished(int)));
connect(process, SIGNAL(bytesWritten(qint64)), this, SLOT(mBytesWritten(qint64)));
}
void WrapperClass::startProcess() {
if(process->state() == QProcess::Running) {
stopProcess();
} else {
process->open(QProcess::ReadWrite);
}
}
void WrapperClass::stopProcess() {
process->close();
}
QString WrapperClass::getOutput() {
return str_proc_output;
}
QString WrapperClass::getAllOutput() {
QString str = process->readAll();
std::cout << str.toStdString() << std::endl;
return str;
}
void WrapperClass::writeByte(QString str) {
char cArr[str.length()] = {};
memcpy(cArr, str.toStdString().c_str(), str.length());
QByteArray arr = QByteArray(cArr, -1);
process->write(arr);
}
void WrapperClass::mReadyRead() {
QString s = QString(process->readAll());
std::cout << "ReadyRead: " << s.toStdString() << std::endl;
str_proc_output = s;
}
void WrapperClass::mReadyReadStandardOutput() {
QString s = QString(process->readAllStandardOutput());
std::cout << "ReadyReadStandardOutput: " << s.toStdString() << std::endl;
}
void WrapperClass::mFinished(int code) {
std::cout << "Process finished! (" << code << ')' << std::endl;
}
void WrapperClass::mBytesWritten(qint64 written) {
std::cout << "Bytes written: " << written << std::endl;
}
Main.cpp
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<WrapperClass>("com.example.WrapperClass", 0, 1, "WrapperClass");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
通过将Cpp-Class注册到QML,我可以触发读取/ write函数通过QML- MouseArea
或 Button
中的Click-Events实现。
With registering the Cpp-Class to QML i'm able to trigger the read/write functions via Click-Events from QML-MouseArea
or Button
.
这篇关于在Windows上为现有的基于控制台的应用程序创建QT应用程序作为GUI的GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!