编辑#2:找出我需要的lambda调用语法!
[=](int value) { (this->*callback_function)(i, value); }
仍在寻找有关如何更好地协调此任务的建议......这看起来太乱了。
编辑:更新了代码,几乎在那里,但仍然遇到了障碍。
template <typename F>
void Dialog::create_spinbox_column(const int &NUM_ROWS, QFrame *&frame,
QLabel *label_arr[],
QSpinBox *spinbox_arr[],
F callback_function) {
frame = new QFrame();
QGridLayout *layout = new QGridLayout;
for(int i = 0; i < NUM_ROWS; i++) {
int row = i+1;
QString label_text = QObject::tr("Line %1:").arg(row);
label_arr[i] = new QLabel(label_text);
spinbox_arr[i] = new QSpinBox;
layout->addWidget(label_arr[i], row, 1);
layout->addWidget(spinbox_arr[i], row, 2);
QObject::connect(spinbox_arr[i], qOverload<int>(&QSpinBox::valueChanged), this,
[=](int value) { callback_function(i, value); } );
}
frame->setLayout(layout);
}
我收到错误
error: must use '.*' or '->*' to call pointer-to-member function in 'callback_function (...)', e.g. '(... ->* callback_function) (...)'
[=](int value) { callback_function(i, value); } );
^
我尝试过this->callback_function(i, value)
之类的一些事情,但我尝试过的任何事情都没有奏效。我绝对不希望回调是静态的,这没有意义,它应该在当前调用create_spinbox_column
函数的Dialog类的上下文中调用。
以下是原帖:
我最近开始使用Qt将我的一个程序从基于文本的输入转换为GUI输入,但我遇到了一些障碍。我可以使用高级设计反馈如何做到这一点&#34;正确&#34;在Qt中,以及如何调试当前问题的具体反馈。
首先,快速描述我当前的任务(如果你不在乎,直接跳到下面我的代码):我将有大量的旋转盒,我希望整齐地组织并连接到回调void callback_with_id(int id, int value)
形式的函数,其中id
将是一个唯一的数字,用于标识哪个旋转框的值已更改,而value
当然是该旋转框的新值。< / p>
我设法创建了一个我喜欢的视觉布局,但是尝试将spinbox连接到回调函数会给我带来麻烦。这是我的代码,目前还没有编译。请暂时假装ACCOUNT_DATA_COLS = 1
。
void Dialog::create_spinbox_column(const int &NUM_ROWS, QFrame *&frame,
QLabel **label_arr,
QSpinBox **spinbox_arr,
void (*callback_function)(int, int)) {
frame = new QFrame();
QGridLayout *layout = new QGridLayout;
for(int i = 0; i < NUM_ROWS; i++) {
int row = i+1;
QString label_text = QObject::tr("Line %1:").arg(row);
label_arr[i] = new QLabel(label_text);
spinbox_arr[i] = new QSpinBox;
layout->addWidget(label_arr[i], row, 1);
layout->addWidget(spinbox_arr[i], row, 2);
//QObject::connect(spinbox_arr[i], SIGNAL(valueChanged(int)), this,
// [=](int value) { callback_function(i, value); };
}
frame->setLayout(layout);
}
(我注释掉了连线,因为我收到了编译错误。)
void Dialog::create_account_data_grid() {
account_data_box = new QGroupBox(tr("Account Data"));
QHBoxLayout *layout = new QHBoxLayout;
for (int i = 0; i < ACCOUNT_DATA_COLS; i++) {
QFrame *frame;
QLabel *label_arr[ACCOUNT_DATA_ROWS];
QLabel *spinbox_arr[ACCOUNT_DATA_ROWS];
create_spinbox_column(ACCOUNT_DATA_ROWS, frame, label_arr, spinbox_arr,
callback_with_id);
// int col = i + 1;
layout->addWidget(frame);
}
account_data_box->setLayout(layout);
}
和我的回调函数:
void Dialog::callback_with_id(int id, int value) {
std::cout << "callback_with_id(" << value << ", " << id << ")" << std::endl;
}
我收到了错误
error: no matching function for call to 'Dialog::create_spinbox_column(const int&, QFrame*&, QLabel* [8], QLabel* [8], <unresolved overloaded function type>)'
callback_with_id);
^
我确定我在这里做了不止一件事,不胜感激任何反馈。
答案 0 :(得分:3)
注释行的问题在于您混合了两种不同类型的连接:&#34;运行时&#34; (使用SIGNAL
和SLOT
宏)和&#34;编译时&#34; (允许你直接传递callable的那个)。
通常后者的语法是
QObject::connect(spinbox_arr[i], &QSpinBox::someSignal, this,
[=](int value) { callback_function(i, value); };
但你不能直接对valueChanged
信号执行此操作,因为它有两个重载,因此您必须使用qOverload,因此生成的代码将如下所示:
QObject::connect(spinbox_arr[i], qOverload<int>(&QSpinBox::valueChanged), this,
[=](int value) { callback_function(i, value); };
这需要一些C ++ 14支持。如果您还没有,那么您必须使用QOverload<int>::of(&QSpinBox::valueChanged)
。
另外,正如评论中所指出的,请确保:
callback_with_id
是一个静态函数,create_spinbox_column
模仿仿函数类型,create_spinbox_column
的最后一个参数更改为std::function<void(int, int)>
并在呼叫站点传递lambda capture this
。如果您希望我详细说明这些要点,请告诉我们。