Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当Qt信号/插槽连接失败时,如何提醒我?_C++_Qt_Debugging_Qt5_Signals Slots - Fatal编程技术网

C++ 当Qt信号/插槽连接失败时,如何提醒我?

C++ 当Qt信号/插槽连接失败时,如何提醒我?,c++,qt,debugging,qt5,signals-slots,C++,Qt,Debugging,Qt5,Signals Slots,当使用连接到不存在的信号/插槽时,我们会损失很多时间,因为Qt只在运行时控制台日志中的某个地方发出警告 除了发展到使用类型系统报告这些问题的Qt5,以及从系统中的所有connect调用中,是否还有另一种方法让Qt运行时,例如抛出,或干脆崩溃,或大声提醒我,当连接错误时?您可以在连接上使用包装器,当某些连接失败时,该包装器会停止程序: inline void CHECKED_CONNECT( const QObject * sender, const char * signal,

当使用
连接到不存在的信号/插槽时,我们会损失很多时间,因为Qt只在运行时控制台日志中的某个地方发出警告


除了发展到使用类型系统报告这些问题的Qt5,以及从系统中的所有
connect
调用中,是否还有另一种方法让Qt运行时,例如抛出,或干脆崩溃,或大声提醒我,当连接错误时?

您可以在连接上使用包装器,当某些连接失败时,该包装器会停止程序:

inline void CHECKED_CONNECT( const QObject * sender, const char * signal,
             const QObject * receiver,  const char * method,
             Qt::ConnectionType type = Qt::AutoConnection )
{
  if(!QObject::connect(sender, signal, receiver, method, type))
   qt_assert_x(Q_FUNC_INFO, "CHECKED_CONNECT failed", __FILE__, __LINE__);
}

最简单的解决方案是:

bool ok = QObject::connect(sender, SIGNAL(mySignal()), receiver, SLOT(mySlot());
Q_ASSERT_X(ok, Q_FUNC_INFO, "connect mySignal to mySlot");
不要受“缩短”的诱惑。下面的变体是一个bug,在发布模式下变为无操作:

Q_ASSERT_X(QObject::connect(sender, SIGNAL(mySignal()),
                            receiver, SLOT(mySlot()),
                            Q_FUNC_INFO, "connect mySignal to mySlot");
如果没有定义相应的调试宏,则在发布模式下将完全删除此表单

如果你想扔,你可以从这里开始:

try {
    if (!QObject::connect(sender, SIGNAL(mySignal()), receiver, SLOT(mySlot()))
        throw ...;
} catch ( .. )
    qDebug() << "Could not connect ...";
    qApp->exit(1);
}
由于相关代码的局部性,您甚至可以使用lambda使其简短易懂:

connect(sender, &Sender::valueChanged, [=](const QString &newValue) {
    receiver->updateValue("senderValue", newValue);
} );
可通过其操作员进行测试的返回:

如果连接有效,则返回true


另一个选项可能是“重新路由”并分析自动生成的调试消息以查找连接错误。

Qt在连接失败时发送QWarning消息

您可以使用使用qInstallMessageHandler的帮助器类捕获此消息,并在开发模式下使应用程序因QWarnings而崩溃,或者解析警告并仅因连接错误而崩溃。

(请参阅)

我的紧凑型车型如下所示:

// BoolVerifier.h
#include <cassert>    

class BoolVerifier
{
public:
    BoolVerifier() = default;
    inline BoolVerifier(bool b) { assert(b); (void)(b); }
    inline BoolVerifier& operator=(bool b) { assert(b); (void)(b); return *this; }
};

你真的还在使用Qt4吗?你有C++11支持吗?因为,您可以对Qt5使用正确的信号/插槽语法,这会生成运行时错误。还有,当你在控制台上看到错误消息时,为什么会崩溃?@LaszloPapp:我有一个“大代码库”,里面充满了
connect
调用,但没有时间对它们进行调整。控制台中的调试消息隐藏在所有其他输出之间。我正在寻找一种非常直观和具有破坏性的东西,它不需要更改代码-只需要更改编译器/运行时设置。你是说大型代码库,但使用Qt4,它需要在其他地方大量移植到Qt5?因为如果您可以切换到Qt5,则需要以任何方式更改连接线,因此在这种情况下,为什么不将其更改为正确的连接线呢?如果您仍在使用Qt 4,我听到了。:)Qt Creator的一个好处是:Qt Creator的代码完成有助于实现这一点。Qt_assert_x似乎不是有文档记录的公共API,因此我认为使用Q_assert或Q_assert_x更安全,而且:Q_assert_x已经解决了uuuuu文件和uuuuuuuuuu行和noop样板。这也可以避免额外的功能:
#define Q_ASSERT_X(cond,where,what)(!(cond))?qt_ASSERT_X(where,what,what,uu FILE,uuuuuuu,LINE):qt_noop())
qt对你来说很强大。然而,在我问题的第二段中,我问了一种不改变代码的方法。导致qt大声崩溃的运行时参数。它简洁地回答了容易找到的标题问题,并将Qt5指定为标记。此外,它还澄清了在其他答案中隐式使用的返回值的用法。我还提供了当前文档的链接。这将对其他人有所帮助。此外,我的另一个想法也解决了您的问题。重要提示:对于lambda变体,
接收器
必须保持活动状态,只要
发送器
处于活动状态。因此,明智的做法是将其包括在调用中:
connect(sender,&sender::valueChanged,\u receiver,[=]()…)
。我们忘记了这一点导致了很多问题。顺便说一下,构造函数中的内联关键字是多余的。但是,如果稍微不那么符合人体工程学的话,
explicit
可能会更好。很好的应用C++原理!我喜欢这个技巧;它几乎不具有侵入性,而且可以正常工作,并且可以扩展到其他返回错误代码。但是,只有更改
connect
语句的每次出现,它才能工作。
// BoolVerifier.h
#include <cassert>    

class BoolVerifier
{
public:
    BoolVerifier() = default;
    inline BoolVerifier(bool b) { assert(b); (void)(b); }
    inline BoolVerifier& operator=(bool b) { assert(b); (void)(b); return *this; }
};
BoolVerifier b;
b = connect(objectFrom, SIGNAL(mySignal1(int)), objectTo, SLOT(mySlot1(int)));
b = connect(objectFrom, SIGNAL(mySignal2(int)), objectTo, SLOT(mySlot2(int)));
...