/* * Copyright (C) 2020 Jordan Halase * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include /* Name of the Python GTK Widget class */ #define WIDGET_NAME "MainWidget" /* Name of the Python module */ #define MODULE_NAME ("ui." WIDGET_NAME) /** Initialize a Python interpreter and load the main module */ static PyObject *init_python_module(const char *module_name) { Py_Initialize(); PyObject *sys_path = PySys_GetObject("path"); PyList_Append(sys_path, PyUnicode_FromString(".")); PyObject *module = PyImport_ImportModule(module_name); if (!module) { PyErr_Print(); } return module; } /** Construct a new Python widget from a loaded module */ static GtkWidget *new_python_widget(PyObject *module) { PyObject *widget_py = PyObject_CallMethod(module, WIDGET_NAME, ""); if (!widget_py) { PyErr_Print(); return NULL; } GObject *observed = pygobject_get(widget_py); if (!observed || !G_IS_OBJECT(observed)) { fprintf(stderr, WIDGET_NAME " not a GObject\n"); } return GTK_WIDGET(observed); } static void on_activate(GtkApplication *app) { PyObject *module = init_python_module(MODULE_NAME); GtkWidget *win = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(win), "PyGObject Widget from C"); GtkWidget *widget = new_python_widget(module); gtk_container_add(GTK_CONTAINER(win), widget); g_signal_connect_swapped(win, "destroy", G_CALLBACK(gtk_widget_destroy), win); gtk_widget_show_all(win); } int main(int argc, char **argv) { GtkApplication *app = gtk_application_new("com.example.GtkApplication", G_APPLICATION_FLAGS_NONE); g_signal_connect(app, "activate", G_CALLBACK(on_activate), NULL); g_application_run(G_APPLICATION(app), argc, argv); return Py_FinalizeEx(); }