在GUI应用程序中,我有很多正在使用的按钮。这些按钮标记为pbxx
,其中xx
是网格布局中按钮的行号和列号。按下按钮时,需要突出显示。今天我读到了lambda函数Brian Poteat& Kuba Ober并且我想我会尝试在我的代码中实现这一点。
在我的GuiDisplay类(继承QMainWindow的类)中,我有一个名为的函数:
make_connections();
这会使我的所有按钮连接(所有信号都连接到一个插槽on_pushbutton_clicked()
。我在这里添加了代码:
class GuiDisplay : public QMainWindow
{
Q_OBJECT
public:
explicit GuiDisplay(QWidget *parent = 0);
~GuiDisplay();
... Some more public functions ...
/**
* @brief Connects all custom signals and slots.
*/
void make_connections();
/**
* @brief Will highlight the provided pushbutton with provided rgb colour
*/
void highlight_pushbutton(QPushButton &pb, const int rgb[]);
private slots:
void on_pushbutton_clicked(const QString& label);
private:
Ui::GuiDisplay *ui;
};
void GuiDisplay::make_connections()
{
// Loop through all the pushbuttons and connect clicked signal to clicked slot
QString pb_label = "";
for(int i = 0; i < 8; ++i)
{
for(int j = 0; j < 8; ++j)
{
// Find the pushbutton
pb_label = "pb" + QString::number(i) + QString::number(j);
QPushButton* pb_ptr = this->findChild<QPushButton*>(pb_label);
//connect(pb_ptr, SIGNAL(clicked()), this, SLOT(on_pushbutton_clicked()));
connect(pb_ptr, &QPushButton::clicked, [this]{on_pushbutton_clicked(pb_label);});
}
}
}
当我建立连接时出现问题
connect(pb_ptr, &QPushButton::clicked, [this]{on_pushbutton_clicked(pb_label);});
构建给我以下错误
'pb_label' is not captured
所以我认为好了,那么做以下事情似乎不错:
connect(pb_ptr, &QPushButton::clicked, [this, &pb_label]{on_pushbutton_clicked(pb_label);});
构建时的错误消失了,但是只要执行此代码,我的GUI应用程序就会意外崩溃。不知道为什么。这里有什么帮助?
答案 0 :(得分:2)
您的错误是由于使用了对临时的引用。 pb_label
仅在Qt存储lambda的GuiDisplay::make_connections
期间存在,并且每次触发信号时都会引用connect(pb_ptr, &QPushButton::clicked, [=]{ on_pushbutton_clicked(pb_label); });
。当发生这种情况时,您将引用被破坏的物体。
所以建立连接的正确方法是:
connect(pb_str, &QPushButton::clicked, this, [=]{ on_pushbutton_clicked(pb_label); });
从Qt 5.2开始,添加了QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection)
重载,它将在对象的生命周期结束时自动断开连接。在这种情况下,连接将是:
connect(pb_ptr, &QPushButton::clicked, this, &GuiDisplay::on_pushbutton_clicked);
那说你不应该在这里使用lambda:
GuiDisplay::on_pushbutton_clicked
然后修改你的GuiDisplay::on_pushbutton_clicked
不要参数。您可以通过调用sender()
来获取pb_label
中对象的名称:
返回指向发送信号的对象的指针
然后使用QObject::objectName
获取pb_label
:
此属性包含此对象的名称
因此,您只需要将sender()->objectName()
替换为:QString
直接插槽连接优于lambda有几个原因:
pb_label
QObject
的需要
接收器&#39;没有自动断开连接。被破坏是因为它是一个没有
$baseUrl = Yii::$app->request->baseUrl; $script = <<< JS $('#selectedsession').on('change',function(){ var value1 = document.getElementById("selectedclass").value; var value2 = document.getElementById("selectedsession").value; $.ajax({ url: '{$baseUrl}/enrollment/rollno', type: "POST", data: { value1: value1, value2 : value2 }, success: function(data) { var abc = data; $("#roll").val(abc); } }); }); JS;
的仿函数。
答案 1 :(得分:1)
谢谢Piotr Skotnicki和Simple,你的两个建议都有效。我可能应该进一步阅读,我会在捕获列表中看到[=](参见:Lambda)
因此,导致问题的一行代码可以是:
connect(pb_ptr, &QPushButton::clicked, [this, pb_label]{on_pushbutton_clicked(pb_label);});
或
connect(pb_ptr, &QPushButton::clicked, [=]{on_pushbutton_clicked(pb_label);});