将控件作为成员字段传递给使用new connect()调用的方法

时间:2016-03-11 19:23:34

标签: c++ qt lambda

我对qt的新connect()语法有疑问。

我的连接看起来像这样:

connect(m_ui->addEntryButton, &QPushButton::clicked, [&](){HandleSignalEvents(Events::AddEntryButton);});

m_ui->addEntryButton作为我的触发按钮,lambda调用一个方法,然后根据其枚举参数将信号重定向到实际的处理方法。

但是,我遇到的问题是我的HandleSignalEvents方法如下所示:

void UIController::HandleSignalEvents(Events event)
{
    switch (event)
    {
    case Events::AddEntryButton:
        m_eventHandler.HandleAddEntryClick(m_ui->addEntryDateEdit, m_ui->addEntryTextEdit, m_ui->mainEntryList);
        break;
    }

}

我认为内容在细节上并不太相关,我只想确保你们明白,我想把指针传递给我的UI控件到函数,所以我可以在那里执行所有操作,包括重置文本字段等。

但是,考虑到从lambda调用函数,我无法弄清楚如何处理范围问题。我试图捕获this,然后将整个ui指针传递给HandleSignalEvent函数,但我所有的结果都是内存访问冲突断言。

但是,我真的很喜欢lambda方式,因为我不得不设置SignalMappers或其他一些模糊的东西。

有关如何正确传递正确句柄的建议吗?

我应该注意到我的ui指针是boost::shared_ptr

编辑:

根据要求,这是一些额外的代码:

我的控制器:

void UIController::InitBinds()
{
    connect(m_ui->addEntryButton, &QPushButton::clicked, [&](){HandleSignalEvents(Events::AddEntryButton); });
}

void UIController::HandleSignalEvents(Events event)
{
    switch (event)
    {
    case Events::AddEntryButton:
        m_eventHandler.HandleAddEntryClick(m_ui->addEntryDateEdit, m_ui->addEntryTextEdit, m_ui->mainEntryList);
        break;
    }

}

EventHandler-class:

void EventHandler::HandleAddEntryClick(QDateTimeEdit *dateTimeEdit, QTextEdit *textEdit, QListWidget *mainList)
{
    QDate dateTime = dateTimeEdit->date();
    int day = dateTime.dayOfWeek();
}

我得到的错误是(我的视觉工作室设置为德语,但我尝试翻译它,因此它没有失去意义):

Exception at 0x... (Qt5Core.dll) in ... .exe:

0xC0000005: Access violated while reading at position 0x8B0C43BD

当我尝试访问dateTimeEdit->date();

时,会发生这种情况

2 个答案:

答案 0 :(得分:0)

  

我试图抓住这个,然后将整个ui指针传递给   HandleSignalEvent函数,但我所有的结果都是内存访问   违规断言。

我尝试将m_ui指针按值传递给事件处理程序:

connect(m_ui->addEntryButton, &QPushButton::clicked, [=](){HandleSignalEvents(Events::AddEntryButton, m_ui);});

答案 1 :(得分:0)

您正在调用对象上的方法,因此您必须确保在发出信号时目标对象存在。您可以通过将目标对象作为上下文提供给连接来完成此操作。

如果目标对象消失,这将起作用,或者是无操作:

connect(m_ui->addEntryButton, &QPushButton::clicked, 
        this, [this]{ HandleSignalEvents(Events::AddEntryButton); });
        ^^^^
        Absolutely critical

此外,在UIController::HandleSignalEvents中,某些m_ui成员可能会为空或悬挂指针。确保情况并非如此!

请注意,[&]{ ... }按值捕获this,因为它应该 - 通过引用捕获它是无稽之谈,因为this在方法退出时将超出范围;有关详细信息,请参阅this question