用VS Code搞Qt6:編譯附加模組

2022-08-11 21:00:54

上一次水文中,老周所介紹的是編譯 Qt 的基礎模組—— qtbase。一次性編譯所有程式碼可以一勞永逸,但體積相當大,編譯時間較長,CPU負載大發熱大,風扇轉得猛,電費交得多。因此老周更喜歡分開來編譯。

qtbase 模組已經能完成一般的 Qt 開發了,畢竟它包含了鐵三角—— Core、Gui、Widgets。有這三個硬漢到場,Qt應用就能執行起來。而附加模組是為了特殊需要的,比如 OpenGL。當要用到某模組時再增量編譯,這樣逼格更高,也省事。

本文老周以編譯多媒體模組 qtmultimedia 為例,演示一下如果編輯附加模組。編譯附加模組的前提是你已編譯並安裝好 qtbase 模組(就是老周前一篇水文中說的)。

在編譯之前,老周要先說明一個事:在編譯qtbase模組時,預設它會編譯為 release 模式,即省去一些偵錯符號檔案,使體積更小。但老周通過試驗發現,如果qtbase模組在執行 configure 指令碼時沒有明確加上 -release 引數的話,那附加模組會編譯為 debug 模式的。所以,如果你之前在編譯 qtbase 模組時沒有加 -release 引數,那不妨重新編譯一下,反正單個模組編譯也很快。

所以,設定命令如下:

configure -prefix G:\Kits\Qt6\installed -release

之後就是跟前面說的一樣,cmake --build .、cmake --install .。

-----------------------------------------------------------------------------------------------

編譯附加模組無需重新設定,而是通過一個指令碼來設定引數。這個指令碼位於你最終的安裝路徑中,比如,老周的是 G:\Kits\Qt6\installed,在 bin 子目錄下,有個名為 qt-configure-module 的指令碼。Linux 上無字尾,Windows 上為 .bat。

用法也很簡單,直接輸入:qt-configure-module <附加模組原始碼路徑> 。

只有原始碼路徑是必須引數,之後是可選引數。這些引數是什麼取決於你正在編譯的模組——也就是說每個模組的選項不同。可以在模組的原始碼目錄下找到一個叫 config_help.txt 的文字檔案,裡面會有選項說明。比如,qtmultimedia 模組的選項說明如下:

Multimedia options:

  -pulseaudio .......... Enable PulseAudio support [auto] (Unix only)
  -alsa ................ Enable ALSA support [auto] (Unix only)
  -no-gstreamer ........ Disable support for GStreamer
  -gstreamer [version] . Enable GStreamer support [auto]
                         With no parameter, 1.0 is tried first, then 0.10.
  -evr ................. Enables EVR in WMF [auto]

 這些選項沒有很詳細的說明,想弄明白的話多數要看指令碼程式碼。當然,沒興趣的話就不用看了,其實這些選項一般不用去設定。

 

接下來,咱們開始幹正事。要編譯 qtmultimedia 模組,還要下載 qtshadertools 模組。因為 qtmultimedia 依賴 qtshadertools。說白了,咱們要先編譯並安裝 qtshadertools 模組。

怎麼下載就不說了,還是和上次一樣,我們先建一些特定的目錄,各司其責,這樣好管理。

原始碼目錄:G:\Kits\Qt6\src

生成目錄(執行build):G:\Kits\Qt6\build

安裝目錄(最終成品):G:\Kits\Qt6\installed

再次強調下,要以 release 模式編譯,qtbase 模組要加 -release 引數。假設你已經編譯且安裝好 qtbase 模組。在 G:\Kits\Qt6\installed\bin 目錄下會有相關的二進位制檔案。

1、開啟 x64 Native Tools Command Prompt for VS 2022(Linux 下不需要)

2、CD 到 build 目錄下。cmake 命令在這個目錄下執行,就會將檔案輸出到該目錄。

cd /d G:\Kits\Qt6\build

3、執行 qt-configure-module 指令碼,設定 qtshadertools 模組。

G:\Kits\Qt6\installed\bin\qt-configure-module.bat G:\Kits\Qt6\src\qtshadertools

4、老樣子,先 build 後 install。

cmake --build .
cmake --install .

5、現在,qtshadertools 模組已就緒。注意,一定要執行 install,這樣編譯 qtmultimedia 模組時,才會找到相關的庫。

-------------------------------------------------------------------------------------------

下面該到 qtmultimedia 模組了。把 build 目錄中的檔案全刪除,確保當前目錄仍然是 build。

1、設定 qtmultimedia 模組。

G:\Kits\Qt6\installed\bin\qt-configure-module G:\Kits\Qt6\src\qtmultimedia

2、一樣,執行這兩條 cmake 命令。

cmake --build .
cmake --install .

【注意:這些 cmake 命令的最後都有個點號「.」,表示當前目錄,即 build 目錄】

 

好了,多媒體模組 qtmultimedia 編譯成功了。再次回到 installed\bin 目錄,就能看到它了。

 

有個帶「Widgets」結尾的,它包含 UI 元素(也叫控制元件),主要是用來呈現視訊,要不然使用者只能看個寂寞。

 

========================================================

編譯完成後,我們要檢驗一下是否正確。寫一個範例播放個視訊試試。

在 VS Code 中隨便開啟一個目錄作為工作區,然後建一個文字檔案 CMakeLists.txt。

cmake_minimum_required(VERSION 3.10.0)
project(testApp LANGUAGES CXX)

# 匯入庫
find_package(Qt6 REQUIRED COMPONENTS
            Core 
            Gui 
            Widgets 
            Multimedia 
            MultimediaWidgets)
# 設定變數
set(CMAKE_AUTOMOC TRUE)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

# 新增原始檔並連結庫
add_executable(testApp main.cpp)
target_link_libraries(testApp PRIVATE
            Qt6::Core
            Qt6::Gui
            Qt6::Widgets
            Qt6::Multimedia
            Qt6::MultimediaWidgets
)

除了鐵三角,還要匯入 Multimedia 和 MultimediaWidgets 兩個庫。

接著新建程式碼檔案 main.cpp,以下是完整的 C++ 程式碼。

#include <QApplication>
#include <QWidget>
#include <QVideoWidget>
#include <QMediaPlayer>
#include <QUrl>
#include <QAudioOutput>

int main(int argc, char* argv[]) 
{
    QApplication app(argc, argv);

    // 要播放的檔案
    QUrl file = QUrl::fromLocalFile("D:\\大山的女兒\\大山的女兒第1集.mp4");
    // 播放器
    QMediaPlayer *player=new QMediaPlayer;
    // 設定檔案源
    player -> setSource(file);
    // 設定音訊輸出
    QAudioOutput *audoutput = new QAudioOutput;
    // 音量
    audoutput -> setVolume(0.5F);
    player -> setAudioOutput(audoutput);

    // 播放控制元件
    QVideoWidget vd;
    // 將此控制元件設定為視訊輸出
    player -> setVideoOutput(&vd);
    // 設定視窗位置
    vd.setGeometry(612, 440, 725, 540);

    // 顯示視窗
    vd.show();
    // 開始播放
    player -> play();

    return app.exec();
}

file 變數呼叫靜態方法 fromLocalFile 載入本地視訊檔,你需要改成你自己的檔案路徑。

哦,對了,Qt 這個媒體庫所支援的解碼器是根據系統所安裝的解碼器來決定的,如果想播放更多格式的視訊,可以安裝解碼包,比如著名的 K-Lite Codec Pack。說白了,WMP 能播放的它就能播放。不要說人家暴風、 PotPlayer 啥都能播放,那些是內建的解碼器,.dll 是在安裝目錄下的,不是安裝到系統中的。

另外,在 QMediaPlayer 範例設定 Source 後,不要忘了設定 QAudioOutput,不設定的話,只有畫面沒有聲音的。device 屬性不需要設定,它會查詢系統預設的音訊輸出裝置。音量可以適當設定一下。

注意音量的值是 float 型別,值在 0 到 1,也就是說,100% 音量是 1.0。官方檔案在概覽小節中給的範例是錯誤的,音量值不是 0 - 100,而是 0 - 1。

player 是指標型別的變數,而且 QMediaPlayer 建構函式呼叫時沒有指定 QObject 作為父物件。即 player 沒有被連結到 Qt 物件樹上。所以,按理說,這個 player 最後應該要 delete 的。但是,由於 app.exec 開啟了主迴圈,當主迴圈結束它才會返回,等它返回時程式就要退出了,這時候有沒有 delete player 也不要緊了,反正程序要退出,player 自然會銷燬。

setVideoOutput 方法參照 QVideoWidget 範例,表示將視訊畫面輸出到這個控制元件上,不然,啥都看不見。
最後,執行程式,如果看到視訊播放,並且有聲音,那就OK了。前提是你要用系統能播放的格式。

 

好了,這個演示就到這兒了,其他模組的編譯也是一樣的操作。重點是知道用 qt-configure-module 指令碼就行了。

完結,收工,開飯。