【问题标题】:QObject::connect: signal not found in promoted widget with Lambda syntaxQObject::connect: 使用 Lambda 语法在提升的小部件中找不到信号
【发布时间】:2018-04-30 07:43:03
【问题描述】:

我有一个重载的 QTreeWidget 类,带有我的 SIGNALS:我已经在我的 UI 中提升了它,当我使用 lambda 语法收听提升的 QTreeWidget 对象时出现错误。

QObject::connect: signal not found in CustomTreeWidget.

我的 CustomTreeWidget 看起来像:

.h

class CustomTreeWidget : public QTreeWidget
{
    Q_OBJECT
public:
    explicit CustomTreeWidget(QWidget *parent = 0);

    ~CustomTreeWidget() {
    }

signals:
    void currentNodeChanged(QSet<int> uids);
    void deleteRequest(QVector<int> uids);
}

.cpp

CustomTreeWidget::CustomTreeWidget(QWidget *parent) : QTreeWidget(parent)
{
    setAnimated(true);

    connect(this, &CustomTreeWidget::customContextMenuRequested, this, [=](const QPoint &pos) {
        this->m_bCustomMenuOpen = true;
        const auto &&item = this->itemAt(pos);

        QMenu myMenu;

        bool ok = !(item) ? false : true;

        if (ok) {
        //თუ topLevelItem -ია მხოლოდ დამატების action -ი უნდა იყოს ჩართული.
            if (item == this->topLevelItem(0) || item == this->topLevelItem(0)->child(0)) {
                ok = false;
            }
        }

        QAction *Removecnt = myMenu.addAction(tr("&წაშლა"), this, SLOT(DeleteNode()));
        Removecnt->setIcon(QIcon(":/global_res/delete.png"));
        Removecnt->setEnabled(ok);

        myMenu.exec(this->mapToGlobal(pos));
    });
}

void CustomTreeWidget::BFS(QTreeWidgetItem *item, QSet<int> &out)
{
    std::queue<QTreeWidgetItem *> Q;
    Q.push(item);

    while (!Q.empty()) {
        QTreeWidgetItem *now = Q.front(); Q.pop();
        out.insert(this->m_mapUids[now]);
        for (int i = 0; i < now->childCount(); i++) {
            Q.push(now->child(i));
        }
    }
}

QSet<int> CustomTreeWidget::GetCurrentNodeUids()
{
    QSet<int> uids;
    if (!this->currentItem())
        return uids;

    this->BFS(this->currentItem(), uids);
    return uids;
}

void CustomTreeWidget::DeleteNode()
{
    QSet<int> nodes = this->GetCurrentNodeUids();
    QVector<int> uids;
    for (auto it : nodes) {
        uids.push_back(it);
    }

    emit deleteRequest(uids);
}

我的 lambda 看起来像:

connect(ui->productTree, &CustomTreeWidget::deleteRequest, this, [=](QVector<int> uids) {
    //logic
});

但这个信号适用于旧语法。

connect(ui->productTree, SIGNAL(deleteRequest(QVector<int>)), this, SLOT(checkSlot(QVector<int>)));

这个槽是。

void ProductForm::checkSlot(QVector<int> uids)
{
    qDebug() << uids.size();
}

那么什么是问题 lambda 语法?

【问题讨论】:

  • 您确定,您写的错误与新语法有关吗?当您使用旧语法时,它在运行时看起来像错误。
  • 是的,我确定。如果我使用新语法,我在运行时遇到的错误。但旧语法一切正常。
  • 可能是上下文问题。如果您将 lambda 更改为捕获 this 和/或 tree 对象,它是否有效,例如:[this][this, ui-&gt;productTree]
  • @Bobur 当我将 [=] 更改为 [this] 时,一切都是一样的,当我更改 = [this, ui->productTree] 时,我在令牌 ';' 之前被排除在外
  • @iLoveTatiaGaruchava 对我来说,您的代码工作正常,请尝试删除构建文件夹。为了测试您的代码,我必须对其进行修补,因此如果您发布 minimal reproducible example 会很有帮助

标签: c++ qt lambda signals-slots


【解决方案1】:

这听起来像是违反了单一定义规则 (ODR) - 可能是因为构建文件夹过时。问题是传递给connect方法的deleteRequest的地址与moc_CustomTreeWidget.cpp中可见的方法地址不同。删除构建文件夹,然后重试。如果它仍然不起作用,请开始减少您的问题:

  1. 在存储库中创建一个最小化分支(如果你不使用版本控制,你不会去任何地方最小化)。

  2. ui_CustomTreeWidget.h文件的内容复制粘贴到CustomTreeWidget.cpp文件中,删除#include这一行。

  3. 检查粘贴的内容是否具有正确类型的 productTree 对象的实例化。

  4. 如果正确,则从代码中删除其他所有内容,逐步重建并在每个仍可重现的步骤中提交到存储库。您最终应该得到一个最多 20-30 行的测试用例。而且问题很明显,或者您可以使用测试用例修改问题。

【讨论】:

  • 我正在尝试删除构建项目并重新构建,但情况相同。当我开始减少只是好奇时,我有一个问题.. 我不知道为什么,但我的 CustomTreeWidget 类有一个 UI。应该是吗? :D
  • 我删除了 UI,也清理了,运行 qmake rebuild 但一切都一样...我创建了一个测试项目,它可以工作...我不介意发生了什么。
  • clean 源文件夹开始。这意味着:制作源存储库的新克隆/工作副本,然后在 IDE 中打开它,配置构建,然后构建。
猜你喜欢
  • 2016-10-03
  • 2015-06-24
  • 1970-01-01
  • 2017-11-22
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多