c - GTK+3 大小分配事件不像 GTK+2 那样实时
问题描述
我正在尝试从 GTK+2 迁移到 GTK+3,但发现了一个问题。在 GTK+2 中,当用户主动调整窗口大小时,大小分配事件会实时发生。但是在 GTK+3 中,直到释放鼠标单击才发生调整大小,在拖动时没有大小分配信号,就像在 GTK+2 中一样。是否有任何解决方法,或者 GTK+3 就是这样?我可以看到窗口中的任何内容都没有更新,直到释放鼠标单击拖动,在 GTK+2 中窗口中的东西主动调整。
我需要在窗口主动调整大小时更新小部件,并实时了解所有小部件的大小,以便在大小更改时重新绘制一些小部件,因为在调整大小时需要查看模式。但是在 GTK+3 中,小部件在拖动事件完成之前不会进行任何尺寸更改或更新(将窗口拖动到所需尺寸后释放鼠标按钮)。这对我不起作用,如果没有解决方案,我将被迫坚持使用 GTK+2。
编辑:我被要求提供在 GTK2 中工作的代码,所以这里有一个像 gtk2 中需要的小程序,在调整窗口大小时显示高度和宽度,但在 gtk3 中,高度和宽度仅在之后显示调整窗口大小后释放鼠标按钮。我还可以清楚地看到,在 gtk3 中,窗口的内部区域在释放鼠标按钮之前不会调整大小,因此似乎 gtk3 本身在检测到调整大小完成之前不会调整任何小部件的大小。
int main (int argc, char **argv)
{
gtk_init(&argc, &argv);
main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(main_window), "test window");
g_signal_connect(main_window, "size-allocate", G_CALLBACK(getsize_main_window), NULL);
gtk_window_set_default_size(GTK_WINDOW(main_window), 800, 600);
gtk_window_set_position(GTK_WINDOW(main_window), GTK_WIN_POS_CENTER);
g_signal_connect(G_OBJECT(main_window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(main_window);
gtk_main();
return 0;
}
void getsize_main_window(GtkWidget *widget, GtkAllocation *allocation, void *data)
{
printf ("main window width = %d, height = %d\n", allocation->width, allocation->height);
}
解决方案
我下载、构建并运行了针对两者构建的测试程序gtk+-2.0
和gtk+-3.0
. 我正在使用 Fedora 29 并安装了两者 gtk2
gtk3
该程序在两个版本中的行为相似。我得到了类似的事件日志和事件频率。
所以,我无法在这里重现您的问题。
您是否能够在您的系统上验证您的测试程序的“不良”行为gtk3
?也就是说,它是否准确地展示了您的问题以及您的完整程序?有没有以前没有提到的其他注意事项?
在我运行这个测试之前,我打算建议可能有一个更好的信号/事件来挂钩。而且, for 的行为gtk2
可能是一个副作用(在 中“修复”了gtk3
)。我打算尝试不同的活动,看看是否有一个更好的选择。
请注意,如果您可以改进示例代码(即直到它与gtk3
.
请注意,您的示例程序一开始并没有完全编译。所以,我修复了编译错误。
我在您的日志消息中添加了一些员工时间戳以帮助调试。
这是修改后的程序(as test.c
):
#include <stdio.h>
#include <time.h>
#include <gtk/gtk.h>
gpointer main_window;
typedef long long tsc_t;
int last_wid = -99999;
int last_hgt = -99999;
int evt_count = 0;
tsc_t tsczero;
tsc_t tsctlat;
tsc_t
tscget(void)
{
struct timespec ts;
tsc_t tsc;
clock_gettime(CLOCK_MONOTONIC,&ts);
tsc = ts.tv_sec;
tsc *= 1000000000;
tsc += ts.tv_nsec;
tsc -= tsczero;
return tsc;
}
double
tscsec(tsc_t tsc)
{
double sec;
sec = tsc;
sec /= 1e9;
return sec;
}
void
getsize_main_window(GtkWidget *widget, GtkAllocation *geo, void *data)
{
int chgflg = 0;
tsc_t tscnow;
tscnow = tscget();
if (last_wid != geo->width)
chgflg = 1;
if (last_hgt != geo->height)
chgflg = 1;
++evt_count;
if (chgflg) {
printf("%.9f getsize_main_window: width=%d%+d height=%d%+d events=%d (ELAPSED: %.9f)\n",
tscsec(tscnow),
geo->width, geo->width - last_wid,
geo->height, geo->height - last_hgt,
evt_count,
tscsec(tscnow - tsctlat));
evt_count = 0;
}
if (chgflg) {
last_wid = geo->width;
last_hgt = geo->height;
}
tsctlat = tscnow;
}
int
main(int argc, char **argv)
{
char buf[100];
tsczero = tscget();
tsctlat = tscget();
gtk_init(&argc, &argv);
main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
sprintf(buf,"test window v%d",V);
gtk_window_set_title(GTK_WINDOW(main_window), buf);
g_signal_connect(main_window, "size-allocate",
G_CALLBACK(getsize_main_window), NULL);
gtk_window_set_default_size(GTK_WINDOW(main_window), 800, 600);
gtk_window_set_position(GTK_WINDOW(main_window), GTK_WIN_POS_CENTER);
g_signal_connect(G_OBJECT(main_window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(main_window);
gtk_main();
return 0;
}
这是我创建的[粗略] Makefile
:
ifndef V
V := 2
endif
PKG = gtk+-$(V).0
CFLAGS += $(shell pkg-config --cflags $(PKG))
LIBS = $(shell pkg-config --libs $(PKG))
all: test
test.o: test.c
cc -c $(CFLAGS) "-DV=$(V)" test.c
test: test.o
cc -o test test.o $(LIBS)
clean:
rm -f *.o test
推荐阅读
- exception - 不支持给定路径格式:How to resolve this error in My VS 2019 code
- web - NodeJS URL 内容发送
- r - 是否有显示一列中仅有的 4 位数字的功能?
- swiftui - 将返回按钮添加到 UINavigationBar SwiftUI
- php - 替换 woocommerce_add_order_item_meta 钩子
- c# - 如何从添加到字典中的数组中删除重复值
- reactjs - TypeError:无法读取未定义的属性(读取“地图”),以及 React.js 中的多个 API 请求
- excel - 从单元格引用中获取行号
- haskell - 制作在自身上运行其输入的函数时出现无限类型错误
- kubernetes - Argocd 使用高内存的原因