【问题标题】:How to connect in Qt signal and slot in dynamically added buttons to get in slot index of added button?如何在动态添加的按钮中连接 Qt 信号和插槽以获取添加按钮的插槽索引?
【发布时间】:2017-07-23 13:03:23
【问题描述】:

我有一个带有指针 QPushButton 的列表:

QList<QPushButton*> listButtons;

在这段代码中,我正在添加动态按钮

listButtons.push_back(new QPushButton("Cancel", this)); 
connect(listButtons.last(), SIGNAL (clicked(listButtons.size)), this, SLOT(handleButton(int))); //this doesn't work

我怎样才能保存每个按钮的索引,这样我就可以跟踪用户点击了什么按钮,因为每个按钮都必须取消特定的任务。

我用的是C++98,所以不能用Lambda函数

【问题讨论】:

    标签: c++ qt button qt-signals slot


    【解决方案1】:

    您必须在您的插槽中使用sender() 函数。 像这样:

    void MainWindow::buttonClicked()
    {
        QObject *senderObj = sender(); // This will give Sender object
        QString senderObjName = senderObj->objectName();
        qDebug()<< "Button: " << senderObjName;
    }
    

    查看我为您制作的完整示例:

    .cpp 文件:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        for(int i =0; i<10; i++)
        {
            listButtons.push_back(createNewButton());
            connect(listButtons[i], &QPushButton::clicked, this, &MainWindow::buttonClicked);
            QString text = listButtons[i]->text();
    
            ui->widget->layout()->addWidget(listButtons[i]);
        }
    }
    
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    QPushButton* MainWindow::createNewButton()
    {
        QPushButton* button = new QPushButton("ButtonText");
        button->setObjectName("ButtonName");
        return button;
    }
    
    void MainWindow::buttonClicked()
    {
        QObject *senderObj = sender(); // This will give Sender object
        QString senderObjName = senderObj->objectName();
        qDebug()<< "Button: " << senderObjName;
    }
    

    .h 文件:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QDebug>
    #include <QPushButton>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
        QList<QPushButton*> listButtons;
    
        QPushButton *createNewButton();
        void buttonClicked();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    

    更多信息:

    sender() 函数返回一个指向发送信号的对象的指针,如果在被信号激活的槽中调用;否则返回 0。该指针仅在从该对象的线程上下文调用该函数的槽执行期间有效。

    警告:此函数违反了面向对象的模块化原则。但是,当多个信号连接到单个插槽时,访问发送器可能会很有用。

    【讨论】:

      【解决方案2】:

      一种简单的方法是在连接到信号的 lambda 中捕获索引(或您想要传递给插槽的任何内容),然后将其传递给插槽。

      大致思路是这样的:

      auto button = new QPushButton("Cancel", this);
      auto index = /* code to get what you want to pass */ ;
      connect(button, &QPushButton::clicked,
          this, [index, this](bool){ this->handleButton(index); });
      

      【讨论】:

      • 嘿,谢谢你的回答,我试过你的代码:QPushButton* btn = new QPushButton("Cancel", this); int index = listButtons.size()-1; QObject::connect(btn, &QPushButton::clicked, this, [index, this]{ this->handleButton(index); }); listButtons.push_back(btn);但它给了我错误:没有匹配函数调用 'ProgressDialog::connect(QPushButton*&, void (QAbstractButton::*)(bool), ProgressDialog*, ProgressDialog::updateDialog(QString):: )' this, [index, this]{ this->handleButton(index); });
      • 您没有指定您的 Qt 版本,也没有指定您使用的编译器或 C++ 版本,所以我只是假设 Qt 5.x 和 C++14。如果这不是真的,那么您可能对我编写的代码有问题。另外,现在我刚刚检查了 clicked 信号的文档,我注意到它包含一个 bool,所以 lambda 应该带一个参数,会更新。
      猜你喜欢
      • 2021-02-12
      • 1970-01-01
      • 2020-10-28
      • 2012-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-14
      • 1970-01-01
      相关资源
      最近更新 更多