【问题标题】:Passing a class through a signal/slot setup in Qt通过 Qt 中的信号/插槽设置传递一个类
【发布时间】:2011-01-25 22:24:05
【问题描述】:

我试图在插槽/信号设置的接收端获取类的几个成员变量的信息,所以我想传递整个类。不幸的是,类通过后,成员变量似乎为空。这是一些代码sn-ps:

这设置了通过类的信号

signals:
    void selected(const ControlIcon *controlIcon);

这是插槽/信号连接

connect(controllerList->serialController, SIGNAL(selected(const ControlIcon*)),
        infoView, SLOT(serialControllerSelected(const ControlIcon*)));

我从要传递的类中发出信号

emit selected(this);

这是调用类成员数据的代码

QLabel *ASCIIStringHolder = new QLabel;
ASCIIStringHolder->setText(controlIcon->m_ASCIIString);

标签中什么都没有显示,当我设置断点时,我可以看到m_ASCIIString里面什么都没有。

我首先确保它被分配了一些文本,这不是问题。我还尝试了使用和不使用const 的信号/插槽设置。

任何帮助将不胜感激。

【问题讨论】:

  • 您是否在serialControllerSelected() 插槽内设置了断点?这里有一些奇怪的东西;是serialController 还是ControlIcon*
  • 对不起,我忘了提。 SerialController 是 ControlIcon 的子类,所以是的。此外,信号发送和接收都很好(到达槽内的断点),所以错误不存在。

标签: qt signals parameter-passing signals-slots


【解决方案1】:

Qt 信号/槽机制需要有关您的自定义类型的元信息,以便能够在发出的信号中发送它们。 为此,请使用 qRegisterMetaType<MyDataType>("MyDataType"); 注册您的类型

更多信息请咨询official QMetaType documentation

【讨论】:

  • 这仅在按值传递并使用排队连接或与不同线程的自动连接时才是正确的。 OP 使用指针,所以这应该不是问题。
  • 当我使用命令时,我得到这个错误:'QLabel::Qlabel(const QLabel&)' 是私有的。 ControlIcon 和 SerialController 都继承自 QLabel。有什么想法吗?
  • @CoutPotato,要注册元类型,它必须有一个复制构造函数。编译器尝试生成默认的,但由于 QLabel 的复制构造函数是私有的而失败(这样做是为了禁用复制)。但正如我所说,只有在按值传递时才需要它(这对 QWidgets 来说是个坏主意)并且连接是排队的,这仅在多线程应用程序中有用。跨度>
【解决方案2】:

首先,既然您使用的是自动连接,那么发送者和接收者是否都生活在同一个线程中?如果不是,则可能会发生呼叫已排队,并且当它到达时,发送方中的数据已经被修改。您可以尝试使用直接连接来确保这不是问题。

其次,只是为了好玩,您是否尝试在插槽中使用qobject_cast<ControlIcon*>(sender()) 访问发件人?如果信号没有将其作为参数传递,通常就是这样做的。像这样:

QLabel *ASCIIStringHolder = new QLabel;
// this is instead of the argument to the slot:
ControlIcon *controlIcon = qobject_cast<ControlIcon*>(sender());
ASCIIStringHolder->setText(controlIcon->m_ASCIIString); 

【讨论】:

  • 我只有一个线程,所以它们肯定在同一个线程中。我不确定你说要把 qobject_cast 放在哪里,但我会尝试几种方法并报告回来。
  • @CoutPotato, sender(),当从一个槽调用时,返回一个指向产生信号的对象的指针,由于该槽被调用。因此,您可以只拥有一个不带参数的插槽,并且仍然可以访问发送者,但显然您需要将其转换为实际类型才能使用它。
  • @CoutPotato,查看我的编辑示例代码。但是,如果您的应用程序是单线程的并且您执行emit selected(this);,则行为应该没有任何区别。看起来您在其他地方有错误,可能是内存损坏或类似的东西。您发布的代码 sn-ps 没有任何问题。
  • 不走运,信号发送和接收,但ControlIcon的成员仍然是空的。编辑:还没有读过新的 cmets,我会在几分钟后再试一次。
【解决方案3】:

不能将信号声明为传递一个类,然后实际传递该类的子类。我将信号、槽和 connect() 更改为 SerialController(ControllerIcon 的子级),一切正常。

【讨论】:

  • 这在一般情况下是不正确的。如果您要传递值,那将是另一回事,但您只需传递一个地址。我刚刚用一个虚拟示例对其进行了测试,它对我有用。 SerialController 是否有机会使用多重继承?可能与指针重新对齐有关,尽管它击败了我为什么会导致任何问题。
  • SerialController 仅继承自 ControlIcon。您是否确保通过了虚拟类包含的某些数据?我能够让程序编译并正常运行,但没有传递任何数据(在插槽中创建了一个空的 ControlIcon)。
  • 您的数据成员是否检查了串行控制器的基类中存在的位置?
猜你喜欢
  • 1970-01-01
  • 2015-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多