C QT,通过回调
C++ Qt, Passing Callbacks
编辑#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
函数的当前对话框类的上下文中调用。
以下是原始帖子:
我最近开始使用QT将我的一个程序从基于文本的输入转换为GUI输入,但我遇到了一些障碍。我可能可以在QT中使用"正确执行此操作"的高级设计反馈,以及如何调试我当前问题的具体反馈。
首先,对我当前任务的快速描述(如果您不在乎,请直接跳到下面的代码):我将拥有大量的旋转式盒子 void callback_with_id(int id, int value)
的表单,其中 id
将是一个唯一的数字识别哪个自旋框的值已更改,而 value
当然是该旋转框的新值。
我设法创建了一个我喜欢的视觉布局,但是尝试将旋转框连接到回调功能引起了我的麻烦。这是我的代码,目前尚未编译。现在可以随意假装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);
^
我确定我在这里做错了一件事,对任何反馈都会很感激。
评论行的问题是您要混合两种不同的连接风格:"运行时"(使用SIGNAL
和SLOT
宏)和" Compile-time"(允许您的一个compile time"直接通过可可)。
通常的语法是
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)>
,然后通过呼叫站点捕获this
的lambda。
请让我知道您是否希望我详细说明这些要点!
- 架构决策:返回std::future还是提供回调
- 正在为Xtensa simcall函数编写回调函数
- 如何在C++中使用非静态成员函数作为回调函数
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 用于在回调中调用解析器的设计模式
- 如何使用C++对象的成员函数作为 C 样式回调?
- Java从C++回调到C++回调
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 与Qt同时运行后台循环或回调C++应用程序?
- C QT,通过回调
- Qt - 从回调发出信号
- 在Qt中实现回调
- 当更新值用作回调时,如何处理 QT/C++ 中的进度条
- CopyFileEx 在 Qt 中带有进度回调
- Qt Worker 线程 - 我必须为每个特定任务继承,还是可以使用回调
- 使用 Qt 信号和插槽实现 c++ 回调
- Qt 应用程序在从 <QUrl>NetworkAccessManager->get() 回调访问 QList<QLlnkedList* >时冻结
- QT中的程序终止回调
- C++,Qt,QtWebKit:如何创建一个html呈现窗口,以便您的应用程序从JS调用中获得回调