繁体   English   中英

GTK2 +自动调整按钮标签的字体大小

[英]GTK2+ Automatically adjusting the font size of a button's label

我正在做一个井字游戏,作为一个学校项目。 我在3行中设置了9个按钮,因此,每当用户单击其中一个按钮时,其标签将以纯文本格式更改为X或O。

在此处输入图片说明

我想知道X / O的大小是否可能根据窗口的大小而改变。 我的另一个想法是使用X / O图像而不是纯文本(至少因为我假设如果使用大图像,它将自动按比例缩小)。 我并不是真的想要这样做,因为检查玩家何时赢得比赛的功能会比较标签的文字。

这是负责创建和添加按钮的代码:

GtkWidget *button;
button = gtk_button_new_with_label("");
gtk_box_pack_start(GTK_BOX(theBox),button,FALSE,TRUE,0);
g_signal_connect(GTK_OBJECT(button),"clicked",GTK_SIGNAL_FUNC(ButtonClicked),EntryBox);
gtk_widget_show(button);

这是我的ButtonClicked函数:

void ButtonClicked(GtkButton *button, gpointer data)
{
  if (strcmp(gtk_button_get_label(button), "") == 0)
    if (count % 2 != 0)
      gtk_button_set_label(button, "X");
}

另外,当我在这里时,我还有另一个问题:我将窗口边框设置为0,但是您仍然可以看到非常少量的边框,有什么办法可以消除呢?

您可以尝试一下,我使用"expose-event"绘制了XO以及一个空白单元格,以防用户尚未单击它,并且还使用了一个简单的函数来检查获胜者。 通过将数据传递到事件处理程序来设置单元格值。

"button-release-event"允许您在单击某个单元格时执行某些操作,然后您可以将下一个回合更改为其他玩家,并根据所单击的单元格的回合时间将XO设置为所单击的单元格。点击。

检查一下

#include <gtk/gtk.h>

#include <stdlib.h>
#include <math.h>

enum Player
{
    FirstPlayer,
    SecondPlayer
};

enum TicTacValue
{
    None,
    Empty,
    Unset,
    X,
    O
};

struct GameData
{
    enum TicTacValue value;
    enum Player *player;
    struct GameData *data;
    gint row;
    gint column;
};

enum TicTacValue
evaluate(enum TicTacValue previous, enum TicTacValue next)
{
    if (previous == Unset)
        return next;
    if (previous != next)
        return None;
    return next;
}

void
check_winner(struct GameData *data)
{
    enum TicTacValue rows[3] = {Unset, Unset, Unset};
    enum TicTacValue diagonals[2] = {Unset, Unset};
    enum TicTacValue columns[3] = {Unset, Unset, Unset};
    enum TicTacValue winner;

    for (size_t i = 0 ; i < 9 ; ++i)
    {
        columns[i % 3] = evaluate(columns[i % 3], data[i].value);
        rows[i / 3] = evaluate(rows[i / 3], data[i].value);
        switch (i)
        {
            case 4:
                diagonals[0] = evaluate(diagonals[0], data[i].value);
                diagonals[1] = evaluate(diagonals[1], data[i].value);
                break;
            case 0:
            case 8:
                diagonals[0] = evaluate(diagonals[0], data[i].value);
                break;
            case 2:
            case 6:
                diagonals[1] = evaluate(diagonals[1], data[i].value);
                break;
        }
    }

    winner = diagonals[0] | diagonals[1];
    winner = winner | columns[0] | columns[1] | columns[2];
    winner = winner | rows[0] | rows[1] | rows[2];
    if (winner < Unset)
        return;
    fprintf(stderr, "Player %d WINS (-)\n", winner - Unset);
}

gboolean
on_click(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
    struct GameData *game_data;
    game_data = (struct GameData *) data;
    if (game_data->value != Empty)
        return FALSE;
    if (*(game_data->player) == FirstPlayer)
    {
        game_data->value = X;
        *(game_data->player) = SecondPlayer;
    }
    else
    {
        game_data->value = O;
        *(game_data->player) = FirstPlayer;
    }
    gtk_widget_queue_draw(widget);
    check_winner(game_data->data);
    return FALSE;
}

void
draw_delmiter_line(cairo_t *cairo, gint x1, gint y1, gint x2, gint y2)
{
    cairo_save(cairo);
    cairo_set_source_rgb(cairo, 0.65, 0.65, 0.65);
    cairo_set_antialias(cairo, CAIRO_ANTIALIAS_NONE);
    cairo_set_line_width(cairo, 1);
    cairo_move_to(cairo, x1, y1);
    cairo_line_to(cairo, x2, y2);
    cairo_stroke(cairo);
    cairo_restore(cairo);
}

void
draw_x(cairo_t *cairo, gint width, gint height)
{
    gint size;

    size = width / 3.5;

    cairo_save(cairo);
    cairo_set_source_rgb(cairo, 0.25, 0.4, 1.0);
    cairo_set_line_width(cairo, 2.5);
    cairo_translate(cairo, width / 2, height / 2);
    cairo_move_to(cairo, -size, -size);
    cairo_line_to(cairo, +size, +size);
    cairo_move_to(cairo, +size, -size);
    cairo_line_to(cairo, -size, +size);
    cairo_stroke(cairo);
    cairo_restore(cairo);
}

void
draw_o(cairo_t *cairo, gint width, gint height)
{
    cairo_save(cairo);
    cairo_set_source_rgb(cairo, 1.0, 0.25, 0.25);
    cairo_set_line_width(cairo, 2.5);
    cairo_arc(cairo, width / 2, height / 2, width / 3, 0, 2.0 * M_PI);
    cairo_stroke(cairo);
    cairo_restore(cairo);
}

gboolean
on_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
    GdkWindow *window;
    cairo_t *cairo;
    const struct GameData *game_data;
    gint width;
    gint height;

    window = gtk_widget_get_window(widget);
    cairo = gdk_cairo_create(window);
    game_data = (const struct GameData *) data;

    gdk_window_get_size(window, &width, &height);

    if (game_data->row != 2)
        draw_delmiter_line(cairo, 0, height, width, height);
    if (game_data->column != 3)
        draw_delmiter_line(cairo, width, 0, width, height);

    if (game_data->value == X)
        draw_x(cairo, width, height);
    else if (game_data->value == O)
        draw_o(cairo, width, height);
    cairo_destroy(cairo);
    return FALSE;
}

int
main(int argc, char **argv)
{
    GtkWidget *window;
    GtkWidget *horizontal[3];
    GtkWidget *vertical;
    struct GameData data[9];
    enum Player current_player;
    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    vertical = gtk_vbox_new(TRUE, 0);
    for (size_t i = 0 ; i < 3 ; ++i)
    {
        horizontal[i] = gtk_hbox_new(TRUE, 0);
        gtk_box_pack_start(GTK_BOX(vertical), horizontal[i], TRUE, TRUE, 0);
    }

    current_player = FirstPlayer;
    for (size_t i = 0 ; i < 9 ; ++i)
    {
        GtkWidget *cell;

        cell = gtk_drawing_area_new();
        data[i].value = Empty;
        data[i].player = &current_player;
        data[i].data = data;
        data[i].row = i / 3;
        data[i].column = i % 3;

        g_signal_connect(G_OBJECT(cell), "expose-event", G_CALLBACK(on_expose), &data[i]);
        g_signal_connect(G_OBJECT(cell), "button-release-event", G_CALLBACK(on_click), &data[i]);

        gtk_widget_add_events(cell, GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK);
        gtk_box_pack_start(GTK_BOX(horizontal[data[i].row]), cell, TRUE, TRUE, 0);
    }
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

    gtk_container_add(GTK_CONTAINER(window), vertical);
    gtk_widget_set_size_request(window, 300, 300);
    gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM