12.QT + OpenCV打包成應用(以及QT圖示問題詳細) --- OpenCV從零開始到影象(人臉 + 物體)識別系列
本文作者:小嗷
微信公眾號:aoxiaoji
關鍵詞:QT + OpenCV打包成應用(接著第11篇)
QT開發的程式釋出的時候經常採用兩種方式:
- 靜態編譯,可生成單一的可執行檔案。
- 動態編譯,需同時附上需要的dll檔案。
不管採用哪種方式,首先我們要把專案的釋出做一些準備,例如:準備程式的圖示,將專案編譯成release等(當我應用搞成功,我老是想搞的盡善盡美,想搞個好看的應用圖片,可惜不是美工,無奈無聊)。
2.1 設定主視窗圖示(為啥重點寫圖示?網上基本寫給自己看,為此小嗷進坑到爬坑耗時1.5小時)
首先在繪圖工具(例如Photoshop)中設計好圖示,圖示的解析度最好大於32*32。圖示需要用*ico或*png的檔案。如果想偷懶一點,直接去這裡(
將剛才的生成的圖示檔案放到yourProjectFolder/Resources/images目錄下,或者任意一個程式可以找到的位置。
選擇QtFirstMat.qrc -> 開啟方式 -> XML開啟(不貼圖,不懂參考第11章相關圖片)
最好將圖示檔案新增到qrc中統一管理,qrc檔案的格式如下:
<RCC> <qresource prefix="/QtFirstMat"> <file alias="mainlogo">Resources/image/icon1.png</file> </qresource> </RCC>
- alias為icon資源的特徵字元,prefix(字首)為標示符,你喜歡怎麼寫就怎麼寫,當我們使用icon圖片資源,我們要寫成QStringLiteral(“:/QtFirstMat/mainlogo”))
- Resources/image/icon1.png為圖片資源地址
然後再主視窗中使用,程式碼如下,程式碼很簡單,不過記住這句程式碼一定要放到Mainwindow的建構函式裡去,不然不會work。(就是main呼叫主窗體cpp)
#include "QtFirstMat.h" QtFirstMat::QtFirstMat(QWidget *parent) : QWidget(parent) { setWindowIcon(QIcon(QStringLiteral(":/QtFirstMat/mainlogo"))); ui.setupUi(this); }
程式執行後的效果如下:
2.2 QT自帶新增資原始檔
雙擊QtFirstMat.qrc -> 更改Prefix為/QtFirstMat(任意名字) -> 點選add -> add Files -> 選擇圖片 -> 雙擊資原始檔 -> 寫一下標誌符文字(喜歡怎麼寫就怎麼寫,1/2/3)
實在不懂就QQ/QQ郵箱/公眾號我,謝謝,有時間就會
2.3 設定執行程式的圖示
設定執行程式的圖示在各個平臺是各不相同的,下面分別介紹。首先準備解析度最好大於32*32的圖示檔案。圖示需要用*ico的檔案。
(1) Windows平臺
(1)使用Visual Studio IDE開發工具
如果使用的是VisualStudio IDE開發工具,例如在VS2015中,專案上右擊,新增,資源,選擇icon,然後將之前準備的*ico圖示檔案匯入,確定之後專案中就會出現一個 projectname.rc 的檔案。
(2)使用QTCreator的IDE開發工具
如果你是使用qmake生成makefile檔案或使用QT Creator IDE,那麼按下面三步實施:
第一步:建立一個包含圖示影象的ICO檔案,並將其儲存在資原始檔目錄下,例如命名為:myapp.ico;
第二步:建立一個.rc檔案,包含如下內
IDI_ICON1 ICONDISCARDABLE “myapp.ico”
第三步:在工程檔案myapp.pro檔案中寫入如下內容:
RC_FILE = myapp.rc
再次編譯程式,即可達到效果,效果圖如下:
再次編譯程式,即可達到效果,效果圖如下:
(3)Mac OS X平臺
雖然許多程式可以建立圖示檔案(.icns),推薦的方法是使用由蘋果公司提供的程式iconutil。Iconutil是一個命令列工具,它允許您匯入多個不同大小的圖示(在不同的上下文中使用),並能壓縮檔案。在您的專案目錄中將所有一系列的圖示儲存在一個檔案中。
如果您正使用qmake生成makefile檔案,您只需要將一個單一的行新增到您的.pro工程檔案。例如,如果您的圖示檔案的名稱是myapp.icns,並且您的專案檔名稱是myapp.pro,加入這一行到myapp.pro:
ICON = myapp.icns
這將確保qmake把你的圖示放在適當的位置併為圖示建立一個Info.plist條目。
如果你不使用qmake,你必須手動執行以下幾點:
1) 為您的應用程式(使用PropertyListEditor,在Developer/Applications中可以找到)建立一個Info.plist檔案。
2) 在Info.plist檔案(同樣,使用PropertyListEditor)關聯您的.icns記錄和CFBundleIconFile記錄。
3) 將Info.plist檔案複製到你的應用程式包的Contents目錄。
4) 複製.icns檔案到你的應用程式包的Contents/Resoures目錄。
(5)通用的Linux平臺
在本節中,我們簡要地介紹一下在兩種常見的linux桌面環境:KDE和GNOME,為應用程式提供圖示的相關問題 。為這兩種桌面,用來描述應用程式圖示的核心技術是相同的,也可以適用於其他,但具體到每一個來講也有各自的細節。對使用這些Linux桌面系統的標準資訊的主要來源是freedesktop.org。有關其他Linux桌面的資訊,請參閱您感興趣的桌面文件。
通常情況下,使用者不直接使用可執行檔案,而是通過點選桌面上的圖示來啟動應用程式。這些圖示是包含帶有關於它的圖示資訊的應用程式的描述表示的“桌面項” 檔案。這兩種桌面環境都能夠在這些檔案中檢索資訊,並且可以用它們來生成應用程式的快捷方式到桌面上,在開始選單中,或者在面板上。
有關桌面項檔案的更多資訊,可以在Desktop EntrySpecification中找到。
雖然桌面項檔案可以有效地封裝應用程式的詳細資訊,我們仍然需要將圖示儲存在每個桌面環境中的常規位置。用於圖示的一些位置在Icon ThemeSpecification中給出了。
雖然用於定點陣圖標的路徑依賴於在桌面上的使用和它的配置,下面所有這些目錄結構應該遵循相同的模式:子目錄都按照主題,圖示大小和應用程式型別進行組織。 通常,應用程式圖示被新增到高彩主題,因此方形的應用程式圖示的大小為32畫素,它將被儲存在hicolor/32x32/apps目錄的圖示路徑的下方。
(5)K桌面環境(KDE)
應用程式圖示可以被所有使用者或者一個單一的使用者安裝使用。當前登入到他們的KDE桌面的使用者可以通過使用kde-config發現這些位置,例如,通過在終端視窗中鍵入執行下列操作:
kde-config –pathicon
通常情況下,被輸出到stdout的以冒號分隔的路徑列表中包含了使用者特定的圖示路徑和全系統的路徑。下面這些目錄中,可以根據在Icon ThemeSpecification中描述的約定來定位並安裝圖示。
如果您正在專門為KDE開發,你不妨利用KDE build system的優勢來配置您的應用程式。這可以確保你的圖示被安裝在KDE的適當位置。
(6)GNOME
應用程式圖示都儲存在包含與體系結構無關檔案的一個標準全系統目錄下。這個位置可以通過使用gnome-config來確定,例如,通過在一個終端視窗中鍵入以下命令:
gnome-config–datadir
輸出在標準輸出stdout的路徑指的是包含一個名為pixmaps目錄的位置;這個pixmaps目錄中的目錄結構中在Icon ThemeSpecification中進行了描述。
如果您正在專門為GNOME開發,你可能希望使用一組標準的GNU Build Tools,在GTK+/GnomeApplication Development book的相關章節也作了說明。這可以確保你的圖示被安裝在為GNOME中的適當位置。
編譯release版本
注意將執行程式編譯方式設定成Release,因為debug版本的程式中包含了除錯資訊,可以用來除錯。而真正要釋出程式時,要使用release版本,這樣可以減少釋出程式的體積同時增加軟體的安全。
上圖演示在Qt Creator中的設定方式,選中IDE左邊的側邊欄的專案,然後再構建設定中將構建配置設定為Release。
上圖演示在VS2015中的設定方式,選中IDE右邊的解決方案管理器中的專案,然後在IDE上邊的工具欄中將構建配置設定為Release。
安裝QT SDK 後,預設採用的是動態連結庫的編譯方式,如果需要釋出程式,需要在可執行的檔案中新增必須的動態連結庫,然而有些動態連結庫檔案很大,這並不是我們想要的結果。
最好的辦法是提交一個靜態連結的程式。但是安裝的Qt是動態編譯的,要生成靜態的版本,就需要自己重新進行編譯。
3.1 靜態編譯
優點,釋出簡單,單一檔案。
缺點,庫檔案很大,更新程式版本不方便。每次升級,都要重新分發所有的內容。
靜態釋出雖然不需要較多的dll,釋出簡單、方便,但是往往會牽扯到授權問題(詳情請檢視Qt LGPL授權),動態釋出則可以避免。。。如果附帶了Qt的dll,就相當於釋出了Qt的dll,而這些庫是屬於Qt的,這足以保證使用者知道程式使用了LGPL版本的Qt。
3.2 Windows平臺靜態編譯
靜態編譯首先需要將
mingw平臺靜態編譯,在編譯Qt的時候,有個configure.exe程式,
configure.exe-static -platform win32-g++
可以產生靜態編譯專案檔案。然後,
mingw32-makesub-src
就可以編譯出靜態庫。如果只是用來分發程式,也可以mingw32-makerelease sub-src只編譯一個靜態庫。
VC2015平臺,在編譯Qt的時候,configure.exe-static-platform win32-msvc2015
然後nmakesub-src或者nmake release sub-src完成靜態編譯。
再然後,就是把你的程式重新用靜態編譯的Qt再編譯一次。
你會得到一個非常大的可執行程式。推薦使用AspPack壓縮一下。就可以發給使用者了。
3.3 linux平臺靜態編譯
1、下載源安裝程式,如 qt-everywhere-opensource-src-5.5.1.tar.gz
2、解壓到某一目錄
3、cd 進入解壓後的目錄,命令:
./configure-static -release -qt-zlib -qt-gif -qt-libpng -qt-libmng -qt-libjpeg -nomakedemos -nomake examples -qt-sql-sqlite -prefix /usr/local/Trolltech/Qt-5.5.1_static
引數-static 指的是要採用靜態編譯Qt的方法
引數-release指的是隻編譯release版本的庫
引數-qt-zlib -qt-gif-qt-libpng -qt-libmng -qt-libjpeg 是更好確定Qt編譯出的程式能在目前不知的系統下執行。
引數-nomake demos-nomake examples 指的是不編譯demos和examples
引數-qt-sql-sqlite 如果沒有這個引數,configure的時候,可能會提示sqlite 有問題而中止。
引數 -prefix/usr/local/Trolltech/Qt-5.5.1_static 指明靜態編譯的Qt安裝的目錄,命名Qt-5.5.1_static是為了區別動態編譯安裝的Qt,因為如果沒有這個引數,安裝時會覆蓋之前動態編譯安裝的Qt(如果有的話)。
u 注: 如果出現錯誤:Basic XLibfunctionality test failed!
You might need to modify theinclude and library search paths by editing
QMAKE_INCDIR_X11 andQMAKE_LIBDIR_X11
解決辦法:yum installlibX*
(如果是Ubuntu也可執行sudo apt-getinstall libx11-dev libxext-dev libxtst-dev)
4、沒問題後
make
5、make沒問題後再
sudo make install
6、增加(或改變)環境變數: (也可以不新增環境變數,使用絕對路徑進行編譯),在你home目錄下你的的名字的目錄中,在.profile檔案中追加(或改變)如下環境變數:(為Qt設定一些特定的環境變數,這個很重要!.profile檔案是隱藏的,可在你的名字目錄下,按Ctrl+H顯示所有檔案檢視到)
QTDIR=/usr/local/Trolltech/Qt-5.5.1_static/
PATH=PATH
MANPATH=MANPATH
LD_LIBRARY_PATH=LD_LIBRARY_PATH
export QTDIR PATHMANPATH LD_LIBRARY_PATH
7、重啟
8、在終端測試一下qmake
3.4 MAC OS X系統平臺靜態編譯
在MAC OS X系統平臺下靜態編譯QT應用還是比較麻煩的,首先需要靜態編譯QT應用依賴的各個庫,然後再進行連線生成執行檔案,具體步驟參看連結:http://doc.qt.io/qt-5/osx-deployment.html。
3.5 附加Dll檔案
優點,更新方便,釋出多個產品時,可以統一使用一個庫。
缺點,檔案多、雜。
Qt官方開發環境預設使用動態連結庫方式,在釋出生成的可執行程式時,我們需要複製一大堆動態庫,如果自己去複製動態庫,很可能丟三落四,導致程式在別的電腦裡無法正常執行。 因此 Qt 官方開發環境裡自帶了一個部署工具來幫助開發者自動拷貝大部分的依賴庫。在不同的平臺使用方式也有所不同。
3.5.1 Windows平臺
Windows開發環境下windeployqt工具 (如果你已經將Qt的bin目錄加入PATH環境,那麼你可以直接在命令列使用windeployqt呼叫.)。首先,將專案中的release檔案中的可執行檔案拷到一個新建的資料夾中,例如project.exe,用Qt自帶的生成必備的dll檔案的程式windeployqt,來把必要的動態庫拷到該資料夾中,開啟命令列,輸入windeployqtproject.exe,這時候大部分的dll檔案都自動拷貝過來了,但是如果專案還用了一些其他的SDK,比如OpenCV,Chartdir51等等,就需要手動將所需dll拷貝過來,如果不知道還需要哪些軟體,可以用Dependency Walker來檢視缺少哪些dll檔案。
拷貝完成後資料夾下的檔案清單如下:
注意:如果釋出的應用是Qt Quick Application應用,那麼命令列需要加上QML的安裝目錄。如:命令中的D:\Qt\Qt5.5.1\qml是qml的安裝目錄,請換成你自己的qml安裝目錄!!!!!
windeployqt hello.exe–qmldir D:\Qt\Qt5.5.1\qml
注意:缺少dll請使用everything查詢(上網找免費軟體)
3.5.2 匯入OpenCV需要的dll檔案
使用Dependency Walker這個軟體,開啟打包好的exe檔案,在這個軟體中可以找到需要dll的路徑(右鍵點選該軟體的full path) ,網址:http://www.dependencywalker.com/
實在不懂,直接複製opencv全部dll或者聯絡我(謝謝,大佬)
3.5.3 linux平臺
在X11平臺下qt程式,首先準備好程式中需要使用的資源,庫和外掛…,比如你的可執行程式取名叫作panel,那把你的panel,那些libQt*.so.4和libQt*.so.4.6.0(連結和共享庫都要)放在同一目錄下(也可以不同,只要小小修改下shell檔案).plugins就不多說了。
在程式的同目錄下,新建一個空文件,取名panel.sh (檔名與程式名同名,副檔名為sh,shell檔案)。在panel.sh中原封不動的寫入以下語句:
!/bin/sh
appname=
basename $0 | sed s,/.sh$,,
dirname=
dirname$0
tmp=”${dirname#?}”
if [“tmp}” != “/” ]; then
dirname=dirname
fi
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
appname$*
儲存檔案,退出。在終端給檔案+x屬性: 切換到程式的目錄,輸入
chmod +x panel.sh
然後執行shell檔案就行了(確保panel程式具備X屬性),它會自動更改環境變數,執行程式。
如果要除錯shell檔案,只需要在終端輸入:
sh -x panel.sh
這樣就ok了。
如果需要把執行程式製作成DEB或RPM包的話請參考連結:
3.5.4 MAC OS X系統平臺
由於Qt的庫並不是OS X標配的,所以我們要自己去複製庫到app包裡,才可以讓app在其他未安裝Qt的電腦上執行。
比較幸運的是,Qt為我們提供了macdeployqt工具,藉助於此,在OS X上釋出Qt寫的程式幾乎是所有平臺中最簡單的。
注:我電腦配置了Qt的bin環境,所以可以直接使用macdeployqt,如果沒配置,可以用絕對路徑去找。
1.釋出widgets程式
a) 這個比較方便。選擇Release模式,編譯
b) 執行macdeployqt
對於我的工程,命令是:
macdeployqt /Users/Ocean/Desktop/build-untitled-Desktop_5_5_1_64bit-Release/untitled.app-dmg
然後回車,就打包好了。之後我們會發現,app目錄下多了一個dmg檔案
此dmg檔案,裡面的app就是我們釋出的app了。把dmg拷貝給別人,別人就可以直接使用了。
l 注:如果直接拷貝app檔案給別人,別人是無法直接執行的,會有許可權問題(要用chmod給可執行檔案加上x許可權才可以執行)。而壓縮過(zip或者dmg)後,拷貝給別人,別人是可以直接執行,沒有許可權問題。
l 注:-dmg的意思就是在拷貝好庫後,生成一個dmg檔案,可以不加這個引數。
2.釋出quick2程式
這個相對麻煩一點
a) 選擇Release模式,編譯
b) 開啟終端,先切換編譯的目標目錄下
對於我的工程,命令是: cd /Users/Ocean/Desktop/build-untitled-Desktop_5_5_1_64bit-Release
c) 執行macdeployqt
對於我的工程,命令是: macdeployqt untitled.app-qmldir=../untitled -dmg 然後回車,就打包好了。
l 注1:和widgets釋出程式不同,untitled.app 這個名字,要直接輸入,不要寫 ./untitled.app 或者是其他的 絕對/相對 路徑,不然打包出來的檔案無法使用!!會報錯!!!
l 注2:-qmldir=../untitled的意思就是說在../untitled 目錄下有qml檔案,讓macdeployqt去分析它們,把要用的庫找過來。
效果圖
- 本人是抱著玩一玩的心態,學習opencv(其實深度學習沒有外界說的這麼高深,小嗷是白板,而且有工作在身並且於程式碼無關)
- 大家可以把我的數學水平想象成初中水平,畢竟小嗷既不是程式碼靠吃飯又不是靠數學吃飯,畢業N年
- 寫文章主要是為了後人少走點彎路,多交點朋友,一起學習
- 如果有好的影象識別群拉我進去QQ:631821577
- 就我一個白板,最後還是成的,你們別怕,慢慢來把
分享可以無數次,轉載成自己文章QQ郵箱通知一下,未經授權請勿轉載。
- 郵箱:[email protected]
- QQ群:736854977
- 有什麼疑問公眾號提問,下班或者週六日回答,ths
推薦文章:
11.VS2015安裝QT外掛執行第一行程式碼(QT篇) — OpenCV從零開始到影象(人臉 + 物體)識別系列
1.每天聽一聽我微信公眾號的雜文10分鐘,好過打遊戲,哈哈哈