【问题标题】:Include directive depending on Qt version包含指令取决于 Qt 版本
【发布时间】:2015-10-28 10:06:17
【问题描述】:

我需要在我的代码中包含以下标头:

#include <5.4.1/QtGui/private/qzipwriter_p.h>

问题是,我们正在其他 Qt 版本上编译它,例如 5.4.2 或 5.5.x

我知道我不应该使用这些“私有”标头,因为它们不受支持,但至少在我们有持久替代品之前我们需要它们。

如何连接路径中的 QT_VERSION_STR 变量,以便它适用于所有版本?

【问题讨论】:

  • 你试过#include &lt;QtGui/private/qzipwriter_p.h&gt;吗?这不只包括您当前 Qt 安装所需的一次吗?如果您需要它只是这个文件,只需包含常量路径(例如在环境变量中设置)

标签: c++ qt include c-preprocessor


【解决方案1】:

改用QT_VERSION

QT_VERSION 该宏扩展了 0xMMNNPP(MM = 主要,NN = 次要,PP = 补丁)形式的数值,用于指定 Qt 的版本号。

#if QT_VERSION == 0x050401
  #include <5.4.1/QtGui/private/qzipwriter_p.h>
#endif

编辑:

不知道如何在路径中连接版本字符串?

标准不允许 (16.3.4/3):

生成的完全宏替换的预处理标记序列不作为预处理处理 指令,即使它类似于一个

因此,您不能创建将扩展为#include 指令的宏。您也不能在 include (#include &lt;like this&gt;) 的括号内使用宏,因为括号内的所有内容都只是一个字符串。

【讨论】:

  • 不知道如何在路径中连接版本字符串?
  • @galinette,你可以用一些讨厌的技巧来做到这一点,但通常不会。
【解决方案2】:

您可以使用人类可读的帮助器 QT_VERSION_CHECK 比较数字 QT_VERSION 宏,它将主要、次要和补丁号组合成 QT_VERSION 格式:

#if QT_VERSION == QT_VERSION_CHECK(5, 4, 1)
//...
#endif

来自 GCC 标头 C Macro - Dynamic #include 的连接想法

问题是我们没有 Qt 主要、次要和补丁版本的宏标记。只有数字 QT_VERSION。因此,获得所需的数字很棘手。可以使用qmake 变量QT_*_VERSION 将它们作为宏定义从.pro 文件传输:

DEFINES += QT_MAJOR_VERSION=$$QT_MAJOR_VERSION
DEFINES += QT_MINOR_VERSION=$$QT_MINOR_VERSION
DEFINES += QT_PATCH_VERSION=$$QT_PATCH_VERSION

现在这些宏版本可以在源文件中使用:

// To return as a string: "5.4.1/QtGui/private/qzipwriter_p.h"
#define qt_header__(x) #x
#define qt_header_(major,minor,patch) qt_header__(major.minor.patch/QtGui/private/qzipwriter_p.h)
#define qt_header(major,minor,patch) qt_header_(major,minor,patch)

// Simpler without stringification, however Qt Creator cannot follow
// that header
#define qt_header(major,minor,patch) <major.minor.patch/QtGui/private/qzipwriter_p.h>

#include qt_header(QT_MAJOR_VERSION, QT_MINOR_VERSION, QT_PATCH_VERSION)

最好使用字符串化变体 ("5.4.1/QtGui/private/qzipwriter_p.h")。在这种情况下,最新版本的 Qt Creator 可以遵循这样的 qt_header() 宏并相应地突出显示文本。

【讨论】:

  • 不知道如何在路径中连接版本字符串?
  • @galinette 不,可以连接宏标记但不能连接字符串stackoverflow.com/a/20551609/4023446 要使用它,您需要的不是字符串,而是#define VER 5.4.1 之类的东西。然后可以从这样的VER宏生成包含路径。
  • @galinette 我用可能的连接更新了答案。
  • Qt中有一个版本字符串,它是QT_VERSION_STR,和问题一样。它完全等于“major.minor.patch”,至少在 Qt 4 和 5 中
  • @galinette QT_VERSION_STR 是一个字符串。它被定义为#define QT_VERSION_STR "5.4.1",但是你需要它而不需要引用。
【解决方案3】:

使用 cmake 会是这样的:

CMakeLists.txt:

find_package(Qt5 COMPONENTS Core Qml)
add_definitions(-DQT_VERSION_MAJOR=${Qt5_VERSION_MAJOR})
add_definitions(-DQT_VERSION_MINOR=${Qt5_VERSION_MINOR})
add_definitions(-DQT_VERSION_PATCH=${Qt5_VERSION_PATCH})

你的代码.cpp:

#define p_qqmljslexer(major,minor,patch)  <major.minor.patch/QtQml/private/qqmljslexer_p.h>

#include p_qqmljslexer(QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH)  

【讨论】:

    【解决方案4】:

    带有两个字母的小版本,例如5.11 不行,但是可以

    #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
        auto isok = f.open(QIODevice::NewOnly| QIODevice::Text);
    #else
        auto isok = !QFileInfo::exists(newfile) && f.open(QIODevice::Text);
    #endif
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-02
      • 1970-01-01
      • 2018-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多