Qt - 使用 lambda 函数修改先前连接信号的插槽参数

Posted

技术标签:

【中文标题】Qt - 使用 lambda 函数修改先前连接信号的插槽参数【英文标题】:Qt - modify slot's parameter of previous connected signal using lambda function 【发布时间】:2017-03-23 14:25:48 【问题描述】:

我正在尝试使用不同的参数将信号重新连接到同一个插槽。如果我只是想在不使用参数或 lambda 函数的情况下将相同的信号重新连接到不同的插槽,这将起作用,但我需要这样做。

起初我尝试过这样的事情:

connect(remove_btn,&QPushButton::clicked,[this, id] function1(varA););
connect(remove_btn,&QPushButton::clicked,[this, id] function1(varB););

function1 接收 varA 并且从不接收 varB

我找到了一种方法,方法是保留连接列表,当我想修改参数时,我会断开旧连接并建立新连接。

我想知道的是,是否有一种方法可以进行此修改,而无需跟踪所有连接并完成断开连接/连接过程。

【问题讨论】:

@AlexanderVX 忘记“id”变量。我忘了从我的例子中删除它,这无关紧要。关于您的示例,我不确定您要向我展示什么,但是两个连接都具有相同的参数,这不是我的问题。不过还是谢谢。 【参考方案1】:

我想到了两个解决方案:

    通过引用捕获var 并更改它而不是重新连接:

    class Foo : public QWidget 
      Q_OBJECT
      int remove_btn_var;
      int varA = 10, varB = 20;
      QPushButton remove_btn;
      void function1(int);
    public:
      Foo() 
        remove_btn_var = varA;
        connect(&remove_btn, &QPushButton::clicked, [&]  function1(remove_btn_var); );
      
      void switch() 
        remove_btn_var = varB;
      
    ;
    

    为按钮添加一个可以修改的属性:

    static const char k_function1_var[] = "function1_var";
    class Foo : public QWidget 
      Q_OBJECT
      int varA, varB;
      QPushButton remove_btn;
      void function1(int);
    public:
      Foo() 
        remove_btn.setProperty(k_function1_var, varA);
        connect(&remove_btn, &QPushButton::clicked, [this]  
          function1(remove_btn.property(k_function1_var).toInt())
        );
      
      void switch() 
        remove_btn.setProperty(k_function1_var, varB);
      
    ;
    

【讨论】:

我根据您的想法想出了一个解决方案。我的班级有一个保存 id 号的变量(让我们将其命名为var_id)。现在我将只使用connect(remove_btn, &QPushButton::clicked, [this] function1(myClass->var_id);); 并更改function1() 中的var_id 值。这样,它会更改连接值。这个想法之前有点在我的脑海里闪过,但不知何故我忽略了它。感谢您的帮助。【参考方案2】:

您也许可以使用std::bind,因为QPushButton::clicked 信号有1 个参数(bool checked),使用它应该足够了:

auto f = std::bind(function1, varA); // checked argument ignored (std::placeholders::_1)
connect(remove_btn,&QPushButton::clicked,f);

【讨论】:

bind() 不起作用,它给了我错误“没有重载 bind() 的实例...),但我使用正确的参数相应地使用它,我什至检查了其他示例. 也许这与我的项目有关,但无论如何我找到了解决问题的方法,谢谢@xander

以上是关于Qt - 使用 lambda 函数修改先前连接信号的插槽参数的主要内容,如果未能解决你的问题,请参考以下文章

使用 lambda 函数了解 QProcess 信号的行为

模板参数推导与 QT lambda 不匹配

Qt Lambda表达式的运用

在 for 循环中使用 lambda 函数连接信号槽

qt 5信号和槽的新形式,附带lambda表达式在这里的应用(偷懒的神器) qt官方蓝牙的btcha这个demot的个人解读

QT两个窗口间的相互切换