// ============================================================ // vqt6/_bridge_widgets.cpp — QtWidgets C 桥接层实现 // ============================================================ #include "_bridge.h" #include "_bridge_widgets.h" #include "_bridge_gui.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // ============================================================ // QApplication // ============================================================ extern "C" VQT6_API void* vqt6_qapplication_create(int argc, char** argv) { // Viper 端可能传 null argv(QApplication([]));Qt 构造需有效 argv, // 提供 static 虚拟 argv(生命周期=程序结束,QApplication 持有指针引用) if (argv == nullptr || argc <= 0) { static char vqt6_dummy0[] = "vqt6_app"; static char* vqt6_dummy_argv[2] = { vqt6_dummy0, nullptr }; int dummy_argc = 1; return new QApplication(dummy_argc, vqt6_dummy_argv); } return new QApplication(argc, argv); } extern "C" VQT6_API void* vqt6_qapplication_instance(void) { return QApplication::instance(); } extern "C" VQT6_API int vqt6_qapplication_exec(void* app) { if (app == nullptr) return -1; return static_cast(app)->exec(); } extern "C" VQT6_API void vqt6_qapplication_quit(void* app) { if (app == nullptr) return; static_cast(app)->quit(); } extern "C" VQT6_API void vqt6_qapplication_exit(void* app, int exit_code) { if (app == nullptr) return; static_cast(app)->exit(exit_code); } // ============================================================ // 应用调色板主题(原生控件:复选框/滚动条/高亮 等按此配色) // ============================================================ extern "C" VQT6_API void vqt6_qapplication_set_theme_palette(void* app, int theme) { QApplication* a = (app != nullptr) ? static_cast(app) : static_cast(QApplication::instance()); if (a == nullptr) return; QPalette p; if (theme != 0) { // 浅色 p.setColor(QPalette::Window, QColor(0xf5, 0xf6, 0xf8)); p.setColor(QPalette::WindowText, QColor(0x1e, 0x1e, 0x1e)); p.setColor(QPalette::Base, QColor(0xff, 0xff, 0xff)); p.setColor(QPalette::AlternateBase, QColor(0xef, 0xf2, 0xf6)); p.setColor(QPalette::ToolTipBase, QColor(0xff, 0xff, 0xff)); p.setColor(QPalette::ToolTipText, QColor(0x1e, 0x1e, 0x1e)); p.setColor(QPalette::Text, QColor(0x1e, 0x1e, 0x1e)); p.setColor(QPalette::Button, QColor(0xff, 0xff, 0xff)); p.setColor(QPalette::ButtonText, QColor(0x1e, 0x1e, 0x1e)); p.setColor(QPalette::BrightText, QColor(0x1e, 0x1e, 0x1e)); p.setColor(QPalette::Link, QColor(0x2a, 0x6d, 0xa8)); p.setColor(QPalette::Highlight, QColor(0x2a, 0x6d, 0xa8)); p.setColor(QPalette::HighlightedText, QColor(0xff, 0xff, 0xff)); p.setColor(QPalette::PlaceholderText, QColor(0x8a, 0x93, 0xa1)); p.setColor(QPalette::Disabled, QPalette::Text, QColor(0x9a, 0xa3, 0xb0)); p.setColor(QPalette::Disabled, QPalette::WindowText, QColor(0x9a, 0xa3, 0xb0)); p.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(0x9a, 0xa3, 0xb0)); } else { // 深色 p.setColor(QPalette::Window, QColor(0x1e, 0x1e, 0x1e)); p.setColor(QPalette::WindowText, QColor(0xd4, 0xd4, 0xd4)); p.setColor(QPalette::Base, QColor(0x1a, 0x1a, 0x1a)); p.setColor(QPalette::AlternateBase, QColor(0x25, 0x25, 0x26)); p.setColor(QPalette::ToolTipBase, QColor(0x25, 0x25, 0x26)); p.setColor(QPalette::ToolTipText, QColor(0xd4, 0xd4, 0xd4)); p.setColor(QPalette::Text, QColor(0xd4, 0xd4, 0xd4)); p.setColor(QPalette::Button, QColor(0x33, 0x33, 0x33)); p.setColor(QPalette::ButtonText, QColor(0xff, 0xff, 0xff)); p.setColor(QPalette::BrightText, QColor(0xff, 0xff, 0xff)); p.setColor(QPalette::Link, QColor(0x4a, 0x86, 0xc8)); p.setColor(QPalette::Highlight, QColor(0x2a, 0x6d, 0xa8)); p.setColor(QPalette::HighlightedText, QColor(0xff, 0xff, 0xff)); p.setColor(QPalette::PlaceholderText, QColor(0x9a, 0x9a, 0x9a)); p.setColor(QPalette::Disabled, QPalette::Text, QColor(0x66, 0x66, 0x66)); p.setColor(QPalette::Disabled, QPalette::WindowText, QColor(0x66, 0x66, 0x66)); p.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(0x66, 0x66, 0x66)); } a->setPalette(p); } extern "C" VQT6_API void vqt6_qapplication_process_events(void* app) { if (app == nullptr) return; static_cast(app)->processEvents(); } extern "C" VQT6_API int vqt6_qapplication_desktop_width(void* app) { if (app == nullptr) return 0; QScreen* screen = static_cast(app)->primaryScreen(); return screen != nullptr ? screen->size().width() : 0; } extern "C" VQT6_API int vqt6_qapplication_desktop_height(void* app) { if (app == nullptr) return 0; QScreen* screen = static_cast(app)->primaryScreen(); return screen != nullptr ? screen->size().height() : 0; } extern "C" VQT6_API void vqt6_qapplication_set_quit_on_last_window_closed(void* app, int quit) { if (app == nullptr) return; static_cast(app)->setQuitOnLastWindowClosed(quit != 0); } extern "C" VQT6_API int vqt6_qapplication_quit_on_last_window_closed(void* app) { if (app == nullptr) return 0; return QApplication::quitOnLastWindowClosed() ? 1 : 0; } extern "C" VQT6_API void vqt6_qapplication_set_font_family_utf8(void* app, const char* family) { if (family == nullptr) return; QApplication* a = (app != nullptr) ? static_cast(app) : static_cast(QApplication::instance()); if (a == nullptr) return; // 只换字体族:从当前应用字体克隆,字号/字重/斜体等全部保持不变。 // 不能直接 QFont(family) —— 那个构造把 pointSize 置为 -1,实际字号会被 // 平台默认值改写,整个界面的字号会跟着变。 QFont f = QApplication::font(); f.setFamily(QString::fromUtf8(family)); QApplication::setFont(f); } // ============================================================ // QWidget // ============================================================ extern "C" VQT6_API void* vqt6_qwidget_create(void) { return new QWidget(); } extern "C" VQT6_API void* vqt6_qwidget_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QWidget(static_cast(parent)); } extern "C" VQT6_API void vqt6_qwidget_show(void* widget) { if (widget == nullptr) return; static_cast(widget)->show(); } extern "C" VQT6_API void vqt6_qwidget_hide(void* widget) { if (widget == nullptr) return; static_cast(widget)->hide(); } extern "C" VQT6_API int vqt6_qwidget_close(void* widget) { if (widget == nullptr) return 0; return static_cast(widget)->close() ? 1 : 0; } extern "C" VQT6_API int vqt6_qwidget_is_visible(void* widget) { if (widget == nullptr) return 0; return static_cast(widget)->isVisible() ? 1 : 0; } extern "C" VQT6_API void vqt6_qwidget_set_visible(void* widget, int visible) { if (widget == nullptr) return; static_cast(widget)->setVisible(visible != 0); } extern "C" VQT6_API void vqt6_qwidget_set_geometry(void* widget, int x, int y, int w, int h) { if (widget == nullptr) return; static_cast(widget)->setGeometry(x, y, w, h); } extern "C" VQT6_API void vqt6_qwidget_geometry(void* widget, int* x, int* y, int* w, int* h) { if (widget == nullptr) return; QRect r = static_cast(widget)->geometry(); if (x != nullptr) *x = r.x(); if (y != nullptr) *y = r.y(); if (w != nullptr) *w = r.width(); if (h != nullptr) *h = r.height(); } extern "C" VQT6_API void vqt6_qwidget_resize(void* widget, int w, int h) { if (widget == nullptr) return; static_cast(widget)->resize(w, h); } extern "C" VQT6_API void vqt6_qwidget_size(void* widget, int* w, int* h) { if (widget == nullptr) return; QSize s = static_cast(widget)->size(); if (w != nullptr) *w = s.width(); if (h != nullptr) *h = s.height(); } extern "C" VQT6_API void vqt6_qwidget_move(void* widget, int x, int y) { if (widget == nullptr) return; static_cast(widget)->move(x, y); } extern "C" VQT6_API void vqt6_qwidget_pos(void* widget, int* x, int* y) { if (widget == nullptr) return; QPoint p = static_cast(widget)->pos(); if (x != nullptr) *x = p.x(); if (y != nullptr) *y = p.y(); } extern "C" VQT6_API int vqt6_qwidget_width(void* widget) { if (widget == nullptr) return 0; return static_cast(widget)->width(); } extern "C" VQT6_API int vqt6_qwidget_height(void* widget) { if (widget == nullptr) return 0; return static_cast(widget)->height(); } extern "C" VQT6_API int vqt6_qwidget_x(void* widget) { if (widget == nullptr) return 0; return static_cast(widget)->x(); } extern "C" VQT6_API int vqt6_qwidget_y(void* widget) { if (widget == nullptr) return 0; return static_cast(widget)->y(); } extern "C" VQT6_API void vqt6_qwidget_set_window_title(void* widget, void* title) { if (widget == nullptr || title == nullptr) return; static_cast(widget)->setWindowTitle(*static_cast(title)); } extern "C" VQT6_API void* vqt6_qwidget_window_title(void* widget) { if (widget == nullptr) return nullptr; return new QString(static_cast(widget)->windowTitle()); } extern "C" VQT6_API void vqt6_qwidget_set_text(void* widget, void* text) { if (widget == nullptr || text == nullptr) return; static_cast(widget)->setWindowTitle(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qwidget_text(void* widget) { if (widget == nullptr) return nullptr; return new QString(static_cast(widget)->windowTitle()); } extern "C" VQT6_API void vqt6_qwidget_set_enabled(void* widget, int enabled) { if (widget == nullptr) return; static_cast(widget)->setEnabled(enabled != 0); } extern "C" VQT6_API int vqt6_qwidget_is_enabled(void* widget) { if (widget == nullptr) return 0; return static_cast(widget)->isEnabled() ? 1 : 0; } extern "C" VQT6_API void vqt6_qwidget_set_parent(void* widget, void* parent) { if (widget == nullptr) return; static_cast(widget)->setParent(static_cast(parent)); } extern "C" VQT6_API void* vqt6_qwidget_parent_widget(void* widget) { if (widget == nullptr) return nullptr; return static_cast(widget)->parentWidget(); } extern "C" VQT6_API void vqt6_qwidget_set_focus(void* widget) { if (widget == nullptr) return; static_cast(widget)->setFocus(); } extern "C" VQT6_API void vqt6_qwidget_clear_focus(void* widget) { if (widget == nullptr) return; static_cast(widget)->clearFocus(); } extern "C" VQT6_API int vqt6_qwidget_has_focus(void* widget) { if (widget == nullptr) return 0; return static_cast(widget)->hasFocus() ? 1 : 0; } extern "C" VQT6_API void vqt6_qwidget_set_focus_policy(void* widget, int policy) { if (widget == nullptr) return; static_cast(widget)->setFocusPolicy(static_cast(policy)); } extern "C" VQT6_API void vqt6_qwidget_update(void* widget) { if (widget == nullptr) return; static_cast(widget)->update(); } extern "C" VQT6_API void vqt6_qwidget_repaint(void* widget) { if (widget == nullptr) return; static_cast(widget)->repaint(); } extern "C" VQT6_API void vqt6_qwidget_set_update_enabled(void* widget, int enabled) { if (widget == nullptr) return; static_cast(widget)->setUpdatesEnabled(enabled != 0); } extern "C" VQT6_API void vqt6_qwidget_set_window_flags(void* widget, int flags) { if (widget == nullptr) return; static_cast(widget)->setWindowFlags(static_cast(flags)); } extern "C" VQT6_API int vqt6_qwidget_window_flags(void* widget) { if (widget == nullptr) return 0; return static_cast(static_cast(widget)->windowFlags()); } extern "C" VQT6_API void vqt6_qwidget_set_cursor(void* widget, void* cursor) { if (widget == nullptr || cursor == nullptr) return; static_cast(widget)->setCursor(*static_cast(cursor)); } extern "C" VQT6_API void* vqt6_qwidget_cursor(void* widget) { if (widget == nullptr) return nullptr; return new QCursor(static_cast(widget)->cursor()); } extern "C" VQT6_API void vqt6_qwidget_unset_cursor(void* widget) { if (widget == nullptr) return; static_cast(widget)->unsetCursor(); } extern "C" VQT6_API void vqt6_qwidget_set_tool_tip(void* widget, void* tip) { if (widget == nullptr || tip == nullptr) return; static_cast(widget)->setToolTip(*static_cast(tip)); } extern "C" VQT6_API void* vqt6_qwidget_tool_tip(void* widget) { if (widget == nullptr) return nullptr; return new QString(static_cast(widget)->toolTip()); } extern "C" VQT6_API void vqt6_qwidget_set_status_tip(void* widget, void* tip) { if (widget == nullptr || tip == nullptr) return; static_cast(widget)->setStatusTip(*static_cast(tip)); } extern "C" VQT6_API void* vqt6_qwidget_status_tip(void* widget) { if (widget == nullptr) return nullptr; return new QString(static_cast(widget)->statusTip()); } extern "C" VQT6_API void vqt6_qwidget_set_minimum_size(void* widget, int w, int h) { if (widget == nullptr) return; static_cast(widget)->setMinimumSize(w, h); } extern "C" VQT6_API void vqt6_qwidget_set_maximum_size(void* widget, int w, int h) { if (widget == nullptr) return; static_cast(widget)->setMaximumSize(w, h); } extern "C" VQT6_API void vqt6_qwidget_set_fixed_size(void* widget, int w, int h) { if (widget == nullptr) return; static_cast(widget)->setFixedSize(w, h); } extern "C" VQT6_API void vqt6_qwidget_minimum_size(void* widget, int* w, int* h) { if (widget == nullptr) return; QSize s = static_cast(widget)->minimumSize(); if (w != nullptr) *w = s.width(); if (h != nullptr) *h = s.height(); } extern "C" VQT6_API void vqt6_qwidget_maximum_size(void* widget, int* w, int* h) { if (widget == nullptr) return; QSize s = static_cast(widget)->maximumSize(); if (w != nullptr) *w = s.width(); if (h != nullptr) *h = s.height(); } // ============================================================ // QDialog // ============================================================ extern "C" VQT6_API void* vqt6_qdialog_create(void) { return new QDialog(); } extern "C" VQT6_API void* vqt6_qdialog_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QDialog(static_cast(parent)); } extern "C" VQT6_API int vqt6_qdialog_exec(void* dialog) { if (dialog == nullptr) return -1; return static_cast(dialog)->exec(); } extern "C" VQT6_API void vqt6_qdialog_done(void* dialog, int result) { if (dialog == nullptr) return; static_cast(dialog)->done(result); } extern "C" VQT6_API void vqt6_qdialog_accept(void* dialog) { if (dialog == nullptr) return; static_cast(dialog)->accept(); } extern "C" VQT6_API void vqt6_qdialog_reject(void* dialog) { if (dialog == nullptr) return; static_cast(dialog)->reject(); } extern "C" VQT6_API void vqt6_qdialog_set_result(void* dialog, int result) { if (dialog == nullptr) return; static_cast(dialog)->setResult(result); } extern "C" VQT6_API int vqt6_qdialog_result(void* dialog) { if (dialog == nullptr) return 0; return static_cast(dialog)->result(); } extern "C" VQT6_API void vqt6_qdialog_set_modal(void* dialog, int modal) { if (dialog == nullptr) return; static_cast(dialog)->setModal(modal != 0); } extern "C" VQT6_API int vqt6_qdialog_is_modal(void* dialog) { if (dialog == nullptr) return 0; return static_cast(dialog)->isModal() ? 1 : 0; } // ============================================================ // QMainWindow // ============================================================ extern "C" VQT6_API void* vqt6_qmainwindow_create(void) { return new QMainWindow(); } extern "C" VQT6_API void* vqt6_qmainwindow_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QMainWindow(static_cast(parent)); } extern "C" VQT6_API void vqt6_qmainwindow_set_central_widget(void* mw, void* widget) { if (mw == nullptr) return; static_cast(mw)->setCentralWidget(static_cast(widget)); } extern "C" VQT6_API void* vqt6_qmainwindow_central_widget(void* mw) { if (mw == nullptr) return nullptr; return static_cast(mw)->centralWidget(); } extern "C" VQT6_API void* vqt6_qmainwindow_menu_bar(void* mw) { if (mw == nullptr) return nullptr; return static_cast(mw)->menuBar(); } extern "C" VQT6_API void vqt6_qmainwindow_set_menu_bar(void* mw, void* menubar) { if (mw == nullptr) return; static_cast(mw)->setMenuBar(static_cast(menubar)); } extern "C" VQT6_API void* vqt6_qmainwindow_status_bar(void* mw) { if (mw == nullptr) return nullptr; return static_cast(mw)->statusBar(); } extern "C" VQT6_API void vqt6_qmainwindow_set_status_bar(void* mw, void* statusbar) { if (mw == nullptr) return; static_cast(mw)->setStatusBar(static_cast(statusbar)); } extern "C" VQT6_API void vqt6_qmainwindow_add_tool_bar(void* mw, void* toolbar) { if (mw == nullptr) return; static_cast(mw)->addToolBar(static_cast(toolbar)); } extern "C" VQT6_API void vqt6_qmainwindow_add_tool_bar_break(void* mw) { if (mw == nullptr) return; static_cast(mw)->addToolBarBreak(); } // ============================================================ // QLabel // ============================================================ extern "C" VQT6_API void* vqt6_qlabel_create(void) { return new QLabel(); } extern "C" VQT6_API void* vqt6_qlabel_create_with_text(void* text) { if (text == nullptr) return nullptr; return new QLabel(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qlabel_create_with_text_parent(void* text, void* parent) { if (text == nullptr || parent == nullptr) return nullptr; return new QLabel(*static_cast(text), static_cast(parent)); } extern "C" VQT6_API void vqt6_qlabel_set_text(void* label, void* text) { if (label == nullptr || text == nullptr) return; static_cast(label)->setText(*static_cast(text)); } extern "C" VQT6_API void vqt6_qlabel_set_text_utf8(void* label, const char* utf8) { if (label == nullptr || utf8 == nullptr) return; static_cast(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(label)->text()); } extern "C" VQT6_API void vqt6_qlabel_set_alignment(void* label, int alignment) { if (label == nullptr) return; static_cast(label)->setAlignment(static_cast(alignment)); } extern "C" VQT6_API int vqt6_qlabel_alignment(void* label) { if (label == nullptr) return 0; return static_cast(static_cast(label)->alignment()); } extern "C" VQT6_API void vqt6_qlabel_set_pixmap(void* label, void* pixmap) { if (label == nullptr || pixmap == nullptr) return; static_cast(label)->setPixmap(*static_cast(pixmap)); } extern "C" VQT6_API void* vqt6_qlabel_pixmap(void* label) { if (label == nullptr) return nullptr; return new QPixmap(static_cast(label)->pixmap()); } extern "C" VQT6_API void vqt6_qlabel_set_indent(void* label, int indent) { if (label == nullptr) return; static_cast(label)->setIndent(indent); } extern "C" VQT6_API void vqt6_qlabel_set_margin(void* label, int margin) { if (label == nullptr) return; static_cast(label)->setMargin(margin); } extern "C" VQT6_API void vqt6_qlabel_set_word_wrap(void* label, int wrap) { if (label == nullptr) return; static_cast(label)->setWordWrap(wrap != 0); } extern "C" VQT6_API int vqt6_qlabel_word_wrap(void* label) { if (label == nullptr) return 0; return static_cast(label)->wordWrap() ? 1 : 0; } // ============================================================ // QPushButton // ============================================================ extern "C" VQT6_API void* vqt6_qpushbutton_create(void) { return new QPushButton(); } extern "C" VQT6_API void* vqt6_qpushbutton_create_with_text(void* text) { if (text == nullptr) return nullptr; return new QPushButton(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qpushbutton_create_with_text_parent(void* text, void* parent) { if (text == nullptr || parent == nullptr) return nullptr; return new QPushButton(*static_cast(text), static_cast(parent)); } extern "C" VQT6_API void vqt6_qpushbutton_set_text(void* btn, void* text) { if (btn == nullptr || text == nullptr) return; static_cast(btn)->setText(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qpushbutton_text(void* btn) { if (btn == nullptr) return nullptr; return new QString(static_cast(btn)->text()); } extern "C" VQT6_API void vqt6_qpushbutton_set_icon(void* btn, void* icon) { if (btn == nullptr || icon == nullptr) return; static_cast(btn)->setIcon(*static_cast(icon)); } extern "C" VQT6_API void* vqt6_qpushbutton_icon(void* btn) { if (btn == nullptr) return nullptr; return new QIcon(static_cast(btn)->icon()); } extern "C" VQT6_API void vqt6_qpushbutton_set_default(void* btn, int is_default) { if (btn == nullptr) return; static_cast(btn)->setDefault(is_default != 0); } extern "C" VQT6_API int vqt6_qpushbutton_is_default(void* btn) { if (btn == nullptr) return 0; return static_cast(btn)->isDefault() ? 1 : 0; } extern "C" VQT6_API void vqt6_qpushbutton_set_flat(void* btn, int flat) { if (btn == nullptr) return; static_cast(btn)->setFlat(flat != 0); } extern "C" VQT6_API int vqt6_qpushbutton_is_flat(void* btn) { if (btn == nullptr) return 0; return static_cast(btn)->isFlat() ? 1 : 0; } extern "C" VQT6_API void vqt6_qpushbutton_set_checkable(void* btn, int checkable) { if (btn == nullptr) return; static_cast(btn)->setCheckable(checkable != 0); } extern "C" VQT6_API int vqt6_qpushbutton_is_checkable(void* btn) { if (btn == nullptr) return 0; return static_cast(btn)->isCheckable() ? 1 : 0; } extern "C" VQT6_API void vqt6_qpushbutton_set_checked(void* btn, int checked) { if (btn == nullptr) return; static_cast(btn)->setChecked(checked != 0); } extern "C" VQT6_API int vqt6_qpushbutton_is_checked(void* btn) { if (btn == nullptr) return 0; return static_cast(btn)->isChecked() ? 1 : 0; } extern "C" VQT6_API void vqt6_qpushbutton_click(void* btn) { if (btn == nullptr) return; static_cast(btn)->click(); } // ============================================================ // QLineEdit // ============================================================ extern "C" VQT6_API void* vqt6_qlineedit_create(void) { return new QLineEdit(); } extern "C" VQT6_API void* vqt6_qlineedit_create_with_text(void* text) { if (text == nullptr) return nullptr; return new QLineEdit(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qlineedit_create_with_text_parent(void* text, void* parent) { if (text == nullptr || parent == nullptr) return nullptr; return new QLineEdit(*static_cast(text), static_cast(parent)); } extern "C" VQT6_API void* vqt6_qlineedit_text(void* le) { if (le == nullptr) return nullptr; return new QString(static_cast(le)->text()); } extern "C" VQT6_API void vqt6_qlineedit_set_text(void* le, void* text) { if (le == nullptr || text == nullptr) return; static_cast(le)->setText(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qlineedit_placeholder_text(void* le) { if (le == nullptr) return nullptr; return new QString(static_cast(le)->placeholderText()); } extern "C" VQT6_API void vqt6_qlineedit_set_placeholder_text(void* le, void* text) { if (le == nullptr || text == nullptr) return; static_cast(le)->setPlaceholderText(*static_cast(text)); } extern "C" VQT6_API void vqt6_qlineedit_set_max_length(void* le, int max) { if (le == nullptr) return; static_cast(le)->setMaxLength(max); } extern "C" VQT6_API int vqt6_qlineedit_max_length(void* le) { if (le == nullptr) return 0; return static_cast(le)->maxLength(); } extern "C" VQT6_API void vqt6_qlineedit_set_read_only(void* le, int ro) { if (le == nullptr) return; static_cast(le)->setReadOnly(ro != 0); } extern "C" VQT6_API int vqt6_qlineedit_is_read_only(void* le) { if (le == nullptr) return 0; return static_cast(le)->isReadOnly() ? 1 : 0; } extern "C" VQT6_API void vqt6_qlineedit_set_echo_mode(void* le, int mode) { if (le == nullptr) return; static_cast(le)->setEchoMode(static_cast(mode)); } extern "C" VQT6_API int vqt6_qlineedit_echo_mode(void* le) { if (le == nullptr) return 0; return static_cast(static_cast(le)->echoMode()); } extern "C" VQT6_API void vqt6_qlineedit_select_all(void* le) { if (le == nullptr) return; static_cast(le)->selectAll(); } extern "C" VQT6_API void vqt6_qlineedit_clear(void* le) { if (le == nullptr) return; static_cast(le)->clear(); } // ============================================================ // QTextEdit / QPlainTextEdit // ============================================================ extern "C" VQT6_API void* vqt6_qtextedit_create(void) { return new QTextEdit(); } extern "C" VQT6_API void* vqt6_qtextedit_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QTextEdit(static_cast(parent)); } extern "C" VQT6_API void* vqt6_qtextedit_to_plain_text(void* te) { if (te == nullptr) return nullptr; return new QString(static_cast(te)->toPlainText()); } extern "C" VQT6_API void vqt6_qtextedit_set_plain_text(void* te, void* text) { if (te == nullptr || text == nullptr) return; static_cast(te)->setPlainText(*static_cast(text)); } extern "C" VQT6_API void vqt6_qtextedit_set_html(void* te, void* html) { if (te == nullptr || html == nullptr) return; static_cast(te)->setHtml(*static_cast(html)); } extern "C" VQT6_API void* vqt6_qtextedit_to_html(void* te) { if (te == nullptr) return nullptr; return new QString(static_cast(te)->toHtml()); } extern "C" VQT6_API void vqt6_qtextedit_append(void* te, void* text) { if (te == nullptr || text == nullptr) return; static_cast(te)->append(*static_cast(text)); } extern "C" VQT6_API void vqt6_qtextedit_clear(void* te) { if (te == nullptr) return; static_cast(te)->clear(); } extern "C" VQT6_API void vqt6_qtextedit_set_read_only(void* te, int ro) { if (te == nullptr) return; static_cast(te)->setReadOnly(ro != 0); } extern "C" VQT6_API int vqt6_qtextedit_is_read_only(void* te) { if (te == nullptr) return 0; return static_cast(te)->isReadOnly() ? 1 : 0; } extern "C" VQT6_API void* vqt6_qplaintextedit_create(void) { return new QPlainTextEdit(); } extern "C" VQT6_API void* vqt6_qplaintextedit_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QPlainTextEdit(static_cast(parent)); } extern "C" VQT6_API void* vqt6_qplaintextedit_to_plain_text(void* pte) { if (pte == nullptr) return nullptr; return new QString(static_cast(pte)->toPlainText()); } extern "C" VQT6_API void vqt6_qplaintextedit_set_plain_text(void* pte, void* text) { if (pte == nullptr || text == nullptr) return; static_cast(pte)->setPlainText(*static_cast(text)); } extern "C" VQT6_API void vqt6_qplaintextedit_append(void* pte, void* text) { if (pte == nullptr || text == nullptr) return; static_cast(pte)->appendPlainText(*static_cast(text)); } extern "C" VQT6_API void vqt6_qplaintextedit_append_utf8(void* pte, const char* utf8) { if (pte == nullptr || utf8 == nullptr) return; static_cast(pte)->appendPlainText(QString::fromUtf8(utf8)); } extern "C" VQT6_API void vqt6_qplaintextedit_set_plain_text_utf8(void* pte, const char* utf8) { if (pte == nullptr || utf8 == nullptr) return; static_cast(pte)->setPlainText(QString::fromUtf8(utf8)); } extern "C" VQT6_API void vqt6_qwidget_set_stylesheet_utf8(void* widget, const char* utf8) { if (widget == nullptr || utf8 == nullptr) return; static_cast(widget)->setStyleSheet(QString::fromUtf8(utf8)); } extern "C" VQT6_API void vqt6_qplaintextedit_clear(void* pte) { if (pte == nullptr) return; static_cast(pte)->clear(); } extern "C" VQT6_API void vqt6_qplaintextedit_set_read_only(void* pte, int ro) { if (pte == nullptr) return; static_cast(pte)->setReadOnly(ro != 0); } extern "C" VQT6_API int vqt6_qplaintextedit_line_count(void* pte) { if (pte == nullptr) return 0; return static_cast(pte)->blockCount(); } // ============================================================ // QCheckBox / QRadioButton // ============================================================ // ------------------------------------------------------------------ // 共享的“勾选指示器”渲染(自绘 QCheckBox 与树形勾选代理复用同一套绘制) // ------------------------------------------------------------------ static QColor vqt6_mix_color(const QColor& a, const QColor& b, qreal t) { if (t < 0.0) t = 0.0; else if (t > 1.0) t = 1.0; return QColor::fromRgbF(a.redF() + (b.redF() - a.redF()) * t, a.greenF() + (b.greenF() - a.greenF()) * t, a.blueF() + (b.blueF() - a.blueF()) * t, a.alphaF() + (b.alphaF() - a.alphaF()) * t); } // 规整指示区:内部收缩 1px;过小时回退为 16×16 并居中 static QRectF vqt6_indicator_box(const QRect& r) { QRectF box(r.left() + 1.0, r.top() + 1.0, r.width() - 2.0, r.height() - 2.0); if (box.width() < 10.0 || box.height() < 10.0) { box = QRectF(0, 0, 16, 16); box.moveCenter(QRectF(r).center()); } return box; } // 统一的指示器绘制:圆角框 + QPalette 配色 + 对勾(或半选横线) // box —— 绘制区域(约 16~18px 见方) // pal —— 控件调色板(决定深浅主题配色) // enabled —— 是否可用 // progress —— 勾选过渡进度(0=未选 1=选中) // partial —— 半选态(画横线,progress 按 1 传入) static void vqt6_paint_check_indicator(QPainter* p, const QRectF& box, const QPalette& pal, bool enabled, qreal progress, bool partial) { p->setRenderHint(QPainter::Antialiasing, true); const qreal t = progress < 0.0 ? 0.0 : (progress > 1.0 ? 1.0 : progress); const QColor cBase = enabled ? pal.base().color() : pal.window().color(); const QColor cOn = enabled ? pal.highlight().color() : pal.button().color(); const QColor cB0 = enabled ? pal.text().color() : pal.placeholderText().color(); const QColor cB1 = enabled ? pal.highlight().color() : pal.buttonText().color(); const QColor fill = vqt6_mix_color(cBase, cOn, t); const QColor border = vqt6_mix_color(cB0, cB1, t); QPainterPath path; path.addRoundedRect(box, 3.0, 3.0); p->fillPath(path, fill); QPen bpen(border, 1.4); p->setPen(bpen); p->drawPath(path); if (!enabled || t <= 0.003) return; QColor gc = pal.highlightedText().color(); gc.setAlphaF(gc.alphaF() * t); const qreal x0 = box.left(), y0 = box.top(), w = box.width(), h = box.height(); if (partial) { QPen dpen(gc, 1.6); dpen.setCapStyle(Qt::RoundCap); p->setPen(dpen); p->drawLine(QPointF(x0 + w * 0.22, y0 + h * 0.5), QPointF(x0 + w * 0.78, y0 + h * 0.5)); } else { QPen cpen(gc, 1.6 + 0.8 * t); cpen.setCapStyle(Qt::RoundCap); p->setPen(cpen); p->drawLine(QPointF(x0 + w * 0.24, y0 + h * 0.54), QPointF(x0 + w * 0.43, y0 + h * 0.73)); p->drawLine(QPointF(x0 + w * 0.43, y0 + h * 0.73), QPointF(x0 + w * 0.78, y0 + h * 0.28)); } } // 自绘 QCheckBox:矢量框+对勾按 QPalette 绘制,勾选带过渡动画 class vqt6_CheckBox : public QCheckBox { public: vqt6_CheckBox(QWidget* parent = nullptr) : QCheckBox(parent) { initAnim(); } vqt6_CheckBox(const QString& text, QWidget* parent = nullptr) : QCheckBox(text, parent) { initAnim(); } protected: void paintEvent(QPaintEvent*) override { QPainter p(this); p.setRenderHint(QPainter::Antialiasing, true); const QPalette& pal = palette(); QStyleOptionButton opt; initStyleOption(&opt); QRect r = style()->subElementRect(QStyle::SE_CheckBoxIndicator, &opt, this); if (r.isEmpty() || r.isNull()) { r = QRect(0, 0, 16, 16); r.moveCenter(QPoint(rect().left() + 12, rect().center().y())); } // 框 + 对勾:与树形勾选共用同一渲染(含动画进度) vqt6_paint_check_indicator(&p, vqt6_indicator_box(r), pal, isEnabled(), m_progress, false); // 文本 QRect lr = style()->subElementRect(QStyle::SE_CheckBoxContents, &opt, this); if (!lr.isEmpty() && !lr.isNull()) { p.setPen(QPen(isEnabled() ? pal.text() : pal.placeholderText(), 1.0)); p.drawText(lr, Qt::AlignLeft | Qt::AlignVCenter, text()); } } void showEvent(QShowEvent* e) override { snapToState(); QCheckBox::showEvent(e); } private: QTimer m_timer; qreal m_progress = 0.0; qreal m_target = 0.0; void initAnim() { m_timer.setInterval(16); QObject::connect(&m_timer, &QTimer::timeout, this, [this]() { m_progress += (m_target - m_progress) * 0.25; if (qAbs(m_target - m_progress) < 0.005) { m_progress = m_target; m_timer.stop(); } update(); }); QObject::connect(this, &QCheckBox::toggled, this, [this](bool on) { m_target = on ? 1.0 : 0.0; if (!isVisible()) { m_progress = m_target; } else if (!m_timer.isActive()) { m_timer.start(); } }); } void snapToState() { m_target = isChecked() ? 1.0 : 0.0; m_progress = m_target; m_timer.stop(); } }; extern "C" VQT6_API void* vqt6_qcheckbox_create(void) { return new vqt6_CheckBox(); } extern "C" VQT6_API void* vqt6_qcheckbox_create_with_text(void* text) { if (text == nullptr) return nullptr; return new vqt6_CheckBox(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qcheckbox_create_with_text_parent(void* text, void* parent) { if (text == nullptr || parent == nullptr) return nullptr; return new vqt6_CheckBox(*static_cast(text), static_cast(parent)); } extern "C" VQT6_API void vqt6_qcheckbox_set_checked(void* cb, int checked) { if (cb == nullptr) return; static_cast(cb)->setChecked(checked != 0); } extern "C" VQT6_API int vqt6_qcheckbox_is_checked(void* cb) { if (cb == nullptr) return 0; return static_cast(cb)->isChecked() ? 1 : 0; } extern "C" VQT6_API void vqt6_qcheckbox_set_text(void* cb, void* text) { if (cb == nullptr || text == nullptr) return; static_cast(cb)->setText(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qcheckbox_text(void* cb) { if (cb == nullptr) return nullptr; return new QString(static_cast(cb)->text()); } extern "C" VQT6_API void vqt6_qcheckbox_set_tristate(void* cb, int tristate) { if (cb == nullptr) return; static_cast(cb)->setTristate(tristate != 0); } extern "C" VQT6_API int vqt6_qcheckbox_is_tristate(void* cb) { if (cb == nullptr) return 0; return static_cast(cb)->isTristate() ? 1 : 0; } // ============================================================ // item-view(QTreeWidget 等)勾选框自绘代理 // 拦截 PE_IndicatorItemViewItemCheck,复用 vqt6_paint_check_indicator, // 与自绘 QCheckBox 观感一致(含勾选过渡动画:QTreeWidget 勾选变化时 // 按 60fps 指数衰减驱动对应 item 重绘,动画节奏与复选框完全相同)。 // 采用 QProxyStyle 默认构造(基样式按需自动创建),应用 setStyle 后由 // Qt 管理生命周期 —— 与 Qt 官方 QProxyStyle 示例一致,避免基样式 // 所有权/悬空问题。 // ============================================================ class vqt6_CheckProxyStyle : public QProxyStyle { public: vqt6_CheckProxyStyle() : QProxyStyle() { m_timer.setInterval(16); QObject::connect(&m_timer, &QTimer::timeout, this, [this]() { advance(); }); } void drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const override { if (element == PE_IndicatorItemViewItemCheck && option != nullptr && painter != nullptr) { drawItemCheck(option, painter, widget); return; } QProxyStyle::drawPrimitive(element, option, painter, widget); } private: struct AnimState { qreal progress = 0.0; // 当前绘制进度 0..1 qreal target = 0.0; // 目标进度 }; // 勾选动画记录(键 = QTreeWidgetItem* 指针值) mutable QHash m_anims; // 已绑定 itemChanged 的树视图(避免重复连接) mutable QSet m_hooked; // 动画期间需要定时重绘的树视图 mutable QSet m_repaint; mutable QTimer m_timer; void drawItemCheck(const QStyleOption* option, QPainter* painter, const QWidget* widget) const { const bool enabled = (option->state & QStyle::State_Enabled) != 0; const bool on = (option->state & QStyle::State_On) != 0; const bool partial = (option->state & QStyle::State_NoChange) != 0; qreal progress = (on || partial) ? 1.0 : 0.0; // 懒绑定 QTreeWidget:勾选变化时驱动对应 item 的过渡动画 QTreeWidget* tw = (widget != nullptr) ? const_cast(qobject_cast(widget)) : nullptr; if (tw != nullptr) { if (!m_hooked.contains(tw)) { m_hooked.insert(tw); QObject::connect(tw, &QTreeWidget::itemChanged, this, [this, tw](QTreeWidgetItem* item, int) { onItemChanged(tw, item); }); } const QStyleOptionViewItem* vopt = qstyleoption_cast(option); if (vopt != nullptr && vopt->index.isValid()) { const quintptr key = quintptr(vopt->index.internalPointer()); auto it = m_anims.constFind(key); if (it != m_anims.constEnd()) progress = it->progress; } } const QPalette& pal = (widget != nullptr) ? widget->palette() : QApplication::palette(); vqt6_paint_check_indicator(painter, vqt6_indicator_box(option->rect), pal, enabled, progress, partial); } void onItemChanged(QTreeWidget* tw, QTreeWidgetItem* item) const { if (tw == nullptr || item == nullptr) return; const Qt::CheckState cs = item->checkState(0); const bool on = (cs == Qt::Checked || cs == Qt::PartiallyChecked); const qreal target = on ? 1.0 : 0.0; const quintptr key = quintptr(static_cast(item)); auto it = m_anims.find(key); if (it == m_anims.end()) { // 从“变化前”的观感出发开始过渡(与复选框一致:勾选=淡入对勾, // 取消勾选=淡出),中途连续切换时延续当前进度。 AnimState st; st.progress = (target > 0.5) ? 0.0 : 1.0; st.target = target; m_anims.insert(key, st); } else { it->target = target; } if (!tw->isVisible()) { // 建页/初始化阶段的程序化勾选:直接落定,不产生无谓动画 m_anims.remove(key); return; } m_repaint.insert(tw); tw->viewport()->update(); if (!m_timer.isActive()) m_timer.start(); } void advance() const { QList done; for (auto it = m_anims.begin(); it != m_anims.end(); ++it) { AnimState& st = it.value(); st.progress += (st.target - st.progress) * 0.25; if (qAbs(st.target - st.progress) < 0.005) { st.progress = st.target; done.append(it.key()); } } for (quintptr k : done) m_anims.remove(k); for (QTreeWidget* tw : m_repaint) { if (tw != nullptr && tw->viewport() != nullptr) tw->viewport()->update(); } if (m_anims.isEmpty()) { m_repaint.clear(); m_timer.stop(); } } }; extern "C" VQT6_API void vqt6_enable_custom_item_checks(void* app) { QApplication* a = (app != nullptr) ? static_cast(app) : static_cast(QApplication::instance()); if (a == nullptr) return; static bool s_custom_checks_enabled = false; if (s_custom_checks_enabled) return; // 幂等:只安装一次 s_custom_checks_enabled = true; a->setStyle(new vqt6_CheckProxyStyle()); } // ------------------------------------------------------------------ // 自绘 QRadioButton:圆形指示器(圆环 + 内点) // 与自绘 QCheckBox 同源:同样的 QPalette 取色、同样的 16ms 指数衰减过渡 // (参考 ViperQtProject 里 vqt6_CheckBox / vqt6_CheckProxyStyle 的做法)。 // ------------------------------------------------------------------ // 圆形的绘制区域:在 r 内取居中的正方形(半径一致才是个正圆) static QRectF vqt6_radio_box(const QRect& r) { qreal side = qMin(r.width(), r.height()) - 2.0; if (side < 10.0) side = 14.0; QRectF box(0, 0, side, side); box.moveCenter(QRectF(r).center()); return box; } // 统一的单选指示器绘制:圆环 + 随进度长大的内点 // box —— 绘制区域(正方形) // pal —— 控件调色板(决定深浅主题配色) // enabled —— 是否可用 // progress —— 选中过渡进度(0=未选 1=选中) static void vqt6_paint_radio_indicator(QPainter* p, const QRectF& box, const QPalette& pal, bool enabled, qreal progress) { p->setRenderHint(QPainter::Antialiasing, true); const qreal t = progress < 0.0 ? 0.0 : (progress > 1.0 ? 1.0 : progress); const QColor cBase = enabled ? pal.base().color() : pal.window().color(); const QColor cOn = enabled ? pal.highlight().color() : pal.button().color(); const QColor cB0 = enabled ? pal.text().color() : pal.placeholderText().color(); const QColor cB1 = enabled ? pal.highlight().color() : pal.buttonText().color(); const QColor fill = vqt6_mix_color(cBase, cOn, t); const QColor border = vqt6_mix_color(cB0, cB1, t); QPainterPath path; path.addEllipse(box); p->fillPath(path, fill); QPen bpen(border, 1.4); p->setPen(bpen); p->drawEllipse(box); if (!enabled || t <= 0.003) return; // 内点:半径从 0 涨到 0.32*边长,颜色取 highlightedText 并按进度淡入 QColor gc = pal.highlightedText().color(); gc.setAlphaF(gc.alphaF() * t); const qreal side = qMin(box.width(), box.height()); const qreal rd = side * 0.32 * t; p->setPen(Qt::NoPen); p->setBrush(gc); p->drawEllipse(box.center(), rd, rd); } class vqt6_RadioButton : public QRadioButton { public: vqt6_RadioButton(QWidget* parent = nullptr) : QRadioButton(parent) { initAnim(); } vqt6_RadioButton(const QString& text, QWidget* parent = nullptr) : QRadioButton(text, parent) { initAnim(); } protected: void paintEvent(QPaintEvent*) override { QPainter p(this); p.setRenderHint(QPainter::Antialiasing, true); const QPalette& pal = palette(); QStyleOptionButton opt; initStyleOption(&opt); QRect r = style()->subElementRect(QStyle::SE_RadioButtonIndicator, &opt, this); if (r.isEmpty() || r.isNull()) { r = QRect(0, 0, 16, 16); r.moveCenter(QPoint(rect().left() + 12, rect().center().y())); } // 圆环 + 内点:与自绘复选框共用配色与动画进度 vqt6_paint_radio_indicator(&p, vqt6_radio_box(r), pal, isEnabled(), m_progress); // 文本 QRect lr = style()->subElementRect(QStyle::SE_RadioButtonContents, &opt, this); if (!lr.isEmpty() && !lr.isNull()) { p.setPen(QPen(isEnabled() ? pal.text() : pal.placeholderText(), 1.0)); p.drawText(lr, Qt::AlignLeft | Qt::AlignVCenter, text()); } } void showEvent(QShowEvent* e) override { snapToState(); QRadioButton::showEvent(e); } private: QTimer m_timer; qreal m_progress = 0.0; qreal m_target = 0.0; void initAnim() { m_timer.setInterval(16); QObject::connect(&m_timer, &QTimer::timeout, this, [this]() { m_progress += (m_target - m_progress) * 0.25; if (qAbs(m_target - m_progress) < 0.005) { m_progress = m_target; m_timer.stop(); } update(); }); QObject::connect(this, &QRadioButton::toggled, this, [this](bool on) { m_target = on ? 1.0 : 0.0; if (!isVisible()) { m_progress = m_target; } else if (!m_timer.isActive()) { m_timer.start(); } }); } void snapToState() { m_target = isChecked() ? 1.0 : 0.0; m_progress = m_target; m_timer.stop(); } }; extern "C" VQT6_API void* vqt6_qradiobutton_create(void) { return new vqt6_RadioButton(); } extern "C" VQT6_API void* vqt6_qradiobutton_create_with_text(void* text) { if (text == nullptr) return nullptr; return new vqt6_RadioButton(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qradiobutton_create_with_text_parent(void* text, void* parent) { if (text == nullptr || parent == nullptr) return nullptr; return new vqt6_RadioButton(*static_cast(text), static_cast(parent)); } extern "C" VQT6_API void vqt6_qradiobutton_set_checked(void* rb, int checked) { if (rb == nullptr) return; static_cast(rb)->setChecked(checked != 0); } extern "C" VQT6_API int vqt6_qradiobutton_is_checked(void* rb) { if (rb == nullptr) return 0; return static_cast(rb)->isChecked() ? 1 : 0; } extern "C" VQT6_API void vqt6_qradiobutton_set_text(void* rb, void* text) { if (rb == nullptr || text == nullptr) return; static_cast(rb)->setText(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qradiobutton_text(void* rb) { if (rb == nullptr) return nullptr; return new QString(static_cast(rb)->text()); } // ============================================================ // QComboBox // ============================================================ extern "C" VQT6_API void* vqt6_qcombobox_create(void) { return new QComboBox(); } extern "C" VQT6_API void* vqt6_qcombobox_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QComboBox(static_cast(parent)); } extern "C" VQT6_API void vqt6_qcombobox_add_item(void* cb, void* text) { if (cb == nullptr || text == nullptr) return; static_cast(cb)->addItem(*static_cast(text)); } extern "C" VQT6_API void vqt6_qcombobox_add_items(void* cb, void* items) { if (cb == nullptr || items == nullptr) return; static_cast(cb)->addItems(*static_cast(items)); } extern "C" VQT6_API void vqt6_qcombobox_insert_item(void* cb, int index, void* text) { if (cb == nullptr || text == nullptr) return; static_cast(cb)->insertItem(index, *static_cast(text)); } extern "C" VQT6_API void vqt6_qcombobox_remove_item(void* cb, int index) { if (cb == nullptr) return; static_cast(cb)->removeItem(index); } extern "C" VQT6_API void vqt6_qcombobox_clear(void* cb) { if (cb == nullptr) return; static_cast(cb)->clear(); } extern "C" VQT6_API int vqt6_qcombobox_count(void* cb) { if (cb == nullptr) return 0; return static_cast(cb)->count(); } extern "C" VQT6_API int vqt6_qcombobox_current_index(void* cb) { if (cb == nullptr) return -1; return static_cast(cb)->currentIndex(); } extern "C" VQT6_API void vqt6_qcombobox_set_current_index(void* cb, int index) { if (cb == nullptr) return; static_cast(cb)->setCurrentIndex(index); } extern "C" VQT6_API void* vqt6_qcombobox_current_text(void* cb) { if (cb == nullptr) return nullptr; return new QString(static_cast(cb)->currentText()); } extern "C" VQT6_API void* vqt6_qcombobox_item_text(void* cb, int index) { if (cb == nullptr) return nullptr; return new QString(static_cast(cb)->itemText(index)); } extern "C" VQT6_API void vqt6_qcombobox_set_editable(void* cb, int editable) { if (cb == nullptr) return; static_cast(cb)->setEditable(editable != 0); } extern "C" VQT6_API int vqt6_qcombobox_is_editable(void* cb) { if (cb == nullptr) return 0; return static_cast(cb)->isEditable() ? 1 : 0; } // ============================================================ // QListWidget // ============================================================ extern "C" VQT6_API void* vqt6_qlistwidget_create(void) { return new QListWidget(); } extern "C" VQT6_API void* vqt6_qlistwidget_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QListWidget(static_cast(parent)); } extern "C" VQT6_API void vqt6_qlistwidget_add_item(void* lw, void* text) { if (lw == nullptr || text == nullptr) return; static_cast(lw)->addItem(*static_cast(text)); } extern "C" VQT6_API void vqt6_qlistwidget_add_items(void* lw, void* items) { if (lw == nullptr || items == nullptr) return; static_cast(lw)->addItems(*static_cast(items)); } extern "C" VQT6_API void vqt6_qlistwidget_insert_item(void* lw, int row, void* text) { if (lw == nullptr || text == nullptr) return; static_cast(lw)->insertItem(row, *static_cast(text)); } extern "C" VQT6_API void vqt6_qlistwidget_remove_item_widget(void* lw, int row) { if (lw == nullptr) return; static_cast(lw)->takeItem(row); } extern "C" VQT6_API void* vqt6_qlistwidget_take_item(void* lw, int row) { if (lw == nullptr) return nullptr; return static_cast(lw)->takeItem(row); } extern "C" VQT6_API void vqt6_qlistwidget_clear(void* lw) { if (lw == nullptr) return; static_cast(lw)->clear(); } extern "C" VQT6_API int vqt6_qlistwidget_count(void* lw) { if (lw == nullptr) return 0; return static_cast(lw)->count(); } extern "C" VQT6_API int vqt6_qlistwidget_current_row(void* lw) { if (lw == nullptr) return -1; return static_cast(lw)->currentRow(); } extern "C" VQT6_API void vqt6_qlistwidget_set_current_row(void* lw, int row) { if (lw == nullptr) return; static_cast(lw)->setCurrentRow(row); } extern "C" VQT6_API void* vqt6_qlistwidget_current_item_text(void* lw) { if (lw == nullptr) return nullptr; QListWidgetItem* it = static_cast(lw)->currentItem(); if (it == nullptr) return nullptr; return new QString(it->text()); } extern "C" VQT6_API void* vqt6_qlistwidget_item_text(void* lw, int row) { if (lw == nullptr) return nullptr; QListWidgetItem* it = static_cast(lw)->item(row); if (it == nullptr) return nullptr; return new QString(it->text()); } extern "C" VQT6_API void vqt6_qlistwidget_set_item_text(void* lw, int row, void* text) { if (lw == nullptr || text == nullptr) return; QListWidgetItem* it = static_cast(lw)->item(row); if (it != nullptr) it->setText(*static_cast(text)); } // ============================================================ // 聊天气泡行(QListWidget + setItemWidget 实现,微信/QQ 风格) // // 在列表末尾插入一行:透明容器 + QHBoxLayout(右对齐先 addStretch, // 左对齐后 addStretch),气泡本体是 QLabel(wordWrap + 指定 QSS)。 // 气泡宽度按文本最长行自动收缩,超过 max_bubble_w 才换行定宽; // 行高首帧估算 + 事件循环后按真实 heightForWidth 二次修正。 // replace_last_bubble:删除最后一条后重建(流式回复逐字刷新用)。 // ============================================================ static void Vqt6AddBubbleImpl(QListWidget* list, const QString& msg, const QString& qss, int right_align, int max_bubble_w, int hpad, int vpad) { if (list == nullptr) return; int maxw = max_bubble_w > 0 ? max_bubble_w : 420; QWidget* row = new QWidget(list->viewport()); QHBoxLayout* lay = new QHBoxLayout(row); lay->setContentsMargins(8, 3, 8, 3); lay->setSpacing(0); if (right_align) lay->addStretch(1); QLabel* bubble = new QLabel(msg, row); bubble->setWordWrap(true); bubble->setTextInteractionFlags(Qt::TextSelectableByMouse); if (!qss.isEmpty()) bubble->setStyleSheet(qss); bubble->ensurePolished(); // 让祖先 QSS(如全局 Microsoft YaHei)先生效再测量 QFontMetrics fm(bubble->font()); int textw = 0; const QStringList lines = msg.split(QLatin1Char('\n')); for (const QString& line : lines) { int lw_line = fm.horizontalAdvance(line); if (lw_line > textw) textw = lw_line; } int pad = hpad > 0 ? hpad : 28; // QSS padding 左右合计 int bubble_w = textw + pad + 6; // +6 兜底边框/圆整误差 if (bubble_w > maxw) bubble_w = maxw; bubble->setFixedWidth(bubble_w); lay->addWidget(bubble); if (!right_align) lay->addStretch(1); // 初始行高估算(供第一帧,稍后按真实布局修正) int content_w = bubble_w - pad; if (content_w < 10) content_w = bubble_w; int vpad_i = vpad > 0 ? vpad : 16; QRect text_rect = fm.boundingRect(QRect(0, 0, content_w, 20000), int(Qt::TextWordWrap), msg); int est_h = text_rect.height() + vpad_i + 6; if (est_h < fm.height() + vpad_i + 6) est_h = fm.height() + vpad_i + 6; int vw_est = list->viewport()->width(); if (vw_est < bubble_w + 24) vw_est = bubble_w + 24; QListWidgetItem* item = new QListWidgetItem(list); item->setFlags(Qt::NoItemFlags); list->setItemWidget(item, row); item->setSizeHint(QSize(vw_est, est_h)); list->scrollToBottom(); // 布局后二次修正:按实际 heightForWidth 重设行高,避免文字底部裁切 QTimer::singleShot(0, list, [list, item]() { if (list == nullptr || item == nullptr) return; if (list->row(item) < 0) return; QWidget* w = list->itemWidget(item); if (w == nullptr) return; QLayout* ly = w->layout(); if (ly != nullptr) ly->activate(); int vw = list->viewport()->width(); int h = w->heightForWidth(vw); if (h < 10) h = w->sizeHint().height(); item->setSizeHint(QSize(vw, h + 2)); list->scrollToBottom(); }); } extern "C" VQT6_API void vqt6_qlistwidget_add_bubble(void* lw, void* text, void* qss, int right_align, int max_bubble_w, int hpad, int vpad) { QListWidget* list = static_cast(lw); if (list == nullptr || text == nullptr) return; QString msg = *static_cast(text); if (msg.isEmpty()) msg = QStringLiteral(" "); QString qss_s = qss ? *static_cast(qss) : QString(); Vqt6AddBubbleImpl(list, msg, qss_s, right_align, max_bubble_w, hpad, vpad); } // 流式刷新:删除最后一条气泡后按新文本重建(保留其 QSS/对齐样式参数) extern "C" VQT6_API void vqt6_qlistwidget_replace_last_bubble(void* lw, void* text, void* qss, int right_align, int max_bubble_w, int hpad, int vpad) { QListWidget* list = static_cast(lw); if (list == nullptr || text == nullptr) return; QString msg = *static_cast(text); QString qss_s = qss ? *static_cast(qss) : QString(); if (list->count() > 0) { int last = list->count() - 1; QListWidgetItem* item = list->takeItem(last); if (item != nullptr) { QWidget* w = list->itemWidget(item); list->removeItemWidget(item); delete item; if (w != nullptr) w->deleteLater(); } } if (msg.isEmpty()) msg = QStringLiteral(" "); Vqt6AddBubbleImpl(list, msg, qss_s, right_align, max_bubble_w, hpad, vpad); } extern "C" VQT6_API void vqt6_qlistwidget_scroll_to_bottom(void* lw) { if (lw == nullptr) return; static_cast(lw)->scrollToBottom(); } // ============================================================ // QProgressBar // ============================================================ extern "C" VQT6_API void* vqt6_qprogressbar_create(void) { return new QProgressBar(); } extern "C" VQT6_API void* vqt6_qprogressbar_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QProgressBar(static_cast(parent)); } extern "C" VQT6_API void vqt6_qprogressbar_set_value(void* pb, int value) { if (pb == nullptr) return; static_cast(pb)->setValue(value); } extern "C" VQT6_API int vqt6_qprogressbar_value(void* pb) { if (pb == nullptr) return 0; return static_cast(pb)->value(); } extern "C" VQT6_API void vqt6_qprogressbar_set_minimum(void* pb, int min) { if (pb == nullptr) return; static_cast(pb)->setMinimum(min); } extern "C" VQT6_API void vqt6_qprogressbar_set_maximum(void* pb, int max) { if (pb == nullptr) return; static_cast(pb)->setMaximum(max); } extern "C" VQT6_API void vqt6_qprogressbar_set_range(void* pb, int min, int max) { if (pb == nullptr) return; static_cast(pb)->setRange(min, max); } extern "C" VQT6_API int vqt6_qprogressbar_minimum(void* pb) { if (pb == nullptr) return 0; return static_cast(pb)->minimum(); } extern "C" VQT6_API int vqt6_qprogressbar_maximum(void* pb) { if (pb == nullptr) return 0; return static_cast(pb)->maximum(); } extern "C" VQT6_API void vqt6_qprogressbar_set_text_visible(void* pb, int visible) { if (pb == nullptr) return; static_cast(pb)->setTextVisible(visible != 0); } extern "C" VQT6_API void vqt6_qprogressbar_set_format(void* pb, void* format) { if (pb == nullptr || format == nullptr) return; static_cast(pb)->setFormat(*static_cast(format)); } extern "C" VQT6_API void vqt6_qprogressbar_reset(void* pb) { if (pb == nullptr) return; static_cast(pb)->reset(); } // ============================================================ // QSlider // ============================================================ extern "C" VQT6_API void* vqt6_qslider_create(void) { return new QSlider(); } extern "C" VQT6_API void* vqt6_qslider_create_with_orientation(int orientation) { return new QSlider(static_cast(orientation)); } extern "C" VQT6_API void* vqt6_qslider_create_with_orientation_parent(int orientation, void* parent) { if (parent == nullptr) return nullptr; return new QSlider(static_cast(orientation), static_cast(parent)); } extern "C" VQT6_API void vqt6_qslider_set_value(void* s, int value) { if (s == nullptr) return; static_cast(s)->setValue(value); } extern "C" VQT6_API int vqt6_qslider_value(void* s) { if (s == nullptr) return 0; return static_cast(s)->value(); } extern "C" VQT6_API void vqt6_qslider_set_minimum(void* s, int min) { if (s == nullptr) return; static_cast(s)->setMinimum(min); } extern "C" VQT6_API void vqt6_qslider_set_maximum(void* s, int max) { if (s == nullptr) return; static_cast(s)->setMaximum(max); } extern "C" VQT6_API void vqt6_qslider_set_range(void* s, int min, int max) { if (s == nullptr) return; static_cast(s)->setRange(min, max); } extern "C" VQT6_API void vqt6_qslider_set_orientation(void* s, int orientation) { if (s == nullptr) return; static_cast(s)->setOrientation(static_cast(orientation)); } extern "C" VQT6_API int vqt6_qslider_orientation(void* s) { if (s == nullptr) return 0; return static_cast(static_cast(s)->orientation()); } extern "C" VQT6_API void vqt6_qslider_set_single_step(void* s, int step) { if (s == nullptr) return; static_cast(s)->setSingleStep(step); } extern "C" VQT6_API void vqt6_qslider_set_page_step(void* s, int step) { if (s == nullptr) return; static_cast(s)->setPageStep(step); } // ============================================================ // QSpinBox // ============================================================ extern "C" VQT6_API void* vqt6_qspinbox_create(void) { return new QSpinBox(); } extern "C" VQT6_API void* vqt6_qspinbox_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QSpinBox(static_cast(parent)); } extern "C" VQT6_API int vqt6_qspinbox_value(void* sb) { if (sb == nullptr) return 0; return static_cast(sb)->value(); } extern "C" VQT6_API void vqt6_qspinbox_set_value(void* sb, int value) { if (sb == nullptr) return; static_cast(sb)->setValue(value); } extern "C" VQT6_API void vqt6_qspinbox_set_minimum(void* sb, int min) { if (sb == nullptr) return; static_cast(sb)->setMinimum(min); } extern "C" VQT6_API void vqt6_qspinbox_set_maximum(void* sb, int max) { if (sb == nullptr) return; static_cast(sb)->setMaximum(max); } extern "C" VQT6_API void vqt6_qspinbox_set_range(void* sb, int min, int max) { if (sb == nullptr) return; static_cast(sb)->setRange(min, max); } extern "C" VQT6_API int vqt6_qspinbox_minimum(void* sb) { if (sb == nullptr) return 0; return static_cast(sb)->minimum(); } extern "C" VQT6_API int vqt6_qspinbox_maximum(void* sb) { if (sb == nullptr) return 0; return static_cast(sb)->maximum(); } extern "C" VQT6_API void vqt6_qspinbox_set_single_step(void* sb, int step) { if (sb == nullptr) return; static_cast(sb)->setSingleStep(step); } extern "C" VQT6_API void vqt6_qspinbox_set_prefix(void* sb, void* prefix) { if (sb == nullptr || prefix == nullptr) return; static_cast(sb)->setPrefix(*static_cast(prefix)); } extern "C" VQT6_API void vqt6_qspinbox_set_suffix(void* sb, void* suffix) { if (sb == nullptr || suffix == nullptr) return; static_cast(sb)->setSuffix(*static_cast(suffix)); } extern "C" VQT6_API void* vqt6_qspinbox_prefix(void* sb) { if (sb == nullptr) return nullptr; return new QString(static_cast(sb)->prefix()); } extern "C" VQT6_API void* vqt6_qspinbox_suffix(void* sb) { if (sb == nullptr) return nullptr; return new QString(static_cast(sb)->suffix()); } // ============================================================ // Layouts // ============================================================ extern "C" VQT6_API void vqt6_qlayout_add_widget(void* layout, void* widget) { if (layout == nullptr || widget == nullptr) return; static_cast(layout)->addWidget(static_cast(widget)); } extern "C" VQT6_API void vqt6_qlayout_remove_widget(void* layout, void* widget) { if (layout == nullptr || widget == nullptr) return; static_cast(layout)->removeWidget(static_cast(widget)); } extern "C" VQT6_API int vqt6_qlayout_count(void* layout) { if (layout == nullptr) return 0; return static_cast(layout)->count(); } extern "C" VQT6_API void* vqt6_qlayout_item_at(void* layout, int index) { if (layout == nullptr) return nullptr; QLayoutItem* item = static_cast(layout)->itemAt(index); return item != nullptr ? item->widget() : nullptr; } extern "C" VQT6_API void vqt6_qlayout_set_contents_margins(void* layout, int left, int top, int right, int bottom) { if (layout == nullptr) return; static_cast(layout)->setContentsMargins(left, top, right, bottom); } extern "C" VQT6_API void vqt6_qlayout_set_spacing(void* layout, int spacing) { if (layout == nullptr) return; static_cast(layout)->setSpacing(spacing); } extern "C" VQT6_API int vqt6_qlayout_spacing(void* layout) { if (layout == nullptr) return 0; return static_cast(layout)->spacing(); } extern "C" VQT6_API void vqt6_qlayout_invalidate(void* layout) { if (layout == nullptr) return; static_cast(layout)->invalidate(); } extern "C" VQT6_API void* vqt6_qhboxlayout_create(void) { return new QHBoxLayout(); } extern "C" VQT6_API void* vqt6_qhboxlayout_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QHBoxLayout(static_cast(parent)); } extern "C" VQT6_API void vqt6_qhboxlayout_add_layout(void* layout, void* child) { if (layout == nullptr || child == nullptr) return; static_cast(layout)->addLayout(static_cast(child)); } extern "C" VQT6_API void vqt6_qhboxlayout_add_stretch(void* layout, int stretch) { if (layout == nullptr) return; static_cast(layout)->addStretch(stretch); } extern "C" VQT6_API void vqt6_qhboxlayout_add_spacing(void* layout, int size) { if (layout == nullptr) return; static_cast(layout)->addSpacing(size); } extern "C" VQT6_API void* vqt6_qvboxlayout_create(void) { return new QVBoxLayout(); } extern "C" VQT6_API void* vqt6_qvboxlayout_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QVBoxLayout(static_cast(parent)); } extern "C" VQT6_API void vqt6_qvboxlayout_add_layout(void* layout, void* child) { if (layout == nullptr || child == nullptr) return; static_cast(layout)->addLayout(static_cast(child)); } extern "C" VQT6_API void vqt6_qvboxlayout_add_stretch(void* layout, int stretch) { if (layout == nullptr) return; static_cast(layout)->addStretch(stretch); } extern "C" VQT6_API void vqt6_qvboxlayout_add_spacing(void* layout, int size) { if (layout == nullptr) return; static_cast(layout)->addSpacing(size); } extern "C" VQT6_API void* vqt6_qgridlayout_create(void) { return new QGridLayout(); } extern "C" VQT6_API void* vqt6_qgridlayout_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QGridLayout(static_cast(parent)); } extern "C" VQT6_API void vqt6_qgridlayout_add_widget(void* gl, void* w, int row, int col) { if (gl == nullptr || w == nullptr) return; static_cast(gl)->addWidget(static_cast(w), row, col); } extern "C" VQT6_API void vqt6_qgridlayout_add_widget_with_span(void* gl, void* w, int row, int col, int row_span, int col_span) { if (gl == nullptr || w == nullptr) return; static_cast(gl)->addWidget(static_cast(w), row, col, row_span, col_span); } extern "C" VQT6_API void* vqt6_qformlayout_create(void) { return new QFormLayout(); } extern "C" VQT6_API void* vqt6_qformlayout_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QFormLayout(static_cast(parent)); } extern "C" VQT6_API void vqt6_qformlayout_add_row(void* fl, void* label, void* field) { if (fl == nullptr || label == nullptr || field == nullptr) return; static_cast(fl)->addRow(*static_cast(label), static_cast(field)); } extern "C" VQT6_API void vqt6_qformlayout_add_row_widget_pair(void* fl, void* label, void* field) { if (fl == nullptr || label == nullptr || field == nullptr) return; static_cast(fl)->addRow(static_cast(label), static_cast(field)); } // ============================================================ // QStackedWidget / QTabWidget // ============================================================ extern "C" VQT6_API void* vqt6_qstackedwidget_create(void) { return new QStackedWidget(); } extern "C" VQT6_API void* vqt6_qstackedwidget_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QStackedWidget(static_cast(parent)); } extern "C" VQT6_API int vqt6_qstackedwidget_add_widget(void* sw, void* w) { if (sw == nullptr || w == nullptr) return -1; return static_cast(sw)->addWidget(static_cast(w)); } extern "C" VQT6_API void vqt6_qstackedwidget_remove_widget(void* sw, void* w) { if (sw == nullptr || w == nullptr) return; static_cast(sw)->removeWidget(static_cast(w)); } extern "C" VQT6_API int vqt6_qstackedwidget_count(void* sw) { if (sw == nullptr) return 0; return static_cast(sw)->count(); } extern "C" VQT6_API int vqt6_qstackedwidget_current_index(void* sw) { if (sw == nullptr) return -1; return static_cast(sw)->currentIndex(); } extern "C" VQT6_API void vqt6_qstackedwidget_set_current_index(void* sw, int index) { if (sw == nullptr) return; static_cast(sw)->setCurrentIndex(index); } extern "C" VQT6_API void* vqt6_qstackedwidget_current_widget(void* sw) { if (sw == nullptr) return nullptr; return static_cast(sw)->currentWidget(); } extern "C" VQT6_API void* vqt6_qstackedwidget_widget(void* sw, int index) { if (sw == nullptr) return nullptr; return static_cast(sw)->widget(index); } extern "C" VQT6_API void* vqt6_qtabwidget_create(void) { return new QTabWidget(); } extern "C" VQT6_API void* vqt6_qtabwidget_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QTabWidget(static_cast(parent)); } extern "C" VQT6_API int vqt6_qtabwidget_add_tab(void* tw, void* w, void* label) { if (tw == nullptr || w == nullptr || label == nullptr) return -1; return static_cast(tw)->addTab(static_cast(w), *static_cast(label)); } extern "C" VQT6_API int vqt6_qtabwidget_insert_tab(void* tw, int index, void* w, void* label) { if (tw == nullptr || w == nullptr || label == nullptr) return -1; return static_cast(tw)->insertTab(index, static_cast(w), *static_cast(label)); } extern "C" VQT6_API void vqt6_qtabwidget_remove_tab(void* tw, int index) { if (tw == nullptr) return; static_cast(tw)->removeTab(index); } extern "C" VQT6_API int vqt6_qtabwidget_count(void* tw) { if (tw == nullptr) return 0; return static_cast(tw)->count(); } extern "C" VQT6_API int vqt6_qtabwidget_current_index(void* tw) { if (tw == nullptr) return -1; return static_cast(tw)->currentIndex(); } extern "C" VQT6_API void vqt6_qtabwidget_set_current_index(void* tw, int index) { if (tw == nullptr) return; static_cast(tw)->setCurrentIndex(index); } extern "C" VQT6_API void* vqt6_qtabwidget_tab_text(void* tw, int index) { if (tw == nullptr) return nullptr; return new QString(static_cast(tw)->tabText(index)); } extern "C" VQT6_API void vqt6_qtabwidget_set_tab_text(void* tw, int index, void* text) { if (tw == nullptr || text == nullptr) return; static_cast(tw)->setTabText(index, *static_cast(text)); } extern "C" VQT6_API void vqt6_qtabwidget_set_tabs_closable(void* tw, int closable) { if (tw == nullptr) return; static_cast(tw)->setTabsClosable(closable != 0); } extern "C" VQT6_API int vqt6_qtabwidget_tabs_closable(void* tw) { if (tw == nullptr) return 0; return static_cast(tw)->tabsClosable() ? 1 : 0; } // ============================================================ // QMenuBar / QMenu / QAction // ============================================================ extern "C" VQT6_API void* vqt6_qmenubar_create(void) { return new QMenuBar(); } extern "C" VQT6_API void* vqt6_qmenubar_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QMenuBar(static_cast(parent)); } extern "C" VQT6_API void* vqt6_qmenubar_add_menu(void* mb, void* title) { if (mb == nullptr || title == nullptr) return nullptr; return static_cast(mb)->addMenu(*static_cast(title)); } extern "C" VQT6_API void vqt6_qmenubar_add_menu_with_menu(void* mb, void* menu) { if (mb == nullptr || menu == nullptr) return; static_cast(mb)->addMenu(static_cast(menu)); } extern "C" VQT6_API void vqt6_qmenubar_add_action(void* mb, void* action) { if (mb == nullptr || action == nullptr) return; static_cast(mb)->addAction(static_cast(action)); } extern "C" VQT6_API void vqt6_qmenubar_clear(void* mb) { if (mb == nullptr) return; static_cast(mb)->clear(); } extern "C" VQT6_API void* vqt6_qmenu_create(void) { return new QMenu(); } extern "C" VQT6_API void* vqt6_qmenu_create_with_title(void* title) { if (title == nullptr) return nullptr; return new QMenu(*static_cast(title)); } extern "C" VQT6_API void* vqt6_qmenu_create_with_title_parent(void* title, void* parent) { if (title == nullptr || parent == nullptr) return nullptr; return new QMenu(*static_cast(title), static_cast(parent)); } extern "C" VQT6_API void* vqt6_qmenu_add_menu(void* menu, void* title) { if (menu == nullptr || title == nullptr) return nullptr; return static_cast(menu)->addMenu(*static_cast(title)); } extern "C" VQT6_API void vqt6_qmenu_add_action(void* menu, void* action) { if (menu == nullptr || action == nullptr) return; static_cast(menu)->addAction(static_cast(action)); } extern "C" VQT6_API void vqt6_qmenu_add_separator(void* menu) { if (menu == nullptr) return; static_cast(menu)->addSeparator(); } extern "C" VQT6_API void vqt6_qmenu_clear(void* menu) { if (menu == nullptr) return; static_cast(menu)->clear(); } extern "C" VQT6_API void vqt6_qmenu_set_title(void* menu, void* title) { if (menu == nullptr || title == nullptr) return; static_cast(menu)->setTitle(*static_cast(title)); } extern "C" VQT6_API void* vqt6_qmenu_title(void* menu) { if (menu == nullptr) return nullptr; return new QString(static_cast(menu)->title()); } extern "C" VQT6_API void* vqt6_qmenu_add_action_with_text(void* menu, void* text) { if (menu == nullptr || text == nullptr) return nullptr; return static_cast(menu)->addAction(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qaction_create(void) { return new QAction(); } extern "C" VQT6_API void* vqt6_qaction_create_with_text(void* text) { if (text == nullptr) return nullptr; return new QAction(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qaction_create_with_text_parent(void* text, void* parent) { if (text == nullptr || parent == nullptr) return nullptr; return new QAction(*static_cast(text), static_cast(parent)); } extern "C" VQT6_API void vqt6_qaction_set_text(void* action, void* text) { if (action == nullptr || text == nullptr) return; static_cast(action)->setText(*static_cast(text)); } extern "C" VQT6_API void* vqt6_qaction_text(void* action) { if (action == nullptr) return nullptr; return new QString(static_cast(action)->text()); } extern "C" VQT6_API void vqt6_qaction_set_icon(void* action, void* icon) { if (action == nullptr || icon == nullptr) return; static_cast(action)->setIcon(*static_cast(icon)); } extern "C" VQT6_API void* vqt6_qaction_icon(void* action) { if (action == nullptr) return nullptr; return new QIcon(static_cast(action)->icon()); } extern "C" VQT6_API void vqt6_qaction_set_shortcut(void* action, void* key_sequence) { if (action == nullptr || key_sequence == nullptr) return; static_cast(action)->setShortcut(QKeySequence(*static_cast(key_sequence))); } extern "C" VQT6_API void* vqt6_qaction_shortcut(void* action) { if (action == nullptr) return nullptr; return new QString(static_cast(action)->shortcut().toString()); } extern "C" VQT6_API void vqt6_qaction_set_checkable(void* action, int checkable) { if (action == nullptr) return; static_cast(action)->setCheckable(checkable != 0); } extern "C" VQT6_API int vqt6_qaction_is_checkable(void* action) { if (action == nullptr) return 0; return static_cast(action)->isCheckable() ? 1 : 0; } extern "C" VQT6_API void vqt6_qaction_set_checked(void* action, int checked) { if (action == nullptr) return; static_cast(action)->setChecked(checked != 0); } extern "C" VQT6_API int vqt6_qaction_is_checked(void* action) { if (action == nullptr) return 0; return static_cast(action)->isChecked() ? 1 : 0; } extern "C" VQT6_API void vqt6_qaction_set_enabled(void* action, int enabled) { if (action == nullptr) return; static_cast(action)->setEnabled(enabled != 0); } extern "C" VQT6_API int vqt6_qaction_is_enabled(void* action) { if (action == nullptr) return 0; return static_cast(action)->isEnabled() ? 1 : 0; } extern "C" VQT6_API void vqt6_qaction_trigger(void* action) { if (action == nullptr) return; static_cast(action)->trigger(); } // ============================================================ // QStatusBar / QToolBar // ============================================================ extern "C" VQT6_API void* vqt6_qstatusbar_create(void) { return new QStatusBar(); } extern "C" VQT6_API void* vqt6_qstatusbar_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QStatusBar(static_cast(parent)); } extern "C" VQT6_API void vqt6_qstatusbar_show_message(void* sb, void* message, int timeout_ms) { if (sb == nullptr || message == nullptr) return; static_cast(sb)->showMessage(*static_cast(message), timeout_ms); } extern "C" VQT6_API void vqt6_qstatusbar_clear_message(void* sb) { if (sb == nullptr) return; static_cast(sb)->clearMessage(); } extern "C" VQT6_API void* vqt6_qstatusbar_current_message(void* sb) { if (sb == nullptr) return nullptr; return new QString(static_cast(sb)->currentMessage()); } extern "C" VQT6_API void vqt6_qstatusbar_add_widget(void* sb, void* w, int stretch) { if (sb == nullptr || w == nullptr) return; static_cast(sb)->addWidget(static_cast(w), stretch); } extern "C" VQT6_API void vqt6_qstatusbar_add_permanent_widget(void* sb, void* w, int stretch) { if (sb == nullptr || w == nullptr) return; static_cast(sb)->addPermanentWidget(static_cast(w), stretch); } extern "C" VQT6_API void* vqt6_qtoolbar_create(void) { return new QToolBar(); } extern "C" VQT6_API void* vqt6_qtoolbar_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QToolBar(static_cast(parent)); } extern "C" VQT6_API void* vqt6_qtoolbar_add_widget(void* tb, void* w) { if (tb == nullptr || w == nullptr) return nullptr; return static_cast(tb)->addWidget(static_cast(w)); } extern "C" VQT6_API void vqt6_qtoolbar_add_action(void* tb, void* action) { if (tb == nullptr || action == nullptr) return; static_cast(tb)->addAction(static_cast(action)); } extern "C" VQT6_API void vqt6_qtoolbar_add_separator(void* tb) { if (tb == nullptr) return; static_cast(tb)->addSeparator(); } extern "C" VQT6_API void vqt6_qtoolbar_set_icon_size(void* tb, int w, int h) { if (tb == nullptr) return; static_cast(tb)->setIconSize(QSize(w, h)); } extern "C" VQT6_API void vqt6_qtoolbar_set_orientation(void* tb, int orientation) { if (tb == nullptr) return; static_cast(tb)->setOrientation(static_cast(orientation)); } extern "C" VQT6_API int vqt6_qtoolbar_orientation(void* tb) { if (tb == nullptr) return 0; return static_cast(static_cast(tb)->orientation()); } // ============================================================ // QMessageBox // ============================================================ extern "C" VQT6_API int vqt6_qmessagebox_information(void* parent, void* title, void* text, int buttons) { if (title == nullptr || text == nullptr) return 0; QMessageBox mb(static_cast(0x0400), *static_cast(title), *static_cast(text), static_cast(buttons), static_cast(parent)); return mb.exec(); } extern "C" VQT6_API int vqt6_qmessagebox_warning(void* parent, void* title, void* text, int buttons) { if (title == nullptr || text == nullptr) return 0; QMessageBox mb(static_cast(0x0200), *static_cast(title), *static_cast(text), static_cast(buttons), static_cast(parent)); return mb.exec(); } extern "C" VQT6_API int vqt6_qmessagebox_critical(void* parent, void* title, void* text, int buttons) { if (title == nullptr || text == nullptr) return 0; QMessageBox mb(static_cast(0x0100), *static_cast(title), *static_cast(text), static_cast(buttons), static_cast(parent)); return mb.exec(); } extern "C" VQT6_API int vqt6_qmessagebox_question(void* parent, void* title, void* text, int buttons) { if (title == nullptr || text == nullptr) return 0; QMessageBox mb(static_cast(0x0200), *static_cast(title), *static_cast(text), static_cast(buttons), static_cast(parent)); return mb.exec(); } extern "C" VQT6_API void vqt6_qmessagebox_about(void* parent, void* title, void* text) { if (title == nullptr || text == nullptr) return; QMessageBox::about(static_cast(parent), *static_cast(title), *static_cast(text)); } extern "C" VQT6_API void vqt6_qmessagebox_about_qt(void* parent) { QMessageBox::aboutQt(static_cast(parent)); } // ============================================================ // QFileDialog // ============================================================ extern "C" VQT6_API void* vqt6_qfiledialog_get_open_file_name(void* parent, void* caption, void* dir, void* filter) { QString* result = new QString(QFileDialog::getOpenFileName( static_cast(parent), caption != nullptr ? *static_cast(caption) : QString(), dir != nullptr ? *static_cast(dir) : QString(), filter != nullptr ? *static_cast(filter) : QString() )); return result; } extern "C" VQT6_API void* vqt6_qfiledialog_get_save_file_name(void* parent, void* caption, void* dir, void* filter) { QString* result = new QString(QFileDialog::getSaveFileName( static_cast(parent), caption != nullptr ? *static_cast(caption) : QString(), dir != nullptr ? *static_cast(dir) : QString(), filter != nullptr ? *static_cast(filter) : QString() )); return result; } extern "C" VQT6_API void* vqt6_qfiledialog_get_existing_directory(void* parent, void* caption, void* dir) { QString* result = new QString(QFileDialog::getExistingDirectory( static_cast(parent), caption != nullptr ? *static_cast(caption) : QString(), dir != nullptr ? *static_cast(dir) : QString() )); return result; } extern "C" VQT6_API void* vqt6_qfiledialog_get_open_file_names(void* parent, void* caption, void* dir, void* filter) { return new QStringList(QFileDialog::getOpenFileNames( static_cast(parent), caption != nullptr ? *static_cast(caption) : QString(), dir != nullptr ? *static_cast(dir) : QString(), filter != nullptr ? *static_cast(filter) : QString() )); } // ============================================================ // QTreeWidget / QTreeWidgetItem // ============================================================ extern "C" VQT6_API void* vqt6_qtreewidget_create(void) { return new QTreeWidget(); } extern "C" VQT6_API void* vqt6_qtreewidget_create_with_parent(void* parent) { if (parent == nullptr) return nullptr; return new QTreeWidget(static_cast(parent)); } extern "C" VQT6_API void vqt6_qtreewidget_add_top_level_item(void* tw, void* item) { if (tw == nullptr || item == nullptr) return; static_cast(tw)->addTopLevelItem(static_cast(item)); } extern "C" VQT6_API void vqt6_qtreewidget_insert_top_level_item(void* tw, int index, void* item) { if (tw == nullptr || item == nullptr) return; static_cast(tw)->insertTopLevelItem(index, static_cast(item)); } extern "C" VQT6_API int vqt6_qtreewidget_top_level_item_count(void* tw) { if (tw == nullptr) return 0; return static_cast(tw)->topLevelItemCount(); } extern "C" VQT6_API void* vqt6_qtreewidget_top_level_item(void* tw, int index) { if (tw == nullptr) return nullptr; return static_cast(tw)->topLevelItem(index); } extern "C" VQT6_API void* vqt6_qtreewidget_current_item(void* tw) { if (tw == nullptr) return nullptr; return static_cast(tw)->currentItem(); } extern "C" VQT6_API void vqt6_qtreewidget_expand_all(void* tw) { if (tw == nullptr) return; static_cast(tw)->expandAll(); } extern "C" VQT6_API void vqt6_qtreewidget_collapse_all(void* tw) { if (tw == nullptr) return; static_cast(tw)->collapseAll(); } extern "C" VQT6_API void vqt6_qtreewidget_set_header_hidden(void* tw, int hidden) { if (tw == nullptr) return; static_cast(tw)->setHeaderHidden(hidden != 0); } extern "C" VQT6_API void vqt6_qtreewidget_set_column_count(void* tw, int count) { if (tw == nullptr) return; static_cast(tw)->setColumnCount(count); } extern "C" VQT6_API void vqt6_qtreewidget_set_item_expanded(void* tw, void* item, int expanded) { if (item == nullptr) return; (void)tw; static_cast(item)->setExpanded(expanded != 0); } extern "C" VQT6_API void* vqt6_qtreewidgetitem_create(void* text) { QTreeWidgetItem* it = new QTreeWidgetItem(); if (text != nullptr) it->setText(0, *static_cast(text)); return it; } extern "C" VQT6_API void vqt6_qtreewidgetitem_add_child(void* item, void* child) { if (item == nullptr || child == nullptr) return; static_cast(item)->addChild(static_cast(child)); } extern "C" VQT6_API int vqt6_qtreewidgetitem_child_count(void* item) { if (item == nullptr) return 0; return static_cast(item)->childCount(); } extern "C" VQT6_API void* vqt6_qtreewidgetitem_child(void* item, int index) { if (item == nullptr) return nullptr; return static_cast(item)->child(index); } extern "C" VQT6_API void vqt6_qtreewidgetitem_set_text(void* item, void* text) { if (item == nullptr || text == nullptr) return; static_cast(item)->setText(0, *static_cast(text)); } extern "C" VQT6_API void* vqt6_qtreewidgetitem_text(void* item) { if (item == nullptr) return nullptr; return new QString(static_cast(item)->text(0)); } extern "C" VQT6_API void vqt6_qtreewidgetitem_set_checkable(void* item, int checkable) { if (item == nullptr) return; QTreeWidgetItem* it = static_cast(item); Qt::ItemFlags f = it->flags(); if (checkable != 0) f |= Qt::ItemIsUserCheckable; else f &= ~Qt::ItemIsUserCheckable; it->setFlags(f); } extern "C" VQT6_API void vqt6_qtreewidgetitem_set_check_state(void* item, int state) { if (item == nullptr) return; Qt::CheckState cs = Qt::Unchecked; if (state == 1) cs = Qt::PartiallyChecked; else if (state == 2) cs = Qt::Checked; static_cast(item)->setCheckState(0, cs); } extern "C" VQT6_API int vqt6_qtreewidgetitem_check_state(void* item) { if (item == nullptr) return 0; return static_cast(static_cast(item)->checkState(0)); } extern "C" VQT6_API void vqt6_qtreewidgetitem_set_expanded(void* item, int expanded) { if (item == nullptr) return; static_cast(item)->setExpanded(expanded != 0); } extern "C" VQT6_API int vqt6_qtreewidgetitem_is_expanded(void* item) { if (item == nullptr) return 0; return static_cast(item)->isExpanded() ? 1 : 0; } extern "C" VQT6_API void vqt6_qtreewidgetitem_set_data_int(void* item, int value) { if (item == nullptr) return; static_cast(item)->setData(0, Qt::UserRole, QVariant(value)); } extern "C" VQT6_API int vqt6_qtreewidgetitem_data_int(void* item) { if (item == nullptr) return 0; bool ok = false; int v = static_cast(item)->data(0, Qt::UserRole).toInt(&ok); return ok ? v : 0; } // ============================================================ // 信号连接(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(btn), &QPushButton::clicked, static_cast(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(btn), &QPushButton::toggled, static_cast(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(cb_widget), &QCheckBox::toggled, static_cast(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(cb_widget), &QCheckBox::checkStateChanged, static_cast(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(rb), &QRadioButton::toggled, static_cast(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(le), &QLineEdit::textChanged, static_cast(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(cb_widget), &QComboBox::currentIndexChanged, static_cast(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(s), &QSlider::valueChanged, static_cast(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(sb), &QSpinBox::valueChanged, static_cast(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(pb), &QProgressBar::valueChanged, static_cast(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(lw), &QListWidget::currentRowChanged, static_cast(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(tw), &QTabWidget::currentChanged, static_cast(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(action), &QAction::triggered, static_cast(action), [slot_id](bool) { vqt6_trigger_slot(slot_id); }); } extern "C" VQT6_API void vqt6_qtreewidget_connect_item_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(tw), &QTreeWidget::itemChanged, static_cast(tw), [slot_id](QTreeWidgetItem*, int) { vqt6_trigger_slot(slot_id); }); } extern "C" VQT6_API void vqt6_qtreewidget_connect_item_clicked(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(tw), &QTreeWidget::itemClicked, static_cast(tw), [slot_id](QTreeWidgetItem*, int) { vqt6_trigger_slot(slot_id); }); }