多進程界面開發-Qt試玩兒

来源:https://www.cnblogs.com/swarmbees/archive/2019/06/28/11100513.html
-Advertisement-
Play Games

[TOC] 一、概述 做客戶端開發已經有好幾個年頭了,今天看到同事發了一篇關於富途牛牛的文章,核心思想就是想說,新版本的富途支持多進程架構了,效率大大提升啦,可以更好的適應多核CPU,提高軟體運行效率。 聽到這個消息,我不僅感嘆,我靠,真的好牛逼。 但是心裡又在默默的想,這個東西到底有什麼好處,多進 ...


目錄

一、概述

做客戶端開發已經有好幾個年頭了,今天看到同事發了一篇關於富途牛牛的文章,核心思想就是想說,新版本的富途支持多進程架構了,效率大大提升啦,可以更好的適應多核CPU,提高軟體運行效率。

聽到這個消息,我不僅感嘆,我靠,真的好牛逼。

但是心裡又在默默的想,這個東西到底有什麼好處,多進程寫界面!!!從來沒這麼搞過呀,會不會有坑,到底比多線程好在了哪裡?帶著這個問題,從百度上看了幾篇相關文章,其中一些是線程和進程的區別文章,而更多的還是關註多進程界面怎麼去開發。

資料真是少的可憐,而且都不是特別全面。所以自己打算深入的寫寫這方面的東西

其實很早以前就接觸過多進程,只是自己好像也沒有想那麼多,一直對多進程架構的概念不是那麼清晰。今天和同事聊了一些相關話題,感覺自己的知識面豁然開朗,要學習的東西好像還挺多。

看下麵這張圖,是任務管理器的應用截圖,以前還真是沒發現,居然我自己用的這麼多應用都是多進程架構的。

我們平時最常用的Chrome瀏覽器,客戶端版本微信,還有有道雲筆記等等






有了這麼多的多進程架構開發的客戶端軟體,難道說多進程開發已經是勢在必行了?

說這麼多,還不如來點兒實際的乾貨,這篇文章是我初步開始使用多進程開髮端產品的嘗試,有不對的地方歡迎大家指出,可以給出更好建議

二、效果展示

下麵是我做的一個demo程式截圖,測試程式中一共包含了4個使用場景,分別是:

  1. Qt嵌入系統自帶電腦
  2. Qt嵌入系統自帶記事本
  3. Qt調用系統ping命令,並收集結果
  4. Qt嵌入其他Qt可執行程式

大家可以先看看效果圖,如果覺著有價值的可以繼續往下看,下麵我會分章節把四個事例進行講解。

三、使用方法

首先需要清楚,我們是多進程界面開發,那麼我們的exe啟動後,勢必是需要啟動其他可執行程式的,並且把其他進程的界面嵌入到我們的視窗中來,代碼執行流程可能像這樣。

1、啟動外部進程

啟動外部進程有多種方式,Qt使用比較習慣的同學可以直接使用QProcess類,這個類是Qt封裝的一個跨平臺的類。

啟動方式可能像下麵這樣

QProcess * myProcess = new QProcess(this);
QStringList arguments;
myProcess->start("C:/Windows/System32/notepad.exe");
myProcess->waitForFinished(2000);

除過QProcess之外,Windows系統上我們還可以使用CreateProcess方法來創建進程。

QString cmd = "C:/Windows/system32/calc.exe";
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = true;

bool bRet = CreateProcess(
    NULL,
    (LPWSTR)cmd.toStdWString().c_str(),
    NULL,
    NULL,
    FALSE,
    CREATE_NEW_CONSOLE,
    NULL,
    NULL, &si, &pi);

2、創建Qt視窗

外部進程啟動後,我們可以在任務管理器中找到啟動的進程

接著我們需要使用SPY++工具進行查看外部進程的類名稱和視窗名稱,並使用FindWindow介面進行查找,找到這個進程的主視窗句柄後,嵌入到我們的程式中來。

類名和視窗名稱查找過程可以參考外部進程嵌入到Qt進程界面這篇文章中的內容。

WId wid = (WId)FindWindow(QStringLiteral("Notepad").toStdWString().c_str()
        , QStringLiteral("無標題 - 記事本").toStdWString().c_str());

QWindow * window = QWindow::fromWinId(wid);
if (window)
{
    window->setFlags(window->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint); //這邊可以設置一下屬性

    QWidget * widget = QWidget::createWindowContainer(window, this, Qt::Widget);
}

如上代碼所示,我們如果找到外部進程的主視窗句柄後,就可以使用Qt提供的createWindowContainer這個介面進行創建QWidget,並加入到我們的程式中來。

3、加入到主進程佈局

外部進程被封裝成為一個QWidget後,我們只需要加入到自己的佈局中即可。

ui.verticalLayout_2->addWidget(widget);

接下來我們分別講解不同場景下的多進程界面開發的簡單使用

四、嵌入NotePad

第三小節已經把嵌入其他程式的流程大致說了一遍,這裡我就不在詳細說明瞭,直接給出具體代碼。

代碼中比較關鍵的有2個地方

  1. QProcess不能使用臨時變數,要不然函數執行完畢notepad.exe進程也就退出了。
  2. FindWindow的兩個參數,一個是類名,一個視窗標題欄名稱,這兩個信息都可以用個SPY++進行查找。
void EmbedCalculate::on_pushButton_2_clicked()
{
    //創建進程
    QString cmd = "C:/Windows/System32/notepad.exe";

    QProcess * myProcess = new QProcess(this);
    QStringList arguments;
    myProcess->start(cmd);
    myProcess->waitForFinished(2000);

    WId wid = (WId)FindWindow(QStringLiteral("Notepad").toStdWString().c_str()
        , QStringLiteral("無標題 - 記事本").toStdWString().c_str());

    QWindow * window = QWindow::fromWinId(wid);
    if (window)
    {
        window->setFlags(window->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint); //這邊可以設置一下屬性

        QWidget * widget = QWidget::createWindowContainer(window, this, Qt::Widget);

        ui.verticalLayout_2->addWidget(widget);
    }
}

五、調用Ping命令

ping命令使用場景主要是想展示主進程和外部進程是怎樣通信的,雖然這個事例比較簡單,但也算是兩者之間發生了信息交換

子進程在執行完ping一個地址之後,會把得到的結果傳遞給主進程,主進程使用readAll函數全部讀入到主進程中。

void EmbedCalculate::on_pushButton_3_clicked()
{
    //創建進程
    QProcess * myProcess = new QProcess(this);
    connect(myProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished), this, [this, myProcess](int exitCode){
        if (exitCode == 0) {
            QTextCodec * gbkCodec = QTextCodec::codecForName("GBK");
            QString result = gbkCodec->toUnicode(myProcess->readAll());
            ui.textEdit->setText(result);
        }
    });

    //myProcess->start("cmd.exe", QStringList() << "/c" << "ping www.baidu.com");
    myProcess->start("cmd.exe", QStringList() << "/c" << "ping " + ui.lineEdit->text().trimmed());
    myProcess->waitForFinished(2000);

    ···
}

六、嵌入其他QWidget窗體

雖然這個東西是最後講的,但是這個才是重頭戲,有了這個實驗之後,我們以後的Qt多進程界面開發也可以進行投入正式環境了。

如下所示,ChildWidget外部程式的主窗體被我們嵌入到了EmbedCalculate這個進程的主界面上,突然覺著好神奇,給自己點贊,哈哈哈哈。

由於我這裡的ChildWidget外部程式和EmbedCalculate主程式在一個目錄中,因此cmd變數直接就指向了ChildWidget這個外部程式的名稱。

其他部分的代碼基本上就和前邊幾種使用場景差不多。

void EmbedCalculate::on_pushButton_4_clicked()
{
    //創建進程
    QString cmd = "ChildWidget.exe";

    QProcess * myProcess = new QProcess(this);
    QStringList arguments;
    myProcess->start(cmd);
    myProcess->waitForFinished(2000);

    WId wid = (WId)FindWindow(QStringLiteral("Qt5QWindowIcon").toStdWString().c_str()
        , QStringLiteral("ChildWidget").toStdWString().c_str());

    QWindow * window = QWindow::fromWinId(wid);
    if (window)
    {
        window->setFlags(window->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint); //這邊可以設置一下屬性

        QWidget * widget = QWidget::createWindowContainer(window, this, Qt::Widget);

        ui.verticalLayout_3->addWidget(widget);
    }
}

七、相關文章

外部進程嵌入到Qt進程界面


以上的內容,基本上就是本篇文章的內容所有內容啦!初步完成了qt內嵌其他進程界面的功能,希望可以幫到大家。




很重要--轉載聲明

  1. 本站文章無特別說明,皆為原創,版權所有,轉載時請用鏈接的方式,給出原文出處。同時寫上原作者:朝十晚八 or Twowords

  2. 如要轉載,請原文轉載,如在轉載時修改本文,請事先告知,謝絕在轉載時通過修改本文達到有利於轉載者的目的。



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 現在越來越多的項目就算是一個管理後端也偏向於使用前後端分離的部署方式去做,為了順應時代的潮流,一前後端分離就產生了跨域問題,所以許多同學把跨域和前後端分離項目聯繫在了一起,其實跨域產生的原因並不是前後端分離導致的,那我們一起來看一下,希望可以靠這一篇文章解答大家所有的跨域問題 一、跨域產生的條件 使 ...
  • 背景介紹 上篇介紹了利用Nginx反向代理實現負載均衡,本文詳細講述Nginx下的幾種負載均衡策略。 輪詢 輪詢,顧名思義,就是輪流請求,基於上篇文章的介紹,我們將負載均衡策略聚焦於 文件的 。 在瀏覽器中對 連續發出請求,根據nginx請求日誌可以看出web02與web03訪問的次數是相同的。 加 ...
  • 1、簡介 SOA(Service Oriented Architecture)“面向服務的架構”:他是一種設計方法,其中包含多個服務, 服務之間通過相互依賴最終提供一系列的功能。一個服務 通常以獨立的形式存在與操作系統進程中。各個服務之間 通過網路調用。 2、和微服務對比 微服務架構其實和 SOA ...
  • MTDDL 美團分散式數據訪問中間件(轉) "原文地址:MTDDL——美團點評分散式數據訪問層中間件" 因原文文字和圖顯示有問題,故整理於此,僅供參考。 業界方案 | 組件 | 簡介 | | : : | : | | Atlas | Qihoo 360開發維護的一個基於MySQL協議的數據中間層項目。 ...
  • 適配器主要用於介面的轉換或者將介面不相容的類對象組合在一起形成對外統一介面,是一種結構性模式,其本質是是一個中間件,適用於類及其對象。本文希望通過簡單的介紹和分析,能讓讀者對適配器模式有一個簡單直觀的認識和感知。 1.目的 對現有的類的介面進行轉換以符合新的需求。 2.動機 通過轉換或者組合,間接復 ...
  • CDN加速靜態文件訪問 全局調度 緩存技術 內容分發 帶寬優化 CDN是Content Delivery Network的縮寫,意思是內容分髮網絡。CDN的作用是把用戶需要的內容分發到離用戶近的地方,這樣可以使用戶 能夠就近獲取所需內容。 整個CDN系統(如圖1-1所示)分為CDN源站和CDN節點, ...
  • 3.3 如何從ubuntu或PC傳遞文件到板子,ubuntu如何上網? 答:以下將分別介紹如何在ubuntu和windows下如何傳遞文件。 ubuntu如何配置上網?ubuntu 上網:打開Oracle VM VirtualBox(虛擬機軟體,筆者以此軟體為例,也可用其他虛擬機軟體)管理器中的設置 ...
  • 編者註:前段時間筆者在團隊內部分享了sentinel原理設計與實現,主要講解了sentinel基礎概念和工作原理,工作原理部分大家聽了基本都瞭解了,但是對於sentinel的幾個概念及其之間的關係還有挺多同學有點模糊的,趁著這幾天比較空,針對sentinel的幾個核心概念,做了一些總結,希望能幫助一 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...