我如何 "pause" 应用程序让用户按下按钮? GTK
How can I "pause" app for user to press a button? GTK
我正在使用 GTK 3.0 在 C 中制作纸牌游戏。我有两个函数用于两个 windows,openMenu() 打开菜单和 newGame() 用卡片 table 创建一个新的 window。玩家正在与两个随机选择卡片的机器人对战。我需要玩家选择一张牌来开始游戏。
打开菜单:
static void openMenu(int argc, char *argv[]){
GtkBuilder *builder;
GtkWidget *window;
GObject *button;
GError *error = NULL;
gtk_init(&argc, &argv);
builder = gtk_builder_new_from_file("menu_window_glade.glade");
window = GTK_WIDGET(gtk_builder_get_object(builder, "menu_window"));
gtk_builder_connect_signals(builder, NULL);
gtk_widget_show(window);
gtk_main();
}
新游戏:
void newGame(){
GtkBuilder *builder;
GtkWidget *window;
GtkImage *image;
widgetsPtrs *widgets = malloc(sizeof(widgetsPtrs));
char imageStr[] = "image00";
char aImgstr[] = "A0";
char dImgstr[] = "D0";
builder = gtk_builder_new_from_file("game_glade.glade");
window = GTK_WIDGET(gtk_builder_get_object(builder, "game_glade_window"));
gtk_builder_connect_signals(builder, NULL);
gtk_widget_show(window);
shuffleTheDeck();
printAll(Deck);
card *player = malloc(sizeof(card));
card *leftBot = malloc(sizeof(card));
card *rightBot = malloc(sizeof(card));
deal(player, 0);
deal(leftBot, 0);
deal(rightBot, 0);
/***************Puts images into buttons***********/
tmpCard = player;
for (size_t i = 0; i < 6; i++)
{
tmpCard = tmpCard->next;
imgPath[20] = zero + tmpCard->rank;
imgPath[21] = zero + tmpCard->suit;
gtk_image_set_from_file(GTK_IMAGE(widgets->w_playersHandPtr[i]), imgPath);
}
int a = firstTurnCheck();
playersTurn(player, leftBot, rightBot);
}
问题来自这里:我想到了一个循环的想法,只有在全局布尔值发生变化时才能打破循环,而全局布尔值在服务于点击事件的函数中发生变化。 但是,带有游戏 table 的 window 不显示 ,因此我永远无法单击按钮,因此应用程序冻结。
void playersTurn(card *player, card *leftBot, card *rightBot){
bool DEFENDERTOOKTHECARDS = false;
bool RBHASMORE = true;
PLAYERCHOOSING = true;
int attackCounter = 0;
int *appearedRanks = calloc(9, sizeof(int));
card *cardsOnTheTable = malloc(sizeof(card)); //cardsOnTheTable[0] is a pointer to the table
char answer;
puts("Player's Turn");
puts("Choose a card.");
/*****************The spot where the mistake might be****************/
while(PLAYERCHOOSING);//PLAYERCHOOSING is a global bool.
puts("You've chosen a card.");
}
On_card_click 函数:
void on_card_clicked(GtkButton *button, gpointer *data){
gtk_widget_hide(GTK_WIDGET(data));
PLAYERCHOOSING = false;
}
除其他外,这一行是一个问题:(正如您在评论中猜到的那样。)
while(PLAYERCHOOSING);//PLAYERCHOOSING is a global bool.
进不去
至少它应该能够检查标志以查看是否按下了按钮:
while(PLAYERCHOOSING)
{
if(buttonToggled)//define as another global boolean value, and set when button is pressed
{
PLAYERCHOOSING = false;
buttonToggled = false;
}
else Sleep(1000); //sleep for 1 second
}
更好的方法是 运行 主线程中的用户界面,然后将内务处理(按钮按下检测和处理)放在第二个线程中。回调函数可以定义为按钮按下处理程序。
(void on_card_clicked(GtkButton *button, gpointer *data)
似乎是回调。)
非常感谢@ryyker 提供的建议。
该解决方案基于线程。正如我所说,我以前从未与他们合作过,但我花了大约 15 分钟才弄清楚我需要的一切,所以没有什么好害怕的:)这是我的解决方案:
- '#include < pthread.h >',
- declare pthread_t thread in newGame(),
- add pthread_create(&thread, NULL, playersTurn, NULL); into newGame()
- you can leave 'while(PLAYERCHOOSING)' loop as it is.
- compile with -lpthread flag.
瞧,你真了不起。
我不明白为什么那么多人喜欢用线程做任何事情。 GTK 有一个主循环,使用它(有关更多信息,请参阅 )。您不能使用 sleep
、无限循环或任何其他阻塞调用,否则您会阻塞处理 UI 事件的主循环。
所以不只是把:
PLAYERCHOOSING = true;
在 playersTurn
和
PLAYERCHOOSING = false;
在on_card_clicked
中够吗?
我正在使用 GTK 3.0 在 C 中制作纸牌游戏。我有两个函数用于两个 windows,openMenu() 打开菜单和 newGame() 用卡片 table 创建一个新的 window。玩家正在与两个随机选择卡片的机器人对战。我需要玩家选择一张牌来开始游戏。 打开菜单:
static void openMenu(int argc, char *argv[]){
GtkBuilder *builder;
GtkWidget *window;
GObject *button;
GError *error = NULL;
gtk_init(&argc, &argv);
builder = gtk_builder_new_from_file("menu_window_glade.glade");
window = GTK_WIDGET(gtk_builder_get_object(builder, "menu_window"));
gtk_builder_connect_signals(builder, NULL);
gtk_widget_show(window);
gtk_main();
}
新游戏:
void newGame(){
GtkBuilder *builder;
GtkWidget *window;
GtkImage *image;
widgetsPtrs *widgets = malloc(sizeof(widgetsPtrs));
char imageStr[] = "image00";
char aImgstr[] = "A0";
char dImgstr[] = "D0";
builder = gtk_builder_new_from_file("game_glade.glade");
window = GTK_WIDGET(gtk_builder_get_object(builder, "game_glade_window"));
gtk_builder_connect_signals(builder, NULL);
gtk_widget_show(window);
shuffleTheDeck();
printAll(Deck);
card *player = malloc(sizeof(card));
card *leftBot = malloc(sizeof(card));
card *rightBot = malloc(sizeof(card));
deal(player, 0);
deal(leftBot, 0);
deal(rightBot, 0);
/***************Puts images into buttons***********/
tmpCard = player;
for (size_t i = 0; i < 6; i++)
{
tmpCard = tmpCard->next;
imgPath[20] = zero + tmpCard->rank;
imgPath[21] = zero + tmpCard->suit;
gtk_image_set_from_file(GTK_IMAGE(widgets->w_playersHandPtr[i]), imgPath);
}
int a = firstTurnCheck();
playersTurn(player, leftBot, rightBot);
}
问题来自这里:我想到了一个循环的想法,只有在全局布尔值发生变化时才能打破循环,而全局布尔值在服务于点击事件的函数中发生变化。 但是,带有游戏 table 的 window 不显示 ,因此我永远无法单击按钮,因此应用程序冻结。
void playersTurn(card *player, card *leftBot, card *rightBot){
bool DEFENDERTOOKTHECARDS = false;
bool RBHASMORE = true;
PLAYERCHOOSING = true;
int attackCounter = 0;
int *appearedRanks = calloc(9, sizeof(int));
card *cardsOnTheTable = malloc(sizeof(card)); //cardsOnTheTable[0] is a pointer to the table
char answer;
puts("Player's Turn");
puts("Choose a card.");
/*****************The spot where the mistake might be****************/
while(PLAYERCHOOSING);//PLAYERCHOOSING is a global bool.
puts("You've chosen a card.");
}
On_card_click 函数:
void on_card_clicked(GtkButton *button, gpointer *data){
gtk_widget_hide(GTK_WIDGET(data));
PLAYERCHOOSING = false;
}
除其他外,这一行是一个问题:(正如您在评论中猜到的那样。)
while(PLAYERCHOOSING);//PLAYERCHOOSING is a global bool.
进不去
至少它应该能够检查标志以查看是否按下了按钮:
while(PLAYERCHOOSING)
{
if(buttonToggled)//define as another global boolean value, and set when button is pressed
{
PLAYERCHOOSING = false;
buttonToggled = false;
}
else Sleep(1000); //sleep for 1 second
}
更好的方法是 运行 主线程中的用户界面,然后将内务处理(按钮按下检测和处理)放在第二个线程中。回调函数可以定义为按钮按下处理程序。
(void on_card_clicked(GtkButton *button, gpointer *data)
似乎是回调。)
非常感谢@ryyker 提供的建议。 该解决方案基于线程。正如我所说,我以前从未与他们合作过,但我花了大约 15 分钟才弄清楚我需要的一切,所以没有什么好害怕的:)这是我的解决方案:
- '#include < pthread.h >',
- declare pthread_t thread in newGame(),
- add pthread_create(&thread, NULL, playersTurn, NULL); into newGame()
- you can leave 'while(PLAYERCHOOSING)' loop as it is.
- compile with -lpthread flag.
瞧,你真了不起。
我不明白为什么那么多人喜欢用线程做任何事情。 GTK 有一个主循环,使用它(有关更多信息,请参阅 sleep
、无限循环或任何其他阻塞调用,否则您会阻塞处理 UI 事件的主循环。
所以不只是把:
PLAYERCHOOSING = true;
在 playersTurn
和
PLAYERCHOOSING = false;
在on_card_clicked
中够吗?