Qt 我可以在构造函数中将信号/插槽连接到自身吗?

Qt can I connect signals/slots to self in constructor?

本文关键字:连接 插槽 我可以 构造函数 信号 Qt      更新时间:2023-10-16

编辑:与信号/插槽/连接无关。 问题是构造函数调用构造函数。

可能有更好的方法来做到这一点 - 我很想听听这些......

我有从QLabel派生的MyClass。 我想在信号中传递更多关于派生类的数据,而不是基本信号所做的。 所以我做了一个插槽来拦截customContextMenuRequest信号,并发出一个修改后的信号,其中包含更多数据。

当我尝试在构造函数中连接此信号时,我的插槽永远不会被调用。 但是,如果我移动策略并将行连接到父小部件(而不是类层次结构父小部件(,以便它们在 MyClass 完全构造后执行,那么我的插槽将被调用。 但是我总是希望它与这个类连接起来,这似乎是我想要的构造函数,而不是指望父类记住这样做。

我做错了什么吗? 还是向信号添加数据的更好方法?

MyClass::MyClass() : QLabel()
{
    QFont currFont = font();
    currFont.setPointSize(15);
    setFont(currFont);
    setBackgroundRole(QPalette::Mid);
    std::cout << "connecting customContextMenuRequested" << std::endl;
    /** PROBLEM START */
    setContextMenuPolicy(Qt::CustomContextMenu);
    // Is there anything wrong with connecting from "this" to "this" in a constructor?
    QObject::connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
                     this, SLOT(addCellDataToMenuContextRequest(const QPoint&)));
     /* PROBLEM END **/
}

MyClass::MyClass(QString &cellString, int row, int col)
    : QLabel(cellString)
{
    MyClass();
    setRow(row);
    setCol(col);
}
// This one is a slot
void MyClass::addCellDataToMenuContextRequest(const QPoint& pos)
{
        // This doesn't get printed if I connect in my constructor,
        // but it does print if I do the same connect from a parent widget.
    std::cout << "called addCellDataToMenuContextRequest" << std::endl;
    emit customContextMenuRequestedForCell(pos, _row, _col);
}

所以我希望父小部件只查找customContextMenuRequestForCell,但现在,父小部件似乎也需要负责customContextMenuRequest。

实际上

,如果您使用的是C++11,则可以调用(某种程度上(另一个构造函数。它称为委派构造函数。但我不认为这会让问题消失。您的问题似乎是调用元对象时未完全构造connect()。此外,您可能需要迁移到Qt 5才能C++11工作。

解决方案是延迟连接,直到对象完全构造完成。您可以启动间隔为零的计时器。它将在下一个事件循环处理时触发,这肯定会在你的对象完全构造之后。

然后在您的 timerEvent 中,建立连接并终止计时器。

编辑

没有看到您的编辑。 看起来您找到了解决方案。那就忽略这个吧。:)

顺便说一句。您没有调用另一个构造函数。您创建了一个临时的 MyClass 对象。

使这种"更干净"的一种方法是在MyClass中重新实现QWidget::mouseReleaseEvent((。实现它的方法是,如果传递给 mouseReleaseEvent 的 QMouseEvent 类型不是右键单击鼠标版本,则调用 QLabel::mouseReleaseEvent(event(。如果是右键单击鼠标释放事件,则可以发出自定义信号。这提供了使用 QLabel/QWidget 给出的现有鼠标按钮释放处理代码的好处,同时允许您拦截要发出自定义信号的一种情况。

编辑哦,一定要在mouseReleaseEvent处理自定义案例后调用event->accept((。