在我的 Gtk-Gdk-Cairo-Pango 应用程序的开头,我创建了窗口:
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
首先,有GtkWindow
,但gtk_create_window
返回GtkWidget
,没有GtkWindow
,为什么?
然后,一些功能,如gdk_window_process_updates(..)
require GdkWindow*
。
gtk_window_set_geometry_hints()
另一方面需要GtkWindow*
.
在文档中也GdkWindow* gdk_window_new()
有返回GdkWindow
。
当然有文件说:
GdkWindow 是屏幕上的一个矩形区域。它是一个低级对象,用于在 GTK+ 级别上实现 GtkWidget 和 GtkWindow 等高级对象。GtkWindow 是一个顶层窗口,用户可能会认为它是一个带有标题栏等的“窗口”;一个 GtkWindow 可能包含许多 GdkWindow。
但它仍然没有告诉我,何时以及为什么应该创建 Gtk 或 Gdk 窗口?这里要遵循的模式是什么?
现在你问,我要解决什么特别的问题?当然,我尝试在鼠标移动之后在 gtk+gdk 之上使用 cairo+pango 绘制文本。问题是,虽然实际绘图似乎执行得很快,但我无法让它在鼠标移动时完全发生。在我motion_notify_event
的调用gtk_widget_queue_draw(GtkWidget)
中,但实际鼠标在屏幕上的移动明显滞后,即使我绘制单个字符,它在移动阶段也没有与鼠标指针对齐,只有在鼠标停止后才捕捉到它。
我尝试的是通过调用来加速更新gdk_window_process_updates(GDK_WINDOW(window), false);
,编译器吃掉它,但我得到了运行时断言:Gdk-CRITICAL **: gdk_window_process_updates: assertion 'GDK_IS_WINDOW (window)' failed
. 我找不到有关此宏以及如何/何时使用它的任何信息。
#include <cairo.h>
#include <gtk/gtk.h>
#define TXT "1234567890"
int X = 0, Y = 0;
static void do_drawing(cairo_t *);
GtkWidget *window;
PangoLayout *layout = 0;
static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
gpointer user_data) {
do_drawing(cr);
return FALSE;
}
static void do_drawing(cairo_t *cr) {
if (layout == 0) {
layout = pango_cairo_create_layout (cr);
pango_layout_set_text (layout, TXT, -1);
}
for (int y = 0; y < 2; y++) {
cairo_set_source_rgb (cr, 1, 0, 1);
cairo_move_to (cr, 0+X, 0 + y * 20 + Y);
pango_cairo_show_layout (cr, layout);
}
gtk_widget_queue_draw(window);
}
static gint onmouse(GtkWidget *widget, GdkEventMotion *event) {
X = event->x; Y = event->y;
gtk_widget_queue_draw(widget);
gdk_window_process_updates(GDK_WINDOW(widget), false);
}
int main(int argc, char *argv[]) {
GtkWidget *darea;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
darea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), darea);
gtk_widget_set_events (window, GDK_EXPOSURE_MASK
| GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK);
g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(on_draw_event), NULL);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(window, "motion_notify_event", G_CALLBACK(onmouse), NULL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 5000, 5000);
gtk_window_set_title(GTK_WINDOW(window), "Lines");
gtk_widget_show_all(window);
gtk_main();
return 0;
}