代码之家  ›  专栏  ›  技术社区  ›  CybeX

范围中未定义Qt版本检查和QOverload

  •  2
  • CybeX  · 技术社区  · 7 年前

    大家好

    背景:

    我正准备在debian系统上构建和测试部署我的应用程序,但是我遇到了一些麻烦

    我的应用程序使用 QOverload 对于 QNetworkReply ,如 documentation

    用法示例如下(从文档页):

    connect(networkReply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error),
        [=](QNetworkReply::NetworkError code){ /* ... */ });
    

    或在我的应用程序中发现的其他用法:

    # header
    QButtonGroup *grpProtocol;
    QMetaObject::Connection conProtocol
    
    # implementation
    conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
        //do some action when a radio button in a QButtonGroup is toggled
    });
    

    问题:

    呼叫时 make 根据我的申请, 制作 投诉错误:

    mainwindow.cpp: In member function ‘void MainWindow::initConnectors()’:
    mainwindow.cpp:462:53: error: ‘QOverload’ was not declared in this scope
         conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
                                                         ^
    mainwindow.cpp:462:79: error: expected primary-expression before ‘*’ token
         conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
                                                                                   ^
    mainwindow.cpp:462:80: error: expected primary-expression before ‘,’ token
         conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
                                                                                    ^
    mainwindow.cpp:462:82: error: expected primary-expression before ‘bool’
         conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
                                                                                      ^
    Makefile:476: recipe for target 'mainwindow.o' failed
    

    现在,我要检查一下 Q过载 找到并包含标题。

    QOverload 可在中找到 qglobal.h 但仅在QT 5.7中引入

    • Qoverload需要使用C++11

    • 或qOverload,使用C++14

    问题是Ubuntu 16.04使用的是Qt版本5.5:

    qtchooser -print-env
    QT_SELECT="default"
    QTTOOLDIR="/usr/lib/x86_64-linux-gnu/qt5/bin"
    QTLIBDIR="/usr/lib/x86_64-linux-gnu"
    
    /usr/lib/x86_64-linux-gnu/qt5/bin/qmake -v
    QMake version 3.0
    Using Qt version 5.5.1 in /usr/lib/x86_64-linux-gnu
    

    我尝试的是:

    我决定使用 preprocessor directives to do the version check 替我打电话。

    #if QT_VERSION <= QT_VERSION_CHECK(5, 7, 0)
        qDebug(mainclient) << "Adding connector for settings prefered connection protocol";
        conProtocol = QObject::connect(ui->grpProtocol, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), [this](){
            // my code here which which handles events
        });
    #endif
    

    然而,上述错误 制作 包含预处理器指令的结果。i、 e.包括Qt版本检查仍然会使QOverload超出范围。

    问题:

    简单地说,我做错了什么?为什么使用特定的QT版本检查集时,make会忽略这一点并仍然构建所有内容?

    更新可能的替代解决方案

    1. 消除 Q过载 完全替换为QT 5.7之前的代码,这将使我的代码稍微笨重一些,并有一些冗余代码(可能)
    2. 将头文件添加到我的应用程序文件中,并仅在系统具有Qt版本时包含它<Qt5.7(被认为是非常糟糕的做法)
    2 回复  |  直到 7 年前
        1
  •  7
  •   fouronnes    7 年前

    您可以使用 static_cast 替换 QOverload :

    connect(networkReply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
        [=](QNetworkReply::NetworkError code){ /* ... */ });
    

    从这里开始: Connecting overloaded signals and slots in Qt 5

        2
  •  0
  •   Teivaz Nima Soroush    7 年前

    此处的逻辑表达式有错误:

    #if QT_VERSION <= QT_VERSION_CHECK(5, 7, 0)
    

    基本上是说“如果版本为 小于或等于 大于5.7英寸,Qt 5.5符合该标准。