根据 Qt 版本动态使用 QGLWidget 或 QOpenGLWidget

Dynamically use QGLWidget or QOpenGLWidget depending on Qt version

我的代码应该在 Qt 5.4 之前和之后的平台上编译和 运行,Qt 5.4 引入了 QOpenGLWidget,取代了 QGLWidget。我以为我可以编写这样的代码来支持两者:

#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
#  define USE_Q_OPEN_GL_WIDGET
#endif

#ifdef USE_Q_OPEN_GL_WIDGET
#  include <QOpenGLWidget>
#else
#  include <QGLWidget>
#endif

class GLWidget :
#ifdef USE_Q_OPEN_GL_WIDGET
    public QOpenGLWidget
#else
    public QGLWidget
#endif
{
    Q_OBJECT
public:
    [...]

但这不会成功,因为 moc 似乎不理解预处理器指令,并且会为错误的 class.

生成代码

我试图通过向我的 CMakeLists.txt 添加一个 add_custom_command 指令来解决这个问题,这将在将文件传递给 moc 之前对文件进行 运行 ${CMAKE_CXX_COMPILER}" -E -P -x c++-header ...。但这似乎也不起作用,因为预处理器将删除神奇的 Q_OBJECT 行,表明确实 moc 必须是 运行 before C 预处理器是 运行.

我还有哪些其他选择?

我必须求助于两个几乎相同的头文件(两行除外),然后在构建时在 cmake 中选择正确的头文件吗?

编辑

要测试此问题,请尝试以下操作:

所以总而言之,moc 确实理解一些预处理器指令,但它理解的指令在 qt 5.4 之前和之后的版本之间是不同的。似乎不存在两者都能理解的通用预处理器指令。因此,我看不到使用预处理器指令解决此问题的方法。

您可以使用 CMake 生成这个 header。将此代码放入其中:

#include <@GL_CLASS@>

class GLWidget : @GL_CLASS@
{
    Q_OBJECT
public:
    [...]

然后在 CMakeLists.txt 中执行此操作:

set(GL_CLASS <depending on Qt version>)
include_directories(${CMAKE_CURRENT_BINARY_DIR}) #this is because configure_file produces its output in the build dir
configure_file(yourheader.h output.h @ONLY)

最后,在您的代码中使用 #include "output.h"