feat(vqt6): 信号槽回调机制 + 高层包装类扩展

- 信号槽:vqt6_signal_register/trigger_slot 锁外回调,覆盖 QPushButton/QCheckBox/QRadioButton/QLineEdit/QComboBox/QSlider/QSpinBox/QProgressBar/QListWidget/QTabWidget/QAction/QTimer 共 13 个信号
- 高层包装:新增 QMainWindow/QDialog/QLineEdit/QCheckBox/QRadioButton/QComboBox/QSlider/QSpinBox/QProgressBar/QTextEdit/QPlainTextEdit/QListWidget/QTabWidget/QStackedWidget/QHBoxLayout/QVBoxLayout/QGridLayout/QMessageBox/QFileDialog/QTimer/QMenuBar/QMenu/QAction/QStatusBar/QColor/QFont 等 26 个类
- 便捷 FFI:vqt6_qlabel_set_text_utf8 / vqt6_qplaintextedit_append_utf8(Viper str 直传,避免 QString 手动管理)
- 修复:QApplication 构造需 int& 左值(dummy_argc);QCheckBox 用 checkStateChanged 避免弃用警告
This commit is contained in:
TermiNexus committed 2026-09-02 09:16:35 +08:00
1 parent 250be46051
commit 2aff684cc4
7 files changed
+1646 -5

No files matched your search

+147 -1
View File
@@ -56,7 +56,8 @@ extern "C" VQT6_API void* vqt6_qapplication_create(int argc, char** argv) {
if (argv == nullptr || argc <= 0) {
static char vqt6_dummy0[] = "vqt6_app";
static char* vqt6_dummy_argv[2] = { vqt6_dummy0, nullptr };
return new QApplication(1, vqt6_dummy_argv);
int dummy_argc = 1;
return new QApplication(dummy_argc, vqt6_dummy_argv);
}
return new QApplication(argc, argv);
}
@@ -477,6 +478,11 @@ extern "C" VQT6_API void vqt6_qlabel_set_text(void* label, void* text) {
static_cast<QLabel*>(label)->setText(*static_cast<QString*>(text));
}
extern "C" VQT6_API void vqt6_qlabel_set_text_utf8(void* label, const char* utf8) {
if (label == nullptr || utf8 == nullptr) return;
static_cast<QLabel*>(label)->setText(QString::fromUtf8(utf8));
}
extern "C" VQT6_API void* vqt6_qlabel_text(void* label) {
if (label == nullptr) return nullptr;
return new QString(static_cast<QLabel*>(label)->text());
@@ -757,6 +763,11 @@ extern "C" VQT6_API void vqt6_qplaintextedit_append(void* pte, void* text) {
static_cast<QPlainTextEdit*>(pte)->appendPlainText(*static_cast<QString*>(text));
}
extern "C" VQT6_API void vqt6_qplaintextedit_append_utf8(void* pte, const char* utf8) {
if (pte == nullptr || utf8 == nullptr) return;
static_cast<QPlainTextEdit*>(pte)->appendPlainText(QString::fromUtf8(utf8));
}
extern "C" VQT6_API void vqt6_qplaintextedit_clear(void* pte) {
if (pte == nullptr) return;
static_cast<QPlainTextEdit*>(pte)->clear();
@@ -1749,3 +1760,138 @@ extern "C" VQT6_API void* vqt6_qfiledialog_get_open_file_names(void* parent, voi
filter != nullptr ? *static_cast<QString*>(filter) : QString()
));
}
// ============================================================
// 信号连接(Qt 信号 → Viper 回调 vqt6_slot_callback_t)
// 模式:vqt6_signal_register 分配 slot_id → Qt lambda 连接信号 →
// 信号触发时 vqt6_trigger_slot(slot_id) 调回 Viper 回调
// ============================================================
extern "C" VQT6_API void vqt6_qpushbutton_connect_clicked(void* btn, vqt6_slot_callback_t cb, void* user_data) {
if (btn == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QPushButton*>(btn), &QPushButton::clicked,
static_cast<QPushButton*>(btn), [slot_id](bool) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qpushbutton_connect_toggled(void* btn, vqt6_slot_callback_t cb, void* user_data) {
if (btn == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QPushButton*>(btn), &QPushButton::toggled,
static_cast<QPushButton*>(btn), [slot_id](bool) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qcheckbox_connect_toggled(void* cb_widget, vqt6_slot_callback_t cb, void* user_data) {
if (cb_widget == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QCheckBox*>(cb_widget), &QCheckBox::toggled,
static_cast<QCheckBox*>(cb_widget), [slot_id](bool) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qcheckbox_connect_state_changed(void* cb_widget, vqt6_slot_callback_t cb, void* user_data) {
if (cb_widget == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QCheckBox*>(cb_widget), &QCheckBox::checkStateChanged,
static_cast<QCheckBox*>(cb_widget), [slot_id](Qt::CheckState) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qradiobutton_connect_toggled(void* rb, vqt6_slot_callback_t cb, void* user_data) {
if (rb == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QRadioButton*>(rb), &QRadioButton::toggled,
static_cast<QRadioButton*>(rb), [slot_id](bool) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qlineedit_connect_text_changed(void* le, vqt6_slot_callback_t cb, void* user_data) {
if (le == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QLineEdit*>(le), &QLineEdit::textChanged,
static_cast<QLineEdit*>(le), [slot_id](const QString&) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qcombobox_connect_current_index_changed(void* cb_widget, vqt6_slot_callback_t cb, void* user_data) {
if (cb_widget == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QComboBox*>(cb_widget), &QComboBox::currentIndexChanged,
static_cast<QComboBox*>(cb_widget), [slot_id](int) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qslider_connect_value_changed(void* s, vqt6_slot_callback_t cb, void* user_data) {
if (s == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QSlider*>(s), &QSlider::valueChanged,
static_cast<QSlider*>(s), [slot_id](int) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qspinbox_connect_value_changed(void* sb, vqt6_slot_callback_t cb, void* user_data) {
if (sb == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QSpinBox*>(sb), &QSpinBox::valueChanged,
static_cast<QSpinBox*>(sb), [slot_id](int) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qprogressbar_connect_value_changed(void* pb, vqt6_slot_callback_t cb, void* user_data) {
if (pb == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QProgressBar*>(pb), &QProgressBar::valueChanged,
static_cast<QProgressBar*>(pb), [slot_id](int) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qlistwidget_connect_current_row_changed(void* lw, vqt6_slot_callback_t cb, void* user_data) {
if (lw == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QListWidget*>(lw), &QListWidget::currentRowChanged,
static_cast<QListWidget*>(lw), [slot_id](int) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qtabwidget_connect_current_changed(void* tw, vqt6_slot_callback_t cb, void* user_data) {
if (tw == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QTabWidget*>(tw), &QTabWidget::currentChanged,
static_cast<QTabWidget*>(tw), [slot_id](int) {
vqt6_trigger_slot(slot_id);
});
}
extern "C" VQT6_API void vqt6_qaction_connect_triggered(void* action, vqt6_slot_callback_t cb, void* user_data) {
if (action == nullptr) return;
int slot_id = vqt6_signal_register(cb, user_data);
if (slot_id < 0) return;
QObject::connect(static_cast<QAction*>(action), &QAction::triggered,
static_cast<QAction*>(action), [slot_id](bool) {
vqt6_trigger_slot(slot_id);
});
}