如何从另一个类中发射信号?

37
我有一个关于Qt应用程序的问题。我正在尝试从另一个类中发出信号(它是放置信号的类的嵌套类)。
我已经将信号与插槽连接,这应该没问题。但是当我尝试从这个嵌套类中发出此信号时,我会得到编译器错误:
无法调用成员函数而不使用对象
怎么了?我在Qt文档中寻找了解决方案,但找不到合理的解决方案甚至解释。
简化的类定义如下。
class LogWriter : public QDialog
{   
   Q_OBJECT

public:
   class Log : public QObject
   {
      Q_OBJECT

   public:
      bool print;

      Log(bool _print, QString _color, QObject *obj = NULL)
         : QObject(obj)
      {
         print = _print;
         color = _color;
      }
   };

   LogWriter(QWidget * parent = 0);
   ~LogWriter();

public slots:
   void setMinVal();
   void setMediumVal();
   void setHighVal();
   void cleanWindow();
   void appendText(QString &text);

signals:
   void signalLogAppend(QString);
};

我在客户端代码中将LogWriter实例的一个名为LOW的信号连接到某个槽位,使用以下函数调用:

connect(&LOW, SIGNAL(signalLogAppend(QString)),
        this, SLOT(appendText(QString&)),
        Qt::DirectConnection);

LOW 是正确的对象类型吗? - tmpearce
什么是LOW?缺少一些代码以便进行适当的分析。 - Timo Geusch
LOW代表日志类 - 这是我在帖子中提到的内部类。 - lagoru
1
不确定 moc 是否能很好地处理嵌套类定义。 - ruben2020
1个回答

61
To understand the issue, you have to understand how signals are emitted:
它们只是非静态成员函数调用,因此需要一个实例来调用(“发送者”)。通常,这个实例是this(如果你在同一个类的另一个非静态成员函数中发出信号),所以调用语法变成了一个普通的函数调用,没有任何(文字)实例。 emit关键字是可选的,只是一个展开为无内容的宏。以下四个版本在同一个包含信号的类的成员函数中编写时都是相同的:
emit this->signalLogAppend("foo");
emit signalLogAppend("foo");
this->signalLogAppend("foo");
signalLogAppend("foo");

如果你在内部类中发出外部类的信号,那么this指针将引用内部类的一个实例,因此外部类缺少某些实例。就像在内部类中调用外部类的任何其他函数一样:编译器不知道要在哪个对象实例(外部类)上调用它。因此,你需要编写类似以下的内容:
emit someLogWriter->signalLogAppend("foo");

在这里,someLogWriter 是你想要发出信号的 LogWriter 实例。

嗯...看起来这是逻辑上的解释 :) 我也试着这样想过,但我使用了ptr->emit signalLogAppend(),在阅读了你的帖子后,这看起来有点愚蠢 - 好的,谢谢你的帮助!!! - lagoru
嗯,这很愚蠢,但我认为它也应该能工作。因为它会扩展为 ptr-> signalLogAppend()(注意空格),这应该是有效的。 - leemes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接