0

I'm attempting to transition a program from tkinter to Kivy. When I got to a section where I used messagebox.askyesno, I figured that I could just create a popup with a couple of buttons, and I'd be done. The issue I've encountered is that, while Kivy's popup and tkinter's messagebox are both modal, when I call messagebox.askyesno in a function, messagebox will halt all execution of the current function until the messagebox is destroyed, while the popup will allow the function to finish. My original program had

flag = messagebox.askyesno(message='...',parent=self)
if flag:
    #Stuff if flag is true
else:
    #Stuff if flag is false

However, this will not work with a Kivy popup since the popup will open, and the program will continue to execute. Is there a way to halt execution until the popup has been destroyed, or another way to solve the problem?

The basic idea is a quasi-dialog for a two player game. Here, the program asks one player if he wants to perform an action, such as move a piece. If the player says "yes," then the second player is given a messagebox.askyesno for a counter-move. A simple analogy is advancing a runner from first base to third base on a single in baseball. You would have to ask the offensive team if he wants to advance the runner, or have the runner remain at second. If the answer is yes, then the program would have to ask the defensive team if he wants to throw to third. It would definitely be possible to create a function to handle each instance of askyesno, with appropriate bindings, but it seems excessive.

Pistol Pete
  • 1,027
  • 2
  • 12
  • 25

1 Answers1

2

I'm not very familiar with how tkinter does things, but kivy requires a slightly different mental model here. You don't want to stop and start the eventloop in between bits of python code, but instead probably want to start the popup, pass any state you need into it or store it somewhere else, then bind the result of the popup (e.g. when the user presses a 'done' button) to some new function that does the rest of your calculation.

I can provide an example if you like, especially if you give more information about what you're trying to do.

inclement
  • 29,124
  • 4
  • 48
  • 60
  • Your assessment is something that I had considered, and if this situation only occurred once, then it would be viable. However, I have at least 10 instances of askyesno, and doing this for each occurrence, while possible, seems to be overkill. – Pistol Pete Apr 19 '14 at 22:34
  • Why would it be overkill...you still only need to write the code once? Perhaps you could provide a more complete example. – inclement Apr 19 '14 at 22:36
  • I've edited in a, hopefully, clearer example of what I'm trying to do. While your idea works, I'm thinking there has to be a cleaner solution than breaking functions, at least 10 in my case, to utilize a popup. – Pistol Pete Apr 20 '14 at 00:49
  • 1
    Honestly, I don't see what is unclean about breaking up your functions, and I think it's the best way (and only easy way I can think of). All you need to do is make an appropriate popup class that takes a function as an argument calls it when one is pressed, then you literally just add the new function name (`def whatever(flag):`) in between the popup creation and 'if flag' lines. I'll maybe make an example tomorrow. – inclement Apr 20 '14 at 01:23
  • It only seems unclean because your original program was built around blocking dialogs. Kivy discourages this kind of program flow. – brousch Apr 20 '14 at 13:29
  • @inclement if you could provide the example you mention, that may be helpful. – Pistol Pete Apr 22 '14 at 14:01
  • You're recommendation works nicely, it's a little painful, but it solved my problem. Thanks. – Pistol Pete Aug 20 '14 at 00:47