Edit #2: Figured out the lambda call syntax I need!
[=](int value) { (this->*callback_function)(i, value); }
Still looking for suggestions on how to better orchestrate this task... This seems way too messy.
Edit: Updated code, almost there but still hit a snag.
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);
}
I'm getting an error
error: must use '.*' or '->*' to call pointer-to-member function in 'callback_function (...)', e.g. '(... ->* callback_function) (...)'
[=](int value) { callback_function(i, value); } );
^
I've tried a few things like this->callback_function(i, value)
, but nothing I've tried yet has worked. I definitely do NOT want the callback to be static, that makes no sense, it should be called within the context of the current Dialog class which is calling the create_spinbox_column
function.
Below is the original post:
I recently started using Qt to convert one of my programs from a text-based input to a GUI input, but I'm hitting a few snags. I could probably use both high-level design feedback of how to do this "properly" in Qt, and specific feedback for how to debug my current problem.
First, a quick description of my current task (if you don't care, skip straight to my code below): I will have a large number of spinboxes which I want to be neatly organized and connected to a callback function of the form void callback_with_id(int id, int value)
, where id
would be a unique number identifying which spinbox's value was changed, and value
of course would be the new value of that spinbox.
I've managed to create a visual layout that I like, but trying to connect the spinboxes to a callback function is causing me troubles. Here's my code, which won't compile at the moment. Feel free to pretend ACCOUNT_DATA_COLS = 1
for now.
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);
}
(I commented out the connect line because I was getting a compiler error.)
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);
}
and my callback function:
void Dialog::callback_with_id(int id, int value) {
std::cout << "callback_with_id(" << value << ", " << id << ")" << std::endl;
}
I'm getting the error
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);
^
I'm sure I'm doing more than one thing wrong here, would be grateful for any feedback.