【问题标题】:Running a function when user stops entering text当用户停止输入文本时运行函数
【发布时间】:2013-01-11 12:04:56
【问题描述】:

我正在使用 Haskell 的 gtk2hs 库编写一个小型 GUI 应用程序,目前正在使用其中的 multiline text boxes。我有一个功能,当用户对文本框中的文本进行更改时,我想运行它,但不希望他们必须单击按钮来激活它。

此外,因为它是一个相当侵入性和处理密集型的功能(它绘制图形、加载文件等),我希望它不会在用户进行 any 更改时触发(这可能我猜是用文本缓冲区中的bufferChanged 信号完成的?)但是当它们在更改之间停止几秒钟时。

基本上我想知道 gtk 中是否有类似于 range widgets 可以将其更新策略设置为 continuous or delayed 的方式,但对于文本框

【问题讨论】:

  • 我在 wxHaskell 中做类似事情的一种方法是使用设置为(可配置)1 秒延迟的 Timer 对象,并在每次用户键入时启用它,这具有延迟的效果第二次打字完成后。我放弃了 gtk,所以我对它不熟悉,但也许你可以使用 timeoutAddtimeoutAddFulltimeoutRemove from Graphics.UI.Gtk.General.General 做类似的事情。
  • 不知道它在 Haskell 端口中叫什么,但这就是 g_idle_add() 的用途。
  • 或者(根据@AndrewC 的建议),记录最后一次用户输入的时间,并在定期超时中检查以决定何时运行繁重的代码。

标签: user-interface haskell gtk signals gtk2hs


【解决方案1】:

我对 Haskell 绑定一无所知,但在纯 C 语言中,通过利用超时 GSource 很容易实现。

#include <gtk/gtk.h>

static guint source_id = 0;

static gboolean do_stuff(gpointer user_data)
{
    g_print("doing stuff...\n");
    return FALSE;
}

static void postpone(void)
{
    if (source_id > 0)
        g_source_remove(source_id);
    source_id = g_timeout_add(1000, do_stuff, NULL);
}

int main(int argc, char **argv)
{
    GtkWidget *window, *text_view;
    GtkTextBuffer *text_buffer;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);

    text_view = gtk_text_view_new();
    gtk_container_add(GTK_CONTAINER(window), text_view);

    text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
    g_signal_connect(text_buffer, "changed", G_CALLBACK(postpone), NULL);

    gtk_widget_show_all(window);
    gtk_main();
    return 0;
}

在超时之前退出 TextView 的问题仍然存在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-31
    • 2020-03-09
    • 2021-07-27
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 2021-11-15
    相关资源
    最近更新 更多