为什么我尝试将按钮连接到 lambda 失败

Why does my attempt at connecting a pushbutton to a lambda fail?

本文关键字:连接 lambda 失败 按钮 为什么      更新时间:2023-10-16

我在尝试使用 lambda 表达式在按钮和单击按钮时要调用的函数之间建立联系时遇到了一些问题。

我使用的是Qt 5.6,编译器MinGW 4.9.2(默认版本)。我的代码如下:

在主窗口中.cpp :

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initBuildings();
    initPage();
    for (int i(0); i<buildings.size(); ++i) {
        connect(static_cast<QAbstractButton*>(widgetlist.at(i).at(2)), &QAbstractButton::clicked, [this, i]() {
            buildings.at(i).buy(amountMultiplier);});
    }
}
void MainWindow::initBuildings()
{
    Building b1 = Building("Building 1",100,1,200);
    Building b2 = Building("Building 2",1000,10,2000);
    buildings.append(b1);
    buildings.append(b2);
}
void MainWindow::initPage()
{
    for (int i(0); i<buildings.size(); i++) {
        QList<QWidget *> buttons;
        QLabel *namelabel = new QLabel(buildings.at(i).getName());
        QLabel *amountlabel = new QLabel;
        QPushButton *buybutton = new QPushButton(this);
        QPushButton *upgradebutton = new QPushButton(this);
        amountlabel->setFixedSize(50,40);
        buybutton->setFixedSize(100,40);
        upgradebutton->setFixedSize(100,40);
        buttons.append(namelabel);
        buttons.append(amountlabel);
        buttons.append(buybutton);
        buttons.append(upgradebutton);
        widgetlist.append(buttons);
    }
}

在主窗口中:

#include <QMainWindow>
#include <QScrollArea>
#include <QList>
#include <building.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    void initBuildings();
    void initPage();
    Ui::MainWindow *ui;
    int amountMultiplier;
    QList<Building> buildings;
    QList<QList<QWidget*>> widgetlist;
};

"Building"是我创建的类,它不会从另一个类继承。我想使用的函数是此类的公共函数:

void buy(int amount) const; 

它无法编译,我收到几个错误:

  • no matching function for call to 'MainWindow::connect(QAbstractButton*, void (QAbstractButton::*)(bool), MainWindow::MainWindow(QWidget*)::<lambda()>)
  • invalid use of incomplete type 'struct QtPrivate::QEnableIf< false, QMetaObject::Connection>
  • cannot convert '<lambda closure object>MainWindow::MainWindow(QWidget*)::< lambda()>{((MainWindow*)this), i}' (type 'MainWindow::MainWindow(QWidget*)::< lambda()>') to type 'const QObject*

我试图更改 lambda 捕获列表,或更改我在列表中获取值的方式,但它不会改变任何东西,而且我不明白问题出在哪里。也许我在使用λ时错了?

两个问题:

  1. buildings.at()返回一个const Building &,并且buy方法不是常量。必须改用[]为建筑物编制索引。

  2. widgetlist.at(i).at(2) 返回的类型绝对不是QPushButton* - 如果是,代码将编译。甚至错误消息也指示问题所在:

没有匹配函数调用'MainWindow::connect(QWidget* const&, void (QAbstractButton::*)(bool), [...])

这将编译:

// https://github.com/KubaO/stackoverflown/tree/master/questions/lambda-list-37615204
#include <QtWidgets>
struct Building {
   void buy() {}
};
class Class : public QObject {
   QList<Building> m_buildings;
   QList<QList<QWidget*>> m_widgets;
public:
   Class() {
      for (int i = 0; i<m_buildings.size(); ++i)
         connect(static_cast<QAbstractButton*>(m_widgets.at(i).at(2)), &QAbstractButton::clicked, [=] {
            m_buildings[i].buy();
         });
   }
};
int main() {}

如果您希望在面对编程错误时采取额外的安全措施,请将static_cast替换为qobject_cast,然后如果您投射非按钮而不是做一些可能具有误导性的事情,它将中止。

根据文档,您的 lambda 应该接受bool参数。