#c #gtk #hardware
#c #gtk #аппаратное обеспечение
Вопрос:
Я использую GTK в качестве пользовательского интерфейса к аппаратному обеспечению (3D-принтеру). Аппаратное обеспечение может создавать события в результате взаимодействия пользователя с машиной (не с графическим интерфейсом). Например, они могут удалить панель сборки, которая отключает переключатель, таким образом посылая сигнал в мою программу о том, что это произошло, но как мне заставить gtk_main() распознать, что это событие произошло?
Другими словами, как мне заставить gtk_main() отслеживать нестандартные события ввода устройства?
Ответ №1:
Вы можете использовать пользовательские действия, предоставляемые GtkApplication.
В любом случае вы должны самостоятельно реализовать код мониторинга, либо путем опроса состояния вашего оборудования, либо с использованием более продвинутых методов (если это возможно).
/* gcc -o monitor monitor.c $(pkg-config --cflags --libs gtk -3.0) */
#include <gtk/gtk.h>
static void
startup(GtkApplication *application)
{
GAction *action;
/* plate-removed is a custom action */
action = G_ACTION(g_simple_action_new("plate-removed", NULL));
g_action_map_add_action(G_ACTION_MAP(application), action);
g_object_unref(action);
/* You can connect your callbacks to the GAction::activate signal */
action = g_action_map_lookup_action(G_ACTION_MAP(application), "plate-removed");
g_signal_connect_swapped(action, "activate",
G_CALLBACK(g_print), "Plate has been removedn");
}
static gpointer
worker_thread(gpointer user_data)
{
GApplication *application = G_APPLICATION(user_data);
for (;;) {
g_usleep(g_random_int_range(500000, 5000000));
/* Event occurred: emit the signal */
g_action_group_activate_action(G_ACTION_GROUP(application),
"plate-removed", NULL);
}
return NULL;
}
static gboolean
polling_loop(gpointer user_data)
{
GApplication *application = G_APPLICATION(user_data);
if (g_random_int_range(1, 20) == 8) {
/* Event occurred: emit the signal */
g_action_group_activate_action(G_ACTION_GROUP(application),
"plate-removed", NULL);
}
return G_SOURCE_CONTINUE;
}
static void
activate(GtkApplication *application)
{
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_application_add_window(application, GTK_WINDOW(window));
gtk_widget_show_all(window);
/* You can use whatever you want to monitor your hardware, in particular
* a polling loop or a worker thread */
g_timeout_add(50, polling_loop, application);
/* g_thread_new("WorkerThread", worker_thread, application); */
}
int
main(int argc, char *argv[])
{
GtkApplication *application;
int retval;
application = gtk_application_new(NULL, G_APPLICATION_FLAGS_NONE);
g_signal_connect(application, "startup", G_CALLBACK(startup), NULL);
g_signal_connect(application, "activate", G_CALLBACK(activate), NULL);
retval = g_application_run(G_APPLICATION(application), argc, argv);
g_object_unref(application);
return retval;
}