C语言 GTK按钮约束比例

xe55xuns  于 2023-03-28  发布在  其他
关注(0)|答案(1)|浏览(120)

我在一个GTK Flowbox中有一堆GTK按钮,我使用CSS border-radius属性将它们变成圆形,并将背景图像作为背景。不幸的是,它们随后显示为椭圆形,如下面的picrel。我该怎么做才能使按钮的高度始终等于宽度,从而保持完美的圆形形状?

按要求进行地雷危险教育:C文件:

#include <gtk/gtk.h>

#define WINDOW_HEIGHT 600

GtkWidget * stop;
int num_stops; 

static void stop_toggle (GtkToggleButton *source, gpointer user_data) {
    //have to use set child here
    if (gtk_toggle_button_get_active(source)) {
        gtk_widget_set_name(GTK_WIDGET(source), "stop_button_pressed");
    }
    else {
        gtk_widget_set_name(GTK_WIDGET(source), "stop_button");
    }
}  

static void make_toggles (GtkWidget * window) {
    GtkWidget * stop_flow;
    short i; 

    stop_flow = gtk_flow_box_new();
    
    //initialise stops on this panel
    char label[7]; label[0] = '\0';
    for (i = 0; i < num_stops; i++) {
        sprintf(label, "%d", i);
        stop = gtk_toggle_button_new_with_label(label);
        gtk_widget_set_name(stop, "stop_button");
        
        gtk_flow_box_append(GTK_FLOW_BOX(stop_flow), stop);
        g_signal_connect(stop, "toggled", G_CALLBACK(stop_toggle), NULL);
    }
    gtk_flow_box_set_column_spacing(GTK_FLOW_BOX(stop_flow), 15);
    gtk_flow_box_set_row_spacing(GTK_FLOW_BOX(stop_flow), 10);
    gtk_flow_box_set_selection_mode(GTK_FLOW_BOX(stop_flow), GTK_SELECTION_NONE);
    
    gtk_widget_set_name(stop_flow, "window_main");
    gtk_window_set_child (GTK_WINDOW (window), stop_flow);
}
static void app_startup(GtkApplication* app) {
    //use this to figure out number of stops and pistons from the LCS app
    num_stops = 16; 
}
static void activate (GtkApplication* app, gpointer user_data) {
    GtkWidget *window;

    window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "Left Panel");
    gtk_window_set_default_size (GTK_WINDOW (window), 800, WINDOW_HEIGHT);
    make_toggles(window);
    
    GtkCssProvider * cssProvider = gtk_css_provider_new();
    gtk_css_provider_load_from_path(cssProvider, "/your_location/GTK/styling2.css");
    gtk_style_context_add_provider_for_display(gtk_widget_get_display(window), GTK_STYLE_PROVIDER(cssProvider),
                                                                    GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
    gtk_widget_show (window);
}

int main(int argc, char **argv) {
    GtkApplication *app;
    int status;

    app = gtk_application_new("lcs.console", G_APPLICATION_DEFAULT_FLAGS);
    g_signal_connect(app, "startup", G_CALLBACK(app_startup), NULL);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}

Css文件:

w_main {
    background-color: grey;
}

#stop_button {
    background-color: white;
    background-size: 100% 100%;
    background-position: center center;
    border-radius: 50%;
    color: black;
    font-weight: bold;
    font-size: xx-large;
}
#stop_button_pressed {
    background-color: yellow;
    background-size: 100% 100%;
    background-position: center center;
    border-radius: 50%;
    color: black;
    font-weight: bold;
    font-size: xx-large;
}

你可以通过gcc-Wall pkg-config --cflags gtk4 file.c pkg-config --libs gtk4在linux上编译CSS文件。

pbossiut

pbossiut1#

我尝试了你的代码,在测试不同数量的按钮时,这个问题似乎围绕着gtk_flow_box小部件的行为。随着更多的按钮被添加,按钮的大小和扭曲程度都在增加。无论我怎么尝试,程序都不允许缩小窗口的大小,使椭圆形按钮看起来像圆形按钮。
我不知道你是否必须使用GTK流盒,但如果不是,你可以尝试使用GTK网格盒来代替。下面是你的程序的重构版本,容器引用从流盒改为网格盒。

#include <gtk/gtk.h>

#define WINDOW_HEIGHT 300

GtkWidget * stop;
int num_stops;

static void stop_toggle (GtkToggleButton *source, gpointer user_data)
{
    //have to use set child here
    if (gtk_toggle_button_get_active(source))
    {
        gtk_widget_set_name(GTK_WIDGET(source), "stop_button_pressed");
    }
    else
    {
        gtk_widget_set_name(GTK_WIDGET(source), "stop_button");
    }
}

static void make_toggles (GtkWidget * window)
{
    GtkWidget * stop_grid;                                      /* Revised name to pertain to a grid box */
    short i;

    stop_grid = gtk_grid_new();
    gtk_grid_set_column_spacing(GTK_GRID(stop_grid), 10);
    gtk_grid_set_row_spacing(GTK_GRID(stop_grid), 10);

    //initialise stops on this panel
    char label[7];
    label[0] = '\0';

    /*gtk_flow_box_set_column_spacing(GTK_FLOW_BOX(stop_flow), 0);
    gtk_flow_box_set_row_spacing(GTK_FLOW_BOX(stop_flow), 0);
    gtk_flow_box_set_selection_mode(GTK_FLOW_BOX(stop_flow), GTK_SELECTION_NONE);*/

    gtk_widget_set_name(stop_grid, "window_main");

    for (i = 0; i < num_stops; i++)
    {
        for (int j = 0; j < num_stops; j++)                 /* Create a 4 x 4 grid of buttons */
        {
            sprintf(label, "%d", i * num_stops + j + 1);
            stop = gtk_toggle_button_new_with_label(label);
            gtk_widget_set_name(stop, "stop_button");
            gtk_grid_attach(GTK_GRID(stop_grid), stop, j, i * num_stops, 1, 1);
            //gtk_flow_box_append(GTK_FLOW_BOX(stop_flow), stop);
            g_signal_connect(stop, "toggled", G_CALLBACK(stop_toggle), NULL);
        }
    }

    gtk_window_set_child (GTK_WINDOW (window), stop_grid);
}
static void app_startup(GtkApplication* app)
{
    //use this to figure out number of stops and pistons from the LCS app
    num_stops = 4;                                                          /* Revised for unit testing */
}
static void activate (GtkApplication* app, gpointer user_data)
{
    GtkWidget *window;

    window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "Left Panel");
    gtk_window_set_default_size (GTK_WINDOW (window), 300, WINDOW_HEIGHT);  /* Revised for unit testing */
    make_toggles(window);

    GtkCssProvider * cssProvider = gtk_css_provider_new();
    gtk_css_provider_load_from_path(cssProvider, "styling2.css");           /* Revised for unit testing */
    gtk_style_context_add_provider_for_display(gtk_widget_get_display(window), GTK_STYLE_PROVIDER(cssProvider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
    gtk_widget_show (window);
}

int main(int argc, char **argv)
{
    GtkApplication *app;
    int status;

    app = gtk_application_new("lcs.console", 0);                            /* Revised for unit testing */
    g_signal_connect(app, "startup", G_CALLBACK(app_startup), NULL);
    g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
    status = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return status;
}

在代码重构的沿着,样式表也做了一些修改,添加了一些填充。

#window_main {
    background-color: #c5dbe0;
    padding:10px;
}

#stop_button {
    background-color: white;
    background-size: 100% 100%;
    background-position: center center;
    border-radius: 50%;
    color: black;
    font-weight: bold;
    font-size: xx-large;
    min-width:40px;
    min-height:40px;
    padding:10px;
    border:20px;
}
#stop_button_pressed {
    background-color: yellow;
    background-size: 100% 100%;
    background-position: center center;
    border-radius: 50%;
    color: black;
    font-weight: bold;
    font-size: xx-large;
    min-width:40px;
    min-height:40px;
    padding:10px;
    border:20px;
}

通过这些重构和改进,可以生成一个带有圆形按钮的窗口。

同样,如果使用GTK流程框不是强制性的,您可以尝试这些调整,看看它是否符合您的项目的精神。

相关问题