【问题标题】:Replacement for exceptions if QObject is used with Signal and Slots如果 QObject 与 Signal 和 Slots 一起使用,则替换异常
【发布时间】:2017-05-12 12:53:49
【问题描述】:

我试图将我的问题分解为一个小例子。真正的问题是更复杂的通信:

我有一个触发通信并连接并向服务器发送消息的功能。如果有答案,客户端类会发出一个包含答案的信号。

void communicate()
{
     client.setUpMessage(); // the answer is emitted as a signal and
                            // and processed in the Slot 
                            // 'reactToAnswer(...)'

     client.sendMessage("HelloWorld");
}

void reactToAnswer(QString answer)
{
     parser.parseAnswer() // an error could occur
}

如果在处理响应的槽中检测到错误怎么办?我想停止执行函数communicate()。这意味着不应再执行函数client.sendMessage("HelloWorld")

我天真地尝试用异常处理问题:

void communicate()
{
     try
     {
          client.setUpMessage(); // the answer is emitted as a signal and
                                 // and processed in the Slot 
                                 // 'reactToAnswer(...)'

          client.sendMessage("HelloWorld");
      }
      catch(myException)
      {
           // do something
      }

void reactToAnswer(QString answer)
{
     if( !parser.parseAnswer() )
     {
          throw myException;
     }
}

这不起作用,从 qt 信号调用的插槽中抛出异常是未定义的行为。 usual way 是重新实现 QApplication::notify()QCoreApplication()::notify,但这对我不起作用。 GUI 已经有一个 QApplication,我希望通信类 (QObject) 独立存在。所有的事情都应该在这个类中处理。

我希望我能通俗易懂地解释这个问题。在任何情况下我都不想使用异常,其他停止通信的方式也适合我。

提前致谢!

【问题讨论】:

标签: c++ qt exception qt-signals


【解决方案1】:

我不确定您要完成的工作是否特别适合信号槽范例...也许您只想使用常规的旧函数调用来代替?即类似:

void communicate()
{
   QString theAnswer;  // will be written to by setupMessage() unless error occurs
   if (client.setUpMessage(theAnswer)) 
   {
      reactToAnswer(theAnswer);     
      client.sendMessage("HelloWorld");
   }
}

信号和槽不适合的原因是信号被设计为可以同时连接到多个槽,并且槽方法被调用的顺序是未定义的——所以如果一个槽-方法试图以您描述的方式干扰信号发射过程,行为是相当不可预测的(因为您不知道有多少其他连接的插槽方法,如果有的话,已经作为信号的一部分被调用-排放,在您的特定插槽方法刹车之前)。当然,如果你曾经使用排队/异步信号,那么它根本就不起作用,因为在信号发射函数已经返回很久之后,插槽将在完全不同的上下文中被调用。

也就是说,如果您绝对必须为此使用信号和插槽,您可以让您的插槽发出自己的错误已发生信号,该信号可以连接回原始信号发射类中的插槽。然后该插槽可以设置一个布尔值(或其他),然后您的通信()方法可以检查该布尔值的状态(在 client.setUpMessage() 返回之后)以决定是继续执行还是提前返回。

(虽然我不建议这样做——信号和槽可以让你的程序不那么复杂,在这种情况下,我认为使用它们而不是常规函数调用实际上会使你的程序更复杂,没有相应的好处)

【讨论】:

    猜你喜欢
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    相关资源
    最近更新 更多