How to use backup features in Qt?

Suppose there is a project that uses Qt and depends on functions (for example, added class members) present in the new version of Qt. The project must be built with a "system" / distribution version of Qt, which may be older than the version on which the project depends.

A naive approach leads to the hell preprocessor:

void Class::foo() {
#if QT_VERSION >= QT_VERSION_CHECK(...)
  QClass::newFangled();
#else
  QClass::oldFangled1();
  blurble();
#endif
}

Is there a cleaner approach that will not depend on the preprocessor macros when using this function? That is, we do not want:

// THIS IS BLAH
#if QT_VERSION >= QT_VERSION_CHECK(...)
#define QClass_newFangled QClass::newFangled
#else
#define QClass_newFangled [this]{ \
   QClass::oldFangled1(); \
   blurble(); \
}
#endif
void Class::foo() {
  QClass_newFangled();
}
+1
source share
1 answer

. / Qt , .

Qt-namespace-aware: Qt .

backported ( ) compat,

void test() {
  ...
  qDebug() << compat::qEnvironmentVariableIntValue("RUNMODE");
  compat::QTimer::singleShot(1000, object, []{ ... });
}

, / compat ++ 17 . , / .

Backporting

, backport qEnvironmentVariableIntValue Qt 5.5:

// INTERFACE

namespace compat {
#if QT_VERSION >= QT_VERSION_CHECK(5,5,0)
#if __cplusplus >= 201703L
using QT_PREPEND_NAMESPACE(qEnvironmentVariableIntValue); // C++17
#else
int inline qEnvironmentVariableIntValue(const char *varName, bool *ok = {}) {
  return QT_PREPEND_NAMESPACE(qEnvironmentVariableIntValue)(varName, ok);
}
#endif
#else
int qEnvironmentVariableIntValue(const char *varName, bool *ok = {});
#endif
} // compat
// IMPLEMENTATION

namespace compat {
#if QT_VERSION < QT_VERSION_CHECK(5,5,0)
using QT_PREPEND_NAMESPACE(qgetenv); // C++17
int qEnvironmentVariableIntValue(const char *varName, bool *ok) {
  return qgetenv(varName).toInt(ok, 0);
}
#endif // Qt<5.5
} // compat

, Qt 5.4 QTimer::singleShot(int, QObject*, Functor), :

// INTERFACE

namespace compat {
#if QT_VERSION >= QT_VERSION_CHECK(5,4,0)

using QT_PREPEND_NAMESPACE(QTimer);

#else

using Q_QTimer = QT_PREPEND_NAMESPACE(QTimer);
class QTimer : public Q_QTimer {
  Q_OBJECT
public:
  #if __cplusplus >= 201703L
  using Q_QTimer::Q_QTimer; // C++17
  #else
  QTimer(QObject *parent = {}) : Q_QTimer(parent) {}
  #endif
  template <class Functor> static void singleShot(int, QObject *, Functor &&);
};

template <class Functor>
void QTimer::singleShot(int msec, QObject *context, Functor &&fun) {
  ...
}

#endif
} // compat
+1

All Articles