最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

配置CLion管理Qt項目國際化支持的方法

 更新時間:2021年04月13日 09:37:20   作者:apocelipes  
這篇文章主要介紹了配置CLion管理Qt項目國際化支持的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

隨著Qt 6的發(fā)布,cmake也正式宣告接管qmake的工作了。

在之前的一篇博客里我介紹了如何使用cmake管理你的qt項目,不過有一點我沒有講,那就是對國際化(i18n)的處理。

今天我們就來介紹下如何使用cmake+clion配置管理一個包含了國際化支持的項目。

準備工作

你需要準備下面的工具

  • Qt 5.13+(我使用的是Qt 5.15.2)
  • CLion 2020.3+
  • GCC 9.0+ (最好支持c++17,最低要求是支持c++11)

其中GCC一般自己安裝的Qt會有附帶,否則在Windows上使用vs2019的編譯器也是可以的。

在Linux上如果不想自己下載安裝Qt的話也可以使用系統(tǒng)倉庫打包好的:

# ubuntu
sudo apt-get install build-essential libglu1-mesa-dev libpulse-dev libglib2.0-dev
sudo apt-get --no-install-recommends install libqt*5-dev qt*5-dev qml-module-qtquick-* qt*5-doc-html

# Arch/Manjato
sudo pacman -S base-devel
sudo pacman -S --needed qt5

選擇CLion的2020.3及以上版本是因為它提供了自帶的Qt項目模板,省去了我們自己搭框架的麻煩。

當然如果你還在使用舊版CLion的話可以參考這篇文章配置Qt項目。

Qt 6在cmake的配置上是類似的,只需要修改幾個函數(shù)的名稱即可,后面會提及。

創(chuàng)建項目

前置工作完成之后就可以創(chuàng)建項目了,如下圖所示:

默認是c++14標準,我個人更喜歡用c++17,不過今天的例子使用c++14也是可以的。

創(chuàng)建完成后你會得到如下的CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.17)
project(untitled1)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

set(QT_VERSION 5)

# 設置需要用到的Qt modules
set(REQUIRED_LIBS Core Gui Widgets)
set(REQUIRED_LIBS_QUALIFIED Qt5::Core Qt5::Gui Qt5::Widgets)

add_executable(${PROJECT_NAME} main.cpp)

# 提示你應該指定qt的cmake模塊的路徑,使用系統(tǒng)默認配置時無需關心
# 嫌這個警告啰嗦的話完全可以注釋掉或者刪除
if (NOT CMAKE_PREFIX_PATH)
    message(WARNING "CMAKE_PREFIX_PATH is not defined, you may need to set it "
            "(-DCMAKE_PREFIX_PATH=\"path/to/Qt/lib/cmake\" or -DCMAKE_PREFIX_PATH=/usr/include/{host}/qt{version}/ on Ubuntu)")
endif ()

# 引入并鏈接用到的Qt modules
find_package(Qt${QT_VERSION} COMPONENTS ${REQUIRED_LIBS} REQUIRED)
target_link_libraries(${PROJECT_NAME} ${REQUIRED_LIBS_QUALIFIED})

CLion就是靠cmake來組織項目的,對于cmake的配置自然是必不可少的。

項目下還有一個提前寫入了Hello World示例的main.cpp。點擊編譯運行你就會看到程序創(chuàng)建的窗口了。

下面我們就該進入正題了。

配置國際化支持

為了能更好地展示國際化,我們需要把例子代碼改成下面這樣:

#include <QApplication>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QPushButton>
#include <QWidget>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    QWidget window;
    auto btn1 = new QPushButton{QObject::tr("click left button")};
    QObject::connect(btn1, &QPushButton::clicked, [w = &window]() {
        QMessageBox::information(w, 
                                 QObject::tr("clicked left button"), 
                                 QObject::tr("you clicked left button"));
    });
    auto btn2 = new QPushButton{QObject::tr("click right button")};
    QObject::connect(btn2, &QPushButton::clicked, [w = &window]() {
        QMessageBox::information(w,
                                 QObject::tr("clicked right button"),
                                 QObject::tr("you clicked right button"));
    });
    auto mainLayout = new QHBoxLayout;
    mainLayout->addWidget(btn1);
    mainLayout->addWidget(btn2);
    window.setLayout(mainLayout);
    window.show();
    return QApplication::exec();
}

對于國際化的細節(jié)我們不過多介紹,這里只要知道需要翻譯的文字要用QObject::tr處理即可。

點擊運行,你會看到界面上都是英文,因為現(xiàn)在我們還沒添加國際化支持:

Qt的翻譯文件由ts文件和qm文件組成,ts文件用于人類進行翻譯工作,而Qt會根據ts文件生成qm文件,這是供程序使用的二進制文件,人類無法直接閱讀。

所以在項目中我們只需要關心ts文件即可,下面我們創(chuàng)建一個lang子目錄,我們要在其中進行英語到漢語和日語的翻譯工作:

mkdir lang

不過我們不用自己創(chuàng)建ts文件,因為這是Qt能自動完成的。

下面我們修改一下cmake,讓他能支持國際化:

cmake_minimum_required(VERSION 3.17)
project(untitled1)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

set(QT_VERSION 5)
set(REQUIRED_LIBS Core Gui Widgets)
set(REQUIRED_LIBS_QUALIFIED Qt5::Core Qt5::Gui Qt5::Widgets)

set(TS_FILES
        ${CMAKE_SOURCE_DIR}/lang/zh_CN.ts
        ${CMAKE_SOURCE_DIR}/lang/ja_JP.ts)

find_package(Qt${QT_VERSION} COMPONENTS ${REQUIRED_LIBS} LinguistTools REQUIRED)

qt5_create_translation(QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${TS_FILES})

add_executable(${PROJECT_NAME} main.cpp ${TS_FILES})

if (NOT CMAKE_PREFIX_PATH)
    message(WARNING "CMAKE_PREFIX_PATH is not defined, you may need to set it "
            "(-DCMAKE_PREFIX_PATH=\"path/to/Qt/lib/cmake\" or -DCMAKE_PREFIX_PATH=/usr/include/{host}/qt{version}/ on Ubuntu)")
endif ()

target_link_libraries(${PROJECT_NAME} ${REQUIRED_LIBS_QUALIFIED})

哇,配置變得更長更嚇人了,其實核心內容一共只有這幾行:

set(TS_FILES
        ${CMAKE_SOURCE_DIR}/lang/zh_CN.ts
        ${CMAKE_SOURCE_DIR}/lang/ja_JP.ts)

find_package(Qt${QT_VERSION} COMPONENTS ${REQUIRED_LIBS} LinguistTools REQUIRED)

qt5_create_translation(QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${TS_FILES})

add_executable(${PROJECT_NAME} main.cpp ${TS_FILES} ${QM_FILES})

第一行很好理解,把我們的需要的ts文件的名字先設置到變量里。

接著我們引入Qt5::LinguistTools,這不是c++庫,只是一個幫助生成ts文件和qm文件的cmake模塊,所以不能鏈接到程序里。

最后一行也很簡單,把ts文件加入編譯程序的依賴項目里,一旦發(fā)生改變就重新構建我們的程序。

關鍵在于qt5_create_translation這里,這個函數(shù)會幫我們創(chuàng)建ts文件,如果ts文件已經存在就會更新ts文件把新添加的翻譯追加進去;

到這步還沒結束,在更新完ts文件后它會檢查ts文件中是否有有效的翻譯信息,如果有就在cmake的編譯目錄下生成和ts文件同名的qm文件。

中間的${CMAKE_CURRENT_SOURCE_DIR}就是指定從哪個目錄下的源文件里獲得需要翻譯的文本的。

注意,如果qm文件最終沒被用到的話,那么實際上不會被生成。為了能生成qm文件所以我們把它加入了依賴,還有更好的辦法,后面介紹。

在Qt 6中我們只需要把函數(shù)名改成qt_create_translation就行了。

如果你想自己創(chuàng)建和更新ts文件,只需要把函數(shù)換成qt5_add_translation,它會自動根據ts文件生成qm文件,不過要是沒有ts文件存在他就會報錯。在Qt 6中它的名字會變?yōu)?code>qt_add_translation。

上述的工作會在make的時候進行,比如這樣:

添加翻譯

添加翻譯沒什么好講的,你可以直接編輯ts文件,因為它是xml格式的,編輯起來還是很容易的。

不過有時候翻譯需要參考文本和代碼的上下文,這時候就需要用到Qt Linguist了:

具體的使用細節(jié)不再贅述,你可以參考園內和網上的其他優(yōu)質文章。

編譯運行后你就會在構建目錄看到兩個qm文件,這時候我們的程序還沒有完成國際化支持,在代碼中我們需要使用這些qm文件:

#include <QLocale>
#include <QTranslator>

int main()
{
    QApplication a(argc, argv);
    QTranslator trans;
    if (trans.load("./" + QLocale().name() + ".qm")) {
        QCoreApplication::installTranslator(&trans);
    }
    ...
    return a.exec();
}

我們用QTranslator加載本地的qm文件,QLocale的name方法正好可以返回諸如“ja_JP”的名字。

我的系統(tǒng)默認設置是日語,因此運行程序會看到這樣的界面:

如果你的環(huán)境是中文的,那么顯示的界面也是中文的,這就是Qt的i18n國際化支持。

將多語言資源綁定進程序

到上一節(jié)結束我們其實就把i18n講完了,你完全可以打包程序的時候把qm文件和程序放在一起,安裝的時候也放在同一目錄。

但這種方案還是有些缺點的:

  • 如果支持的語言比較多,那么就會有大量的小文件需要處理,難免會出錯;
  • 需要把qm這種無關的文件放進編譯依賴里

對于有代碼潔癖的我來說第二點尤其忍不了,但是如果不用這些qm文件的話最終是不會生成他們的,怎么辦呢?

其實還有辦法,我們可以把這些qm文件都集成到qrc里。

首先在目錄下創(chuàng)建一個translations.qrc文件:

<RCC>
    <qresource>
        <file>zh_CN.qm</file>
        <file>ja_JP.qm</file>
    </qresource>
</RCC>

這里不用管資源文件的路徑,因為我們還要對CMakeLists.txt做些修改處理這些問題:

set(CMAKE_AUTORCC ON) # 一定得開啟rcc

# 注意這行
configure_file(translations.qrc ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)

...

add_executable(${PROJECT_NAME} main.cpp ${TS_FILES} ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)

需要注意的是configure_file那行,我們把qrc文件原樣復制到了編譯目錄里,因為qm文件也是在那里生成的。

現(xiàn)在qrc會被自動處理,然后我們的qm文件作為其依賴項也能被自動生成了。

再次編譯項目,這次我們就能發(fā)現(xiàn)qm被生成了:

因為使用了Qt的rcc把資源嵌入了程序,所以cpp代碼也得做一些調整:

QTranslator trans;
-if (trans.load("./" + QLocale().name() + ".qm")) {
+if (trans.load(":/" + QLocale().name() + ".qm")) {
    QCoreApplication::installTranslator(&trans);
}

注意.變成了,這代表我們指定的路徑是嵌入資源的。

這樣國際化支持就徹底完成了,通過修改Linux的LANG環(huán)境變量我們可以自由設置程序的語言,效果如下:

總結

現(xiàn)在我把完整的CMakeLists.txt貼上來作為參考,對于你自己的項目當然是要做調整的:

cmake_minimum_required(VERSION 3.17)
project(untitled1)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

set(QT_VERSION 5)
set(REQUIRED_LIBS Core Gui Widgets)
set(REQUIRED_LIBS_QUALIFIED Qt5::Core Qt5::Gui Qt5::Widgets)

set(TS_FILES
        ${CMAKE_SOURCE_DIR}/lang/zh_CN.ts
        ${CMAKE_SOURCE_DIR}/lang/ja_JP.ts)

find_package(Qt${QT_VERSION} COMPONENTS ${REQUIRED_LIBS} LinguistTools REQUIRED)

configure_file(translations.qrc ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)

qt5_create_translation(QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${TS_FILES})

add_executable(${PROJECT_NAME} main.cpp ${TS_FILES} ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)

message(${QM_FILES})

target_link_libraries(${PROJECT_NAME} ${REQUIRED_LIBS_QUALIFIED})

更進一步

現(xiàn)在你已經能用clion管理自己的多語言支持項目了,然而目前的方案仍稱不上完美。

因為對ts文件的更新和qm文件的創(chuàng)建必須在編譯期間進行,無法單獨進行上述的工作。根據文檔的說法來看,對于多語言的支持通常是在軟件本身功能基本完善之后進行的,ts文件和qm文件不會經常進行變更,所以在編譯期間一并處理是可以接受的。

不過事實上軟件的功能往往會增量更新,翻譯也會進行訂正和改進,為此需要重新編譯整個項目作為代價顯然太過高昂。

那么能不能把i18n的處理獨立出來呢,答案是可以的,不過我們不能再借助LinguistTools了。因為LinguistTools在內部使用的是add_custom_command,無法獨立構成一個編譯目標,所以得另尋出路。

下面來看看修改后的代碼:

# 去掉了LinguistTools
find_package(Qt${QT_VERSION} COMPONENTS ${REQUIRED_LIBS} REQUIRED)

# 創(chuàng)建生成ts文件和qm文件的目標
# ALL指定加入make all
add_custom_target(update_all_ts_files ALL)
add_custom_target(create_all_qm_files ALL)

# 找到$PATH里的lupdate和lrelease,你也可以自己設置他們的安裝路徑
find_file(LUPDATE_PATH lupdate)
find_file(LRELEASE_PATH lrelease)

# 對于每一個ts文件,都生成一個update_ts_file_<NAME>和create_qm_file_<NAME>目標
foreach(TS_FILE ${TS_FILES})
    # 把zh_CN.ts中的zh_CN提取出來
    get_filename_component(I18N_NAME ${TS_FILE} NAME_WE)
    set(TS_TARGET_NAME "update_ts_file_${I18N_NAME}")
    add_custom_target(${TS_TARGET_NAME}
            COMMAND ${LUPDATE_PATH} ${CMAKE_CURRENT_SOURCE_DIR} -ts ${TS_FILE}
            VERBATIM)
    # 將update_ts_file_<NAME>添加為update_all_ts_files的依賴,下同
    add_dependencies(update_all_ts_files ${TS_TARGET_NAME})
    set(QM_TARGET_NAME "create_qm_file_${I18N_NAME}")
    set(QM_FILE "${CMAKE_CURRENT_BINARY_DIR}/${I18N_NAME}.qm")
    add_custom_target(${QM_TARGET_NAME}
            COMMAND ${LRELEASE_PATH} ${TS_FILE} -qm ${QM_FILE}
            VERBATIM)
    # 因為得先有ts文件才能生成qm文件,所以把構建ts文件的目標作為自己的依賴
    add_dependencies(${QM_TARGET_NAME} ${TS_TARGET_NAME})
    add_dependencies(create_all_qm_files ${QM_TARGET_NAME})
endforeach()

configure_file(translations.qrc ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)

add_executable(${PROJECT_NAME} main.cpp ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)
# 因為qrc依賴qm文件,所以需要先讓qm文件創(chuàng)建完成
add_dependencies(${PROJECT_NAME} create_all_qm_files)

看上去很復雜,然而實際上上面的代碼只做了一件事,生成了如下的依賴鏈:

現(xiàn)在更新ts文件和生成qm文件都可以作為單獨的步驟而存在了,這是qt5_create_translationqt5_add_translation做不到的:

很好,我們可以任意更改翻譯而不用重新編譯整個項目了,自己動手豐衣足食。

如果想要看更具體的項目是如何配置i18n的,我這也有一個例子,如果不嫌棄覺得有幫助的話可以star一下。

到此這篇關于配置CLion管理Qt項目國際化支持的方法的文章就介紹到這了,更多相關CLion Qt國際化內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • c++中引用和指針的區(qū)別和聯(lián)系

    c++中引用和指針的區(qū)別和聯(lián)系

    許多人對于引用和指針的區(qū)別與聯(lián)系很糾結(包括我在內O(∩_∩)O哈哈~),最近看到一篇關于引用和指針區(qū)別和聯(lián)系的文章,感覺茅塞頓開,在這里和大家分享下
    2014-04-04
  • VScode platformio使用的詳細步驟

    VScode platformio使用的詳細步驟

    使用VSCode作為編輯器,同時借助PlatformIO插件,可以幫助開發(fā)者更加高效地進行嵌入式開發(fā),本文主要介紹了VScode platformio使用的詳細步驟,感興趣的可以了解一下
    2023-10-10
  • VC判斷一個文件為目錄的方法

    VC判斷一個文件為目錄的方法

    這篇文章主要介紹了VC判斷一個文件為目錄的方法,在Windows應用程序設計中非常具有實用價值,需要的朋友可以參考下
    2014-10-10
  • C++修煉之拷貝構造函數(shù)

    C++修煉之拷貝構造函數(shù)

    這篇文章主要內容是6個默認成員函數(shù)之一的拷貝構造函數(shù)的認識與學習,讓同學們充分理解淺拷貝與深拷貝,感興趣的小伙伴可以參考閱讀
    2023-04-04
  • Matlab實現(xiàn)繪制雷達圖(蜘蛛圖)

    Matlab實現(xiàn)繪制雷達圖(蜘蛛圖)

    這篇文章主要為大家詳細介紹了如何利用Matlab實現(xiàn)雷達圖(蜘蛛圖)的繪制,文中的示例代碼講解詳細,對我們學習Matlab有一定幫助,需要的可以參考一下
    2022-09-09
  • C語言動態(tài)內存規(guī)劃詳解

    C語言動態(tài)內存規(guī)劃詳解

    這篇文章主要介紹了C語言動態(tài)內存的規(guī)劃,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-10-10
  • 基于C語言實現(xiàn)的掃雷游戲代碼

    基于C語言實現(xiàn)的掃雷游戲代碼

    這篇文章主要介紹了基于C語言實現(xiàn)的掃雷游戲代碼,對于學習游戲開發(fā)的朋友有一定的借鑒價值,需要的朋友可以參考下
    2014-08-08
  • c語言調用匯編的方法

    c語言調用匯編的方法

    在此記錄一下c調用匯編的方法,匯編使用的是AT&T語法。例子很簡單,就是在給一個整數(shù)用匯編轉換成二進制
    2013-11-11
  • C++中的可移植性和跨平臺開發(fā)教程詳解

    C++中的可移植性和跨平臺開發(fā)教程詳解

    這篇文章主要為大家介紹了C++中的可移植性和跨平臺開發(fā)教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • C++解決業(yè)務辦理時間問題示例解析

    C++解決業(yè)務辦理時間問題示例解析

    這篇文章主要為大家介紹了C++解決業(yè)務辦理時間問題示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12

最新評論

眉山市| 隆化县| 永寿县| 滕州市| 松阳县| 临漳县| 梁山县| 双峰县| 巴彦县| 马公市| 弥渡县| 鄂伦春自治旗| 康马县| 长岭县| 项城市| 永胜县| 德昌县| 河南省| 宾阳县| 塘沽区| 新和县| 卢龙县| 镇安县| 枝江市| 略阳县| 巴楚县| 十堰市| 五华县| 庆云县| 宜春市| 任丘市| 维西| 江山市| 台南县| 静宁县| 沈阳市| 安宁市| 行唐县| 丹凤县| 乳源| 开阳县|