C++ QObject::connect:在具有Lambda语法的升级小部件中未找到信号

C++ QObject::connect:在具有Lambda语法的升级小部件中未找到信号,c++,qt,lambda,signals-slots,C++,Qt,Lambda,Signals Slots,我有一个重载的QTreeWidget类,带有我的信号:我在UI中提升了它,当我使用lambda语法侦听提升的QTreeWidget对象时,我有一个错误 QObject::connect: signal not found in CustomTreeWidget. 我的CustomTreeWidget看起来像: connect(ui->productTree, &CustomTreeWidget::deleteRequest, this, [=](QVector<int>

我有一个重载的QTreeWidget类,带有我的信号:我在UI中提升了它,当我使用lambda语法侦听提升的QTreeWidget对象时,我有一个错误

QObject::connect: signal not found in CustomTreeWidget.
我的CustomTreeWidget看起来像:

connect(ui->productTree, &CustomTreeWidget::deleteRequest, this, [=](QVector<int> uids) {
    //logic
});
.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);
}
class CustomTreeWidget:publicQTreeWidget
{
Q_对象
公众:
显式CustomTreeWidget(QWidget*parent=0);
~CustomTreeWidget(){
}
信号:
void currentNodeChanged(QSet UID);
无效删除请求(QVector 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);
}
CustomTreeWidget::CustomTreeWidget(QWidget*父项):QTreeWidget(父项)
{
设置动画(真);
连接(此,&CustomTreeWidget::customContextMenuRequested,此,[=](常量QPoint&pos){
此->m_bCustomMenuOpen=true;
const auto&&item=this->itemAt(pos);
QMenu我的菜单;
bool ok=!(项目)?false:true;
如果(确定){
//თუ 顶级项目-ია მხოლოდ დამატების 行动-ი უნდა იყოს ჩართული.
如果(项==此->topLevelItem(0)| |项==此->topLevelItem(0)->子项(0)){
ok=假;
}
}
QAction*Removecnt=myMenu.addAction(tr(“&წაშლა"), 这个,SLOT(DeleteNode());
移除->设置图标(QIcon(:/global_res/delete.png));
Removecnt->setEnabled(确定);
myMenu.exec(this->mapToGlobal(pos));
});
}
作废CustomTreeWidget::BFS(QTreeWidgetItem*item,QSet&out)
{
std::队列Q;
Q.推动(项目);
而(!Q.empty()){
QTreeWidgetItem*now=Q.front();Q.pop();
out.insert(this->m_mapUids[now]);
对于(int i=0;ichildCount();i++){
推(现在->孩子(我));
}
}
}
QSet CustomTreeWidget::GetCurrentNodeUids()
{
QSet-uids;
如果(!this->currentItem())
返回UID;
此->BFS(此->当前项(),uids);
返回UID;
}
void CustomTreeWidget::DeleteNode()
{
QSet nodes=this->GetCurrentNodeUids();
矢量UID;
用于(自动it:节点){
uids。推回(it);
}
发出删除请求(uids);
}
我的lambda看起来像:

connect(ui->productTree, &CustomTreeWidget::deleteRequest, this, [=](QVector<int> uids) {
    //logic
});
connect(ui->productTree,&CustomTreeWidget::deleteRequest,这,[=](QVector UID){
//逻辑
});
但是这个信号使用旧的语法

connect(ui->productTree, SIGNAL(deleteRequest(QVector<int>)), this, SLOT(checkSlot(QVector<int>)));
connect(ui->productTree,SIGNAL(deleteRequest(QVector)),this,SLOT(checkSlot(QVector));
这个插槽是

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

qDebug()这闻起来像是违反了一个定义规则(ODR)-可能是由于生成文件夹过时。问题是传递给
connect
方法的
deleteRequest
的地址与从
moc\u CustomTreeWidget.cpp
可见的方法的地址不同。请删除生成文件夹,然后重试。如果仍然不起作用,请开始减少问题:

  • 在存储库中创建一个最小化分支(如果您不使用版本控制,那么就不会使用最小化)

  • ui\u CustomTreeWidget.h
    文件的内容复制粘贴到
    CustomTreeWidget.cpp
    文件中,删除
    #include

  • 检查粘贴的内容是否实例化了类型正确的
    productTree
    对象

  • 如果这是正确的,那么就从代码中删除所有其他内容,一步一步地重建并提交到存储库中,每个步骤都会继续复制。您应该得到一个最多20-30行的测试用例。您可能会发现问题所在,也可能会用测试用例修改问题


  • 你确定,你写的错误与新语法有关吗?当你使用旧语法时,它看起来像是运行时的错误。是的,我确定。如果我使用新语法,我在运行时遇到的错误。但是旧语法一切正常。这可能是上下文问题。如果你将lambda更改为捕获
    和/或
    对象,如o:
    [this]
    [this,ui->productTree]
    ?@Bobur当我将[=]更改为[this]时,一切都是一样的,当我更改=[this,ui->productTree]我已经排除了标记“;”@iLoveTatiaGaruchava对我来说,你的代码工作正常,请尝试删除生成文件夹。为了测试你的代码,我必须对其进行修补,这样如果你发布一个我正在尝试删除生成项目并重新生成,它会有很大帮助,但情况相同。当我好奇地开始还原时,我有一个问题..我不知道为什么,但我的CustomTreeWidget类有一个UI。应该是吗?:DI删除了UI,也清理了,运行了qmake rebuild,但一切都是一样的…我创建了一个测试项目,它工作了…我不介意发生了什么。从一个干净的源文件夹开始。这意味着:对源存储库进行一个新的克隆/工作副本,然后在IDE中打开它,共同完成一个构建,然后再重新创建乌尔德。