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

Passing controls as member fields to a method called with the new connect()

本文关键字:connect 方法 调用 控件 成员 字段      更新时间:2023-10-16

我对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();的那一刻

我试图捕获它,然后将整个 ui 指针传递给 HandleSignalEvent 函数,但我结束的只是内存访问 违规断言。

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

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

您正在对对象调用方法,因此必须确保在发出信号时目标对象存在。为此,您需要提供目标对象作为连接的上下文

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

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

此外,在UIController::HandleSignalEvents中,某些m_ui成员可能为空或悬而未决。确保不是这样!

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