問題描述
我正在嘗試使用 Qt 為要在 Windows 命令行中運(yùn)行的現(xiàn)有應(yīng)用程序設(shè)置 GUI.這不僅僅是運(yùn)行應(yīng)用程序system()
命令,但我需要通過命令行與現(xiàn)有應(yīng)用程序交互.
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.
當(dāng)我啟動(dòng)現(xiàn)有的可執(zhí)行文件時(shí),system()
命令會(huì)阻止 GUI.如何在后臺(tái)運(yùn)行此可執(zhí)行文件并通過我自己的 GUI 元素(例如按鈕)觸發(fā)一些輸入?
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?
我想為我的一些同事簡化這個(gè)命令行工具的使用.
I want to simplify the usage of this command line tool for some of my colleagues.
它主要用于windows.
It would be mainly used on windows.
感謝您的幫助.
推薦答案
我找到了滿足我需求的解決方案并且可以做我想做的事情.. 其實(shí)我有點(diǎn)失望.我認(rèn)為它會(huì)更復(fù)雜.
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.
首先我得說這是一個(gè) QtQuick 應(yīng)用程序 .. 也許我應(yīng)該早點(diǎn)說.
First i have to say it's an QtQuick Application .. Maybe i should have said that earlier.
我只是將流程功能外包給另一個(gè)班級(jí).此類通過 qmlRegisterType<>()
函數(shù)傳遞給 QML.我將來自進(jìn)程的一些信號(hào) ( QProcess
) 連接到我自己類中的插槽,并編寫了自己的函數(shù)來處理從控制臺(tái)應(yīng)用程序讀取數(shù)據(jù)和向控制臺(tái)應(yīng)用程序?qū)懭霐?shù)據(jù).通過 QML-onClicked
事件,我可以將參數(shù)和字符串傳遞給控制臺(tái)應(yīng)用程序.通過一些應(yīng)用程序邏輯,我可以處理輸入/輸出請(qǐng)求和時(shí)間.
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 注冊(cè)到 QML,我能夠通過來自 QML-MouseArea
或 Button
的 Click-Events 觸發(fā)讀/寫功能.
With registering the Cpp-Class to QML i'm able to trigger the read/write functions via Click-Events from QML-MouseArea
or Button
.
這篇關(guān)于為 Windows 上現(xiàn)有的基于控制臺(tái)的應(yīng)用程序創(chuàng)建 QT 應(yīng)用程序作為 GUI的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!