代码之家  ›  专栏  ›  技术社区  ›  hidefromkgb

强制gtklabel剪切其居中对齐的文本

  •  6
  • hidefromkgb  · 技术社区  · 8 年前

    我有一个 GtkLabel 其文本将保持居中,而不管其短于或长于标签。

    例如,具有 SS_CENTER 样式标志集的行为如下:

                 ┌===========================┐
                 │     Lorem ipsum dolor     │
                 └===========================┘
    

    当文本短于控件时;

                 ┌===========================┐
      Lorem ipsum│dolor sit amet, consectetur│adipiscing
                 └===========================┘
    

    当文本长于控件时。

    N.B.: 用户看到的文本的唯一部分在框架内。

    我预料到了 格特克拉贝尔 -s执行相同的操作,但实际上它们呈现的居中文本不同:

    _
    _墈墈lorem ipsum dolor墈墈
    ==================
    

    当文本短于控件时;

                 ┌===========================┐
                 │Lorem ipsum dolor sit amet,│consectetur adipiscing
                 └===========================┘
    

    当文本长于控件时。

    如何在 格特克拉贝尔 即使很长,也要保持中心?

    以防万一:用户看到的实际文本以~4 fps更新,并且在运行时之前未知。

    2 回复  |  直到 8 年前
        1
  •  2
  •   liberforce    8 年前

    这可能是可行的,但是从用户体验的角度来看,显示一个句子的半随机部分并没有真正意义。

    也许看看 gtk_label_set_ellipsize ? 他们使用 PangoEllipsizeMode 告诉你要隐藏句子的哪一部分。然后可以隐藏标签的开始、中间或结束部分。不过,它是一个枚举,而不是一个标志,因此您将无法隐藏开始+结束以仅显示中间部分。

    所以我看到的可能的解决方案是:

    • 将gtklabel分为子类,自己画,可能和pangoaciro一起画。
    • 或者在GTK+中添加新的包装模式并实现它(在Pango中?泛古宙?两者都有?)

    如果这不是一个强烈的要求,只需使用一个健全的行为和使用现有的消除模式。

        2
  •  1
  •   hidefromkgb    8 年前

    最后,解决方案准备就绪。

    #include <gtk/gtk.h>
    
    struct SCTX {
        GtkWidget *text;
        GdkRectangle rect;
    };
    
    void Resize(GtkWidget *view, GdkRectangle *rect, gpointer user) {
        struct SCTX *sctx = user;
        GtkRequisition requ;
    
        if ((sctx->rect.width  != rect->width )
        ||  (sctx->rect.height != rect->height)) {
            sctx->rect = *rect;
            gtk_widget_size_request(sctx->text, &requ);
            gtk_layout_move(view, sctx->text, (rect->width  - requ.width ) / 2,
                                              (rect->height - requ.height) / 2);
        }
    }
    
    int main(int argc, char *argv[]) {
        GtkWidget *hwnd, *view;
        struct SCTX sctx = {0};
    
        gtk_init(&argc, &argv);
        hwnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        g_signal_connect(hwnd, "destroy", gtk_main_quit, 0);
    
        view = gtk_layout_new(0, 0);
        g_signal_connect(view, "size-allocate", G_CALLBACK(Resize), &sctx);
        gtk_widget_set_size_request(view, 320, 200);
    
        sctx.text = gtk_label_new("Lorem ipsum dolor sit amet, consectetur "
                                  "adipiscing elit, sed do eiusmod tempor "
                                  "incididunt ut labore et dolore magna aliqua");
        gtk_container_add(view, sctx.text);
    
        gtk_container_add(hwnd, view);
        gtk_container_set_border_width(GTK_CONTAINER(hwnd), 32);
        gtk_window_set_position(GTK_WINDOW(hwnd), GTK_WIN_POS_CENTER);
        gtk_widget_show_all(hwnd);
        gtk_main();
        return 0;
    }
    

    这里的关键部分是包装 GtkLayout 围绕我们 GtkLabel 所以前者可以将后者移动到其边界内。