exe*_*ook 11 gtk pango cairo gdk pangocairo
在我的Gtk-Gdk-Cairo-Pango应用程序的开头,我创建了窗口:
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
Run Code Online (Sandbox Code Playgroud)
首先,有GtkWindow,但gtk_create_window返回GtkWidget,不是GtkWindow,为什么?
然后,一些功能,如gdk_window_process_updates(..)要求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 <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;
}
Run Code Online (Sandbox Code Playgroud)
and*_*abs 23
窗口管理器(X11,Wayland,Windows的user32.dll,以及Mac OS X中我不记得的那个)不一定(必然)提供很多功能.他们给你的是:
当与工具结合使用矢量图形和文本渲染到窗口(通常由其他库提供,例如cairo和pango)时,GUI工具包开始发挥作用.这就是窗口管理器窗口并将其划分为您熟悉的所有小控件:按钮,文本字段,列表,选项卡,网页渲染器等.
在这种情况下,GTK +是GUI工具包.它提供了您在程序中使用的大量控件.
使用GUI工具包时,通常不直接与窗口管理器交互.相反,GUI工具包提供了自己的窗口.当您创建GUI工具包窗口时,GUI工具包会创建基础窗口管理器窗口,然后控制所有绘图和事件,以便它可以处理在该窗口中为您提供所有这些整洁控件的工作.
对于GTK +,这是GtkWindow.
GTK +的设计者不希望拥有GTK +在GTK +中支持的每个平台的所有窗口管理器交互代码.相反,他们创建了一个单独的库(包含在GTK +源代码中),称为GDK.GDK围绕低级平台特定的窗口管理器功能提供一致的可移植API.
所以GdkWindow是包含窗口管理器窗口的类型,并提供GTK +使用的可移植接口.当您创建GdkWindow时,您将创建其中一个低级窗口管理器窗口,而不是您放置控件的更丰富的GtkWindow.
X11在历史上一直非常受资源限制.GTK +不为每个控件创建一个窗口管理器窗口; 它只为GtkWindow,GtkPopover和其他类似控件创建这些控件,这些控件充当了我们用户认为的窗口.
拥有所有这些知识,您现在可以找到问题的答案:您几乎总是想要使用GtkWindow,而且几乎从不想使用GdkWindow.GdkWindow仅对某些GTK +控件的实现非常有用.
GdkWindow和GtkWindow不可互换.
(对于正在发生的事情,这仍然是相当准确的过度简化.它并不适用于所有环境.例如,编写本机Windows程序的人通常会为每个控件创建窗口管理器窗口,窗口管理器提供一些窗口管理器窗口基本控件,如按钮.我可能也在上面的解释中得到了一些错误的细节.)
GDK和GTK +之间的分离还有其他几个优点.例如,添加Wayland支持(据我所知,我很可能错误)需要对GTK +本身进行许多更改,并且有一个名为broadway的GDK层,它允许普通的GTK +程序在Web浏览器中呈现.
更新,因为我似乎连接了很多:
| 归档时间: |
|
| 查看次数: |
4727 次 |
| 最近记录: |