我的代碼應該在引入QOpenGLWidget之前和之後的平臺上編譯和運行,取代了QGLWidget。我以爲我可以寫這樣的代碼來支持:根據Qt版本動態使用QGLWidget或QOpenGLWidget
#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
似乎並不瞭解預處理指令,並會產生錯誤的類代碼。
我試圖通過添加add_custom_command
指令,我CMakeLists.txt
這將它傳遞給商務部之前運行的文件${CMAKE_CXX_COMPILER}" -E -P -x c++-header ...
來解決這個問題。但是,這似乎不起作用,因爲預處理器將刪除魔術線Q_OBJECT
,表明在運行C預處理器之前,必須先運行moc
之前的。
我還有其他選擇嗎?
我必須求助於有兩個幾乎相同的頭文件(兩行除外),然後在cmake中編譯時選擇正確的頭文件嗎?
編輯
爲了測試這個問題,請嘗試以下:
- ,它有一個值得信賴的Ubuntu系統上QT 5.2.1(您可以創建使用
sudo debootstrap trusty ubuntu-trusty
一個chroot)做: - 的apt-get安裝libqt5opengl5-dev的建立必要的qttools5-dev的QT5默認
然後創建
glwidget.h
包含:#ifndef GLWIDGET_H #define GLWIDGET_H #include <QtGlobal> #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 }; #endif
然後運行:
$ moc -v moc 5.2.1 $ moc glwidget.h | grep QGL || echo "not found" not found $ moc glwidget.h | grep QOpenGL >/dev/null && echo "found!" found!
所以你看,即使QT 5.2.1沒有QOpenGL,MOC interpretes預處理指令這樣
我們可以改變版本檢查更簡單
#if QT_VERSION >= 0x050400
如果我們再次嘗試使用該檢查,那麼在Ubuntu Trusty中的qt 5.2.1中的moc生成正確的結果
因此,我們認爲我們找到了解決方案,並嘗試從相同代碼中更近期的qt分發中運行moc 。這一次,我在Debian的不穩定使用MOC從QT 5.5.1,我得到:
$ moc -v moc 5.5.1 $ moc glwidget.h | grep QOpen || echo "not found" not found $ moc foo.h | grep QGL > /dev/null && echo "found" found
最有趣地,如果在QT 5.5.1我打開版本檢查宏觀麥克使用
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
然後它工作!
因此,在總結,商務部確實瞭解一些預處理指令,但它確實瞭解的有前和Qt 5.4版本後之間的不同。似乎沒有一個通用的預處理器指令可以被兩者理解。因此我沒有看到使用預處理器指令來解決這個問題的方法。
其實'moc' *確實瞭解(某些?)預處理指令。這是你的完整標題嗎? – peppe
你用Qt 5.4和5.x(x <4)還是用Qt 4.x? 'moc'擴展了Qt 5中的宏。 – peppe
再一次,是你的完整頭文件嗎?我想有一個完整的測試用例... – peppe