I'm trying to add a tkinter GUI to a simple text-based game made in python but I'm struggling with the game loop, which either runs infinitely or not at all. I would like the game to ask the player what they want to do, then do something based on that, then return to asking the player what they want. The problem I'm having is instead of calling the function once, it calls it repeatedly.
while playing is True:
getAreaDesc()
requestPlayerMove()
if action == 1:
explore()
elif action == 2:
travel()
elif action == 3:
rest()
window.update_idletasks()
window.update()
I'm fairly sure I know what is causing the problem. As I understand it, this is because the value for action is determined by a tkinter button (with a command setting the value for action) so as soon as a button is pressed, it calls the relevant function. Then it checks again but as the action is still the same, it calls the function again. And so on and it doesn't stop until a different button is pressed and a different. I think it's like a lightswitch in the sense that once it's on it stays on, even though the switch is only flicked once.
However, even if I am right about why it calls the functions continuously, I can't think of a way to prevent that occuring which doesn't simply stop the loop.
I've tried resetting action as part of the functions, but that causes it to do nothing beyond ask for player choice. Similarly, trying to nest the if/elif parts comes to the same result, and using after() changes nothing but the speed at which it loops relentlessly. And those were my good ideas. I tried putting input() back in to wait for the player and that went about as well as you could imagine.
I'm sure it's something daft I'm missing, hopefully not offensively stupid, but I'm at a loss and any help would be very appreciated. Thanks for your time reading this, if your patience lasted this far.
Related
An answer to this question might be either about tkinter or parallel loops. I am not sure which solution will be the best. I need your advice.
I have a while True loop, which goes infinitely. Each loop takes around 5 seconds or more, and I wanted to create a GUI button (skip and stop_skip buttons). If the skip button is clicked by a user, it will skip the current while loop and move on to the next while loop until 'stop_skip' button is clicked. So, the skip button will be working as 'continue' in a loop.
Since each loop takes around 5 seconds, I want it to check the variable frequently in the loop. I found that tk.after() may work in every x milliseconds, and some people mentioned tk.update_idletasks() and tk.update(). I tried them, but they just show the box when the loop begins and freeze for the rest 5 seconds. If nothing can work like this (performing a function repetitively with intervals in a while loop), I will probably put if conditions multiple times during the while loop.
The script I want may look like..
show_tk_gui()
while True:
check_tk_if_skip_button_clicked(interval==1000) #if clicked, continue to the next while loop until 'stop_skip' button is clicked.
performing_5_sec_calculation()
Is there any way that can make this possible? Not using GUI option is also acceptable.
To cut a long story short, I've been doing an interactive GUI (tkinter) word-game program for school. At first, everything went smoothly, but having finished the code, it has started to behave in unexpected ways when I run it. Some dialog boxes (particularly the
if tkinter.messagebox.askyesno():
thingy) just rapidly answer themselves with the 'no' option, rather than waiting for user input. Sometimes, the windows close off completely and cause the whole program to quit. However, although these errors are all the same (i.e. tkinter windows closing/answering themselves/stopping the program before they should), they usually happen in different places every time. I'm not sure if that's to do with the fact that tkinter is nested, opened, re-opened and closed numerous times within other code, which is making it run messily, but I have only destroyed tkinter windows in the right places, as far as I know.
Part of my code involves a while loop - I'm not sure if that could be interfering with the mainloop()s, but I couldn't find another way to allow the user to repeat the game as many times as they want.
I know this question is vague, but I'm mainly looking for tips - if it would be easier to diagnose if I split it up into different sections and tidy it up a bit, found an alternative for the while loop, etc.
Thanks!
TKinter dialogs should be fully completed and the results stored before moving onto the next section of code.
Make sure you provide all the arguments to the dialog (your example doesn't include the parameters).
result = tkinter.messagebox.askyesno('Confirm', 'Do you want to do this')
if result == true:
So, I'm currently planning a program using the Easygui module,
The problem I am facing is, when I press the cancel button on the GUI, it just continues, so to get past this, I want to add something to my program like:
if Easygui_Variable is None:
quit()
However, the problem I face is, I am going to have multiple easygui boxes which allow the user to press cancel, and I don't want to be using
if Easygui_Variable is None:
quit()
every time, so is there anyway I can do the above for multiple variables at a time, to make sure my program is most efficient.
I am making a kind of puzzle game and it's been suggested that I use Pygame. I have looked at some tutorials but I am unable to get certain things to show.
Number of moves - I'm basically looking for something that will count how many times the numbers 1 - 6 are pressed.
Timer - I'd like this to start when someone presses a key and stop after a condition has been fulfilled.
Win / fail screen - I'm looking to have something pop up saying the user has won or failed depending on if certain criteria have been met.
Any help on getting these displayed would be greatly appreciated.
Firstly get familiar with pygame font module : http://www.pygame.org/docs/ref/font.html
You will need a way to display string and numbers to the user. Simply make a font object, and render surfaces with the strings, to later blit them like any other bitmap you had.
Also i suggest to look into the time module: the pygame docs are really helpful : http://www.pygame.org/docs/ref/time.html. Here you will use this module to create a small class Timer, with a Clock object to stop and reset, and update functions. In the update functions, you can add the delta(the difference between the last and recent call of tick()) to the overall time or simply depend on the functions given in the time module. You can call stop when a condition is satisfied.
Last, for the screen, you may want to divide your game/app into states, where the game state is only rendered and looped when a play flag == true. When the game is over, you can switch the state to win/lose state to display the information and probably a prompt if the player may want to play again.
I am writing a timer program in Python using PyGTK. It is precise to the hundredths place. Right now, I am using a constantly updated label. This is a problem, because if I resize the window while the timer is running, Pango more often than not throws some crazy error and my program terminates. It's not always the same error, but different ones that I assume are some form of failed draw. Also, the label updates slower and slower as I increase the font size.
So, I am wondering if there is a more correct way to display the timer. Is there a more stable method than constantly updating a label?
Updating a label should work perfectly reliably, so I suspect you're doing something else wrong. Are you using threads? What does your code look like? How small can you condense your program (by removing functionality, not by obfuscating the code), without making the problem go away?
I figured out the problem. It was indeed a problem with the threads. I never would've guessed that myself. The trick is to use gobject.timeout_add() to create a timer instead of a threaded loop. Here is some information about gobject.timeout_add():
http://faq.pygtk.org/index.py?req=show&file=faq01.021.htp
Don't forget to have your function return True, or the timer will stop.