标识符“GdkEventKey”未定义 C/C++(20)

问题描述 投票:0回答:1

这是我的 C++ 和 GTK-4 代码。我正在尝试制作一个简单的计时器应用程序,当我们锁定屏幕并基于此停止计时器时,它可以监听全局和本地键盘快捷键,在

Linux Pop! OS 22

中工作
#include <gtk-4.0/gtk/gtk.h>
#include <gtk-4.0/gdk/gdk.h>
#include <chrono>
#include <iostream>
#include <string>

using namespace std;

guint timerID = 0;
chrono::steady_clock::time_point timePoint;

GtkWidget *label;

void startTimer()
{
  if (timerID != 0)
  {
    gtk_label_set_text(GTK_LABEL(label), "Timer is already running");
  }
  else
  {
    gtk_label_set_text(GTK_LABEL(label), "Timer Started");

    timePoint = chrono::steady_clock::now();

    timerID = g_timeout_add(
        1000,
        [](gpointer userData) -> gboolean
        {
          auto now = chrono::steady_clock::now();
          auto diff = chrono::duration_cast<chrono::seconds>(now - timePoint);

          gtk_label_set_text(GTK_LABEL(label), (to_string(diff.count()) + " seconds now!").c_str());

          return G_SOURCE_CONTINUE;
        },
        nullptr);
  }
}

void stopTimer()
{
  if (timerID != 0)
  {
    g_source_remove(timerID);
    timerID = 0;
    gtk_label_set_text(GTK_LABEL(label), "Timer is not running");
  }
  else
  {
    gtk_label_set_text(GTK_LABEL(label), "Timer is not running");
  }
}

static gboolean onKeyPress(GtkWidget *widget, GdkEventKey *event, gpointer userData)
{
  if (GDK_CONTROL_MASK && gdk_key_event_get_keyval(event) == GDK_KEY_Escape)
  {
    g_print("Ctrl + ESC key pressed\n");
  }

  return TRUE;
}

void applyStyle(GtkWidget *widget, const char *style)
{
  GtkStyleContext *context = gtk_widget_get_style_context(widget);
  GtkCssProvider *provider = gtk_css_provider_new();

  gtk_css_provider_load_from_data(provider, style, -1);
  gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
  g_object_unref(provider);
}

static void activate(GtkApplication *app, gpointer userData)
{
  GtkWidget *window;
  GtkWidget *box;
  GtkWidget *button;
  GtkWidget *grid;

  window = gtk_application_window_new(app);
  gtk_window_set_title(GTK_WINDOW(window), "Timer");
  gtk_window_set_default_size(GTK_WINDOW(window), 800, 350);

  g_signal_connect(window, "key-press-event", G_CALLBACK(onKeyPress), nullptr);

  box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
  gtk_widget_set_halign(box, GTK_ALIGN_CENTER);
  gtk_widget_set_valign(box, GTK_ALIGN_CENTER);

  gtk_window_set_child(GTK_WINDOW(window), box);

  // button = gtk_button_new_with_label("Start");

  // g_signal_connect(button, "clicked", G_CALLBACK(printHelloWorld), nullptr);
  // g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_window_close), nullptr);

  // gtk_box_append(GTK_BOX(box), button);

  grid = gtk_grid_new();

  gtk_grid_set_row_spacing(GTK_GRID(grid), 10);
  gtk_grid_set_column_spacing(GTK_GRID(grid), 10);

  // gtk_window_set_child(GTK_WINDOW(window), grid);


  gtk_box_append(GTK_BOX(box), grid);

  label = gtk_label_new("Timer is not running");
  gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 2, 1);

  button = gtk_button_new_with_label("Start");
  applyStyle(button, "button { background: green; color: white; } button:active { background: darkgreen; }");
  g_signal_connect(button, "clicked", G_CALLBACK(startTimer), nullptr);
  gtk_grid_attach(GTK_GRID(grid), button, 0, 1, 1, 1);

  button = gtk_button_new_with_label("Stop");
  applyStyle(button, "button { background: firebrick; color: white; } button:active { background: darkred; }");
  g_signal_connect(button, "clicked", G_CALLBACK(stopTimer), nullptr);
  gtk_grid_attach(GTK_GRID(grid), button, 1, 1, 1, 1);

  gtk_window_present(GTK_WINDOW(window));
}

int main(int argc, char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new("org.nhrdev.timer", G_APPLICATION_FLAGS_NONE);
  g_signal_connect(app, "activate", G_CALLBACK(activate), nullptr);
  status = g_application_run(G_APPLICATION(app), argc, argv);
  g_object_unref(app);

  return status;
}

尝试在应用程序上添加

key-press-event
侦听器,但 VS Code 显示此错误,甚至编译器也

这是我的

c_cpp_properties.json

{
    "configurations": [
        {
            "name": "Linux",
            "compilerPath": "/usr/bin/g++-12",
            "includePath": [
                "${workspaceFolder}/**",
                "/usr/include/gtk-4.0",
                "/usr/include/gtk-4.0/gdk",
                "/usr/include/glib-2.0",
                "/usr/lib/x86_64-linux-gnu/glib-2.0/include",
                "/usr/include/pango-1.0",
                "/usr/include/harfbuzz",
                "/usr/include/cairo",
                "/usr/include/atk-1.0",
                "/usr/include/gdk-pixbuf-2.0",
                "/usr/include/graphene-1.0",
                "/usr/lib/x86_64-linux-gnu/graphene-1.0/include"
            ],
            "defines": [],
            "cppStandard": "gnu++23",
            "intelliSenseMode": "linux-gcc-x64",
            "browse": {
                "path": [
                    "/usr/include"
                ]
            }
        }
    ],
    "version": 4
}

我试图从Chat-GPT、Bard找到解决方案,但没有人能提供任何可行的解决方案

c++ event-handling gtk4
1个回答
0
投票

g_signal_connect(window, "按键事件", G_CALLBACK(onKeyPress), nullptr);

这不是创建控制器的方法。您的 G_CALLBACK(onKeyPress) 是正确的,但 "key-press-event" 不是直接信号,它来自控制器。要创建您需要的控制器:

  1. 使用 GtkEventController* gtk_event_controller_key_new (void) 创建事件

  2. 将创建的事件(不是您的小部件)连接到您的 G_CALLBACK。

  3. 使用

    将创建的事件添加到包含该事件的小部件中

gtk_widget_add_controller ( GtkWidget* 小部件, GtkEventController* 控制器 )

© www.soinside.com 2019 - 2024. All rights reserved.