长葛住房和城乡建设局网站,wordpress设计模式,响应式网站怎么样,wordpress 如何使用html5游戏关键字#xff1a;GPT4、QProcess、FindWindowEx、Qt 、嵌入 文章目录 前言调用外部程序关于 QProcess 嵌入到主程序显示FindWindowEx FindWindowFindWindowFindWindowEx使用场景 结束 前言
今天计划是稍微研究一下Qt的多进程编程#xff0c;因为最近的程序感觉有点慢…关键字GPT4、QProcess、FindWindowEx、Qt 、嵌入 文章目录 前言调用外部程序关于 QProcess 嵌入到主程序显示FindWindowEx FindWindowFindWindowFindWindowEx使用场景 结束 前言
今天计划是稍微研究一下Qt的多进程编程因为最近的程序感觉有点慢还有一个严重的问题就是会触发Windows的GDI限制所以计划把程序分成几个进程来搞变相的提高程序的性能多多几个GDI。 因为之前是搞过嵌入程序的不过哪个是用的别人提供的SDK库我只需要给他一个句柄来接他的UI即可所以没有深入了解今天需要我自己搭建一个框架出来。
调用外部程序
首先如果想把程序嵌入进来那我们就得先把程序启动了不然就加载个空气进来了所以这里先研究一下怎么启动一个进程。因为项目式理线开发所以这里咱直接用GPT生成一段代码
#include QProcess
#include QDebug// ...QProcess *process new QProcess(this); // this 指定父对象以便自动回收资源
QString program 外部程序的路径; // 比如 notepad.exe// 启动外部程序
process-start(program);// 等待程序启动完成或超时
if (!process-waitForStarted()) {qDebug() 外部程序启动失败 process-errorString();return;
}// 发送数据到外部程序的标准输入如果需要
// process-write(一些输入数据\n);// 等待程序执行完成或超时
if (!process-waitForFinished()) {qDebug() 外部程序执行失败 process-errorString();return;
}// 读取外部程序的标准输出和标准错误输出
QString standardOutput process-readAllStandardOutput();
QString standardError process-readAllStandardError();delete process; // 如果没有指定父对象记得手动删除以避免内存泄漏// 打印输出结果
qDebug() 标准输出 standardOutput;
qDebug() 标准错误 standardError;
关于 QProcess
QProcess 类是属于 Qt 框架中的一个类用于启动和管理外部程序的执行。它允许你的 Qt 应用程序来控制其他程序并且与它们通过标准输入输出进行交互这非常有用于那些需要从其他应用程序接收数据或者向其发送数据的情况。
以下是 QProcess 类的一些基本功能
启动外部程序你可以指定程序名称和所需的参数来启动一个程序。读取和写入数据你可以通过程序的标准输入、输出和错误输出流来与之交互。这意味着你可以发送命令给进程或读取其输出结果。同步或异步操作QProcess 可以同步运行阻塞当前线程直到外部程序完成执行或者异步运行在独立的线程中执行不干扰当前线程的执行流程。信号和槽机制作为一个 QObject 的子类QProcess 使用 Qt 的信号和槽机制。例如你可以连接到 finished 信号以获取当外部程序完成时的通知或者连接到 readyRead 信号来读取可用的数据。处理程序输出QProcess 提供了多种方法来读取程序的标准输出和错误输出包括readAllStandardOutput和readAllStandardError。错误处理QProcess 也能提供关于启动或运行过程中发生错误的信息。
下面是一个简单的例子展示了如何使用 QProcess 来运行一个外部的 ping 命令
#include QProcess
#include QDebugint main(int argc, char *argv[])
{QCoreApplication app(argc, argv);QProcess pingProcess;pingProcess.start(ping, QStringList() -c 4 www.example.com);QObject::connect(pingProcess, QProcess::finished, [](int exitCode) {qDebug() Process finished with exit code exitCode;app.quit();});QObject::connect(pingProcess, QProcess::readyReadStandardOutput, []() {qDebug() pingProcess.readAllStandardOutput();});QObject::connect(pingProcess, QProcess::readyReadStandardError, []() {qDebug() pingProcess.readAllStandardError();});return app.exec();
}在这个例子中QProcess 用来运行 ping 命令并打印出结果。当 ping 命令结束后程序也随之退出。这个程序还演示了如何连接信号到一个 lambda 表达式这允许你直接在信号槽连接中写入处理代码。
嵌入到主程序显示
这里就要说一下GPT了开始用的GPT3 后面换成了GPT4 还是一样一下午都开始怀疑这路子是否可以行的通了最终还是一步一步Debug发现问题。我们看下 GPT 的答案: 在Qt中如果你想嵌入一个外部程序的窗口到你的Qt应用程序中你需要获取外部程序窗口的句柄HWND在Windows中并且将其设置为你的Qt窗口的子窗口。这通常涉及到Windows API的调用因此这种方法是平台依赖的。
以下是一个在Windows平台上嵌入外部程序窗口至Qt应用程序中的基本示例
首先你需要启动一个外部程序并得到它的进程ID。然后使用Windows API来查找窗口句柄并将其嵌入。
以下是示例代码
#include QProcess
#include QtWidgets
#include windows.hclass MyWidget : public QWidget {
public:MyWidget(QWidget *parent nullptr) : QWidget(parent) {// Start the external applicationQProcess *process new QProcess(this);process-start(notepad.exe);// Wait for the process to startprocess-waitForStarted();// Now we need to find the window handleHWND hwnd 0;while (!hwnd) {hwnd FindWindowEx(0, hwnd, Notepad, NULL);if (hwnd) {// Embed the windowSetParent(hwnd, (HWND)this-winId());// Optionally resize the embedded window to fill the parent widgetSetWindowPos(hwnd, 0, 0, 0, this-width(), this-height(), SWP_NOZORDER);}Sleep(10); // Prevents freezing}}protected:// Overriding the resize event to resize the embedded window as wellvoid resizeEvent(QResizeEvent *event) override {QWidget::resizeEvent(event);// Resize the embedded window to fill the parent widgetHWND hwnd FindWindowEx(0, 0, Notepad, NULL);if (hwnd) {SetWindowPos(hwnd, 0, 0, 0, width(), height(), SWP_NOZORDER);}}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);MyWidget widget;widget.show();return app.exec();
}在这个例子中我们启动了记事本程序notepad.exe并且尝试获取它的窗口句柄。一旦我们得到窗口句柄我们就调用SetParent来把记事本的窗口嵌入到我们的Qt窗口中并且通过SetWindowPos函数调整窗口大小。
请注意这个方法并不是通用的因为它依赖于外部程序的窗口类名本例中为Notepad和标题这些信息可能会在不同版本的Windows或不同的应用程序中有所不同。此外由于这种方法依赖于Windows API它只适用于Windows平台。
此外这种方法也可能会遇到安全限制特别是在Windows Vista及以后的操作系统版本中因为嵌入的窗口可能属于不同的进程。这可能需要调整UIPI用户界面特权隔离设置。
对于跨平台的Qt应用程序可能需要寻找其他方法或考虑是否必须嵌入外部程序。
不知道你有没有发现有问题的地方
FindWindowEx FindWindow
FindWindow 和 FindWindowEx 是 Windows API 中的函数用于在桌面上查找窗口但它们在功能上有所不同。
FindWindow
FindWindow 函数用于查找顶级窗口其类名和窗口名与指定的字符串匹配。这个函数不搜索子窗口。调用 FindWindow 时你可以指定完整的窗口类名或窗口标题或者两者都指定也可以只指定其中之一另一个参数设为 NULL。
函数原型如下
HWND FindWindow(LPCSTR lpClassName, // 窗口类名LPCSTR lpWindowName // 窗口标题
);如果函数成功返回值是目标窗口的句柄如果未找到符合条件的窗口返回 NULL。
FindWindowEx
FindWindowEx 函数用于查找子窗口它不仅可以查找顶级窗口还可以查找子窗口其功能比 FindWindow 更加灵活。使用 FindWindowEx 时你可以指定父窗口句柄从而在特定父窗口的子窗口中进行搜索。此外你还可以通过传递前一个兄弟窗口的句柄来继续搜索。
函数原型如下
HWND FindWindowEx(HWND hWndParent, // 父窗口句柄HWND hWndChildAfter, // 子窗口句柄LPCSTR lpszClass, // 窗口类名LPCSTR lpszWindow // 窗口标题
);hWndParent 参数是父窗口的句柄hWndChildAfter 参数是子窗口的句柄函数会从该子窗口后开始搜索。如果 hWndChildAfter 是 NULL搜索从 hWndParent 的第一个子窗口开始。如果 hWndParent 和 hWndChildAfter 都是 NULL那么 FindWindowEx 会搜索任何顶级窗口以及消息窗口。
FindWindowEx 的返回值和 FindWindow 一样找到的窗口句柄或者 NULL。
使用场景
当你只需要查找顶级窗口时使用 FindWindow 即可。当你需要在已知的父窗口中查找子窗口或者需要在同一父窗口的子窗口间进行顺序查找时使用 FindWindowEx。
两者都是通过类名和窗口名进行匹配查找但是 FindWindowEx 提供了更精细的控制允许你对窗口的层级关系和搜索顺序进行精确的指定和遍历。 按照解释是没有任何问题但是当我使用 FindWindowEx 找到的始终都是空不得不转而使用 FindWindow
结束
到这里就基本走通了如果你在开发中也遇到了找不到窗口的问题而碰巧你也用了 FindWindowEx那你不妨试一下 FindWindow 。