首页 文章

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

提问于
浏览
5

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

可能有更好的方法来做到这一点 - 我有兴趣听到那些......

我有一个源自QLabel的MyClass . 我希望在信号中传递有关派生类的更多数据,而不是基本信号 . 所以我创建了一个插槽来拦截customContextMenuRequested信号并发出一个包含更多数据的修改后的信号 .

当我尝试在构造函数中连接此信号时,我的插槽永远不会被调用 . 但是,如果我移动策略并将线连接到父窗口小部件(而不是类层次结构父窗口),以便它们在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);
}

所以我希望父窗口小部件只查找customContextMenuRequestedForCell,但是现在,父窗口小部件似乎也需要负责customContextMenuRequested .

2 回答

  • 0

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

    编辑哦,并确保在mouseReleaseEvent处理自定义案例后调用event-> accept() .

  • 3

    实际上,如果你使用C 11,你可以调用(排序)另一个构造函数 . 它被称为delegating constructor . 但我不认为这会使问题消失 . 你的问题似乎是在调用 connect() 时没有完全构造元对象 . 此外,您可能需要转到Qt 5才能使用C 11 .

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

    然后在timerEvent中, Build 连接并终止计时器 .

    EDIT: 没看到你的编辑 . 看起来你找到了解决方案 . 然后忽略这一点 . :)

    BTW . 你没有调用另一个构造函数 . 您创建了一个临时MyClass对象 .

相关问题