問題描述
我正在嘗試使用 Qt 為要在 Windows 命令行中運行的現有應用程序設置 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,我能夠通過來自 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的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!