This is quite an essential part of my program and I need to have sorted out as soon as possible so anything would be a massive help.
My program consists of three modules which are imported to each other. One module consists of my user interface for which I am using tkinter. The user inputs data on a canvas which is sent to a second program to be processed and is then sent to the third module which contains the algorithm which I intend to step through with the user.
The "first" and "third" modules can interact with each other and during certain points in explaining the algorithm I change the appearance of the canvas and some text on the interface. The third module should then pause (for which I'm currently using a basic sleep method), and wait (ideally it will wait for the user to press the "Next Step" button on the user interface). It is during this step that my interface decides that it wants to freeze.
Is there any way I can stop this?
Many thanks in advance.
Edit: I've found a way to fix this. Thank you for all the suggestions!
Calling time.sleep() will stop your program doing anything until it finishes sleeping. You need Tkinter to keep processing events until it should run the next part of your code.
To do that, put the next part of your code in a separate function, and get Tkinter to call it when it's ready. Typically, you want this to happen when the user triggers it (e.g. by clicking a button), so you need to bind it to an event (docs). If you actually want it to happen after a fixed time, you can use the .after() method on any tkinter widget (docs).
GUI programming takes a bit of getting used to. You don't code as a series of things happening one after the other, you write separate bits of code which are triggered by what the user does.
Terminology note: if your Python files import each other, you have three modules, but it's still all one program. Talking about the "first program" will confuse people.
H.E.P -
The traditional way to do this does indeed involve using a separate thread and co-ordinating the work between the "worker" thread and the GUI thread using some sort of polling or eventing mechanism.
But, as Thomas K. points out, that can get very complex and tricky, especially regarding Python's use of the Global Interpreter Lock (GIL) etc. and having to also contend with Tkinter's processing loop.
(The only good reason to use a multi-threaded GUI is if you absolutely MUST ensure that the GUI remains responsive during a potentially long-running background task, which I don't believe is the issue in this case.)
What I would suggest instead is a generator-based "co-routine"-type architecture.
As noted in "The Python (2.7) Language Reference", Section 6.8, [the "yield" statement is used when defining a generator function and is only used in the body of the generator function. Using a yield statement in a function definition is sufficient to cause that definition to create a generator function instead of a normal function.]
(This effectively forms the basis of a co-routine architecture. (ed.))
[When a generator function is called, it returns an iterator known as a generator iterator, or more commonly, a generator. The body of the generator function is executed by calling the generator’s next() method repeatedly until it raises an exception.
When a yield statement is executed, the state of the generator is frozen and the value of expression_list is returned to next()‘s caller. By “frozen” we mean that all local state is retained, including the current bindings of local variables, the instruction pointer, and the internal evaluation stack: enough information is saved so that the next time next() is invoked, the function can proceed exactly as if the yield statement were just another external call.]
(Also see "PEP 0342 - Coroutines via Enhanced Generators " for additional background and general info.)
This should allow your GUI to call the next part of your algorithm specification generator, on demand, without it having to be put to sleep until the operator presses the "Next" button.
You would basically just be creating a little 'domain-specific language', (DSL), consisting of just the list of steps for your presentation of this particular algorithm, and the generator (iterator) would simply execute each next step when called (on demand).
Much simpler and easier to maintain.
A GUI program is always waiting for some action to occur. When actions do occur, the event code corresponding to that action is executed. Therefore, there is no need to call sleep(). All you need to do is set it up so that the third program is executed from the appropriate event.
Related
I have a GTK window. It turns out that if I schedule several redraw calls all at once, without any delay, from a separate thread, using idle_add(window.queue_draw), only one call will execute.
While if I do idle_add(custom_function), every single scheduled call to custom_function will run.
While it's clear that this is done for optimization, I can't see if/where this is mentioned in the documentation [1] and I also wonder if there are other such rules for idle_add.
[1] https://developer.gnome.org/pygobject/stable/glib-functions.html
It actually isn't idle_add that is making that behavior. The docs for widget-queue-draw-region, which gets called by queue-redraw, state that redrawing only gets done after the main loop is no longer busy.
I am trying improve my Python and tkinter skills. At this moment I am reading a book on tkinter. I noticed that in an object oriented GUI application the author defines the button callbacks this way:
def on_fast_forward_button_clicked(self):
self.player.fast_forward()
def on_rewind_button_clicked(self):
self.player.rewind()
So, if I understand correctly, we are writing to methods for each button in the application class. One with the "indirect" callback, called but the event, and other with the intended action itself, called by the previous one. Why should we write code like this, instead of just using a single method?
There's no specific reason, and in the example you give I absolutely wouldn't do it that way.
It's really quite simple: in general terms, every button should be associated with a function. That's it. That's the rule. What that function does is totally up to you.
If all it ever does is a single thing, there's no reason it can't directly call that single thing. If it needs to do more than one thing, create a special purpose function that does everything the button should do, and have that button call that function.
That being said, there's a conceptual difference between "responding to a button" and "performing an action". For example, you might have two or three ways to do the fast-forward function: you might have a command on the menubar, a command on a right-click menu, a dedicated fast-forward button, and a keyboard accelerator.
Depending on how these are implemented, the functions they call may or may not require extra arguments (eg: a function bound to an event always gets an event object). In that case it is often easier to have a special purpose function that is designed to respond to the event, and that special purpose function call the more general-purpose fast_forward function.
At the end of the day, it's all about clarity. If you think it makes the program easier to understand when you have a single function perform two roles (fastforward, and respond to a button click), by all means do it that way.
Think about it like this: currently, all the button does is have the player fast forward. What if in the future however you also wanted the clock, or some other entity to fast forward with it? Would it make any sense to stick those fast forward calls inside player.fast_forward()? Should the player's methods really have access to information like that?
on_fast_forward_button_clicked is acting as a wrapper to encompass everything that may need to be fast forwarded. If you ever need to add any functionality, all you need to do is make a minor modification:
def on_fast_forward_button_clicked(self):
self.player.fast_forward()
self.clock.fast_forward()
I wrote a recursive python function. After 30min - 1 hour it cancel the process because it ran out of memory. If I look in the task manager I also see that too much ram memory is used. If I restart the function everything is fine again. How can I avoid this problem and let the program "run forever"?
As a rule of thumb, you should not use recursive calls in long-running programs. Of course there are exceptions...
Recursive functions are typically used where the application indicates managing something which calls for that functionality: Eg. traversing a tree structure, or looking up something in a database until a certain level of detail is reached.
Long-running programs rarely are of that class... Even scraping pages with a robot always have a point of reference (when the 'scrape' of one site is finished), where the recursion has to start from scratch. It is sometimes difficult to diagnose the problem (I found, in the logs of my website, that one of the better-known robots got stuck on an infinite loop on a bad link. Beware of infinite loops!).
Enlarging Python's stack is rarely the solution... Add lines to your code to check that the recursion depth returns to 0 at known intervals in your application. Or add a depth counter...
I'm wondering how to go about implementing a macro recorder for a python gui (probably PyQt, but ideally agnostic). Something much like in Excel but instead of getting VB macros, it would create python code. Previously I made something for Tkinter where all callbacks pass through a single class that logged actions. Unfortunately my class doing the logging was a bit ugly and I'm looking for a nicer one. While this did make a nice separation of the gui from the rest of the code, it seems to be unusual in terms of the usual signals/slots wiring. Is there a better way?
The intention is that a user can work their way through a data analysis procedure in a graphical interface, seeing the effect of their decisions. Later the recorded procedure could be applied to other data with minor modification and without needing the start up the gui.
You could apply the command design pattern: when your user executes an action, generate a command that represents the changes required. You then implement some sort of command pipeline that executes the commands themselves, most likely just calling the methods you already have. Once the commands are executed, you can serialize them or take note of them the way you want and load the series of commands when you need to re-execute the procedure.
Thinking in high level, this is what I'd do:
Develop a decorator function, with which I'd decorate every event-handling functions.
This decorator functions would take note of thee function called, and its parameters (and possibly returning values) in a unified data-structure - taking care, on this data structure, to mark Widget and Control instances as a special type of object. That is because in other runs these widgets won't be the same instances - ah, you can't even serialize a toolkit widget instances, be it Qt or otherwise.
When the time comes to play a macro, you fill-in the gaps replacing the widget-representating object with the instances of the actually running objects, and simply call the original functions with the remaining parameters.
In toolkits that have an specialized "event" parameter that is passed down to event-handling functions, you will have to take care of serializing and de-serializing this event as well.
I hope this can help. I could come up with some proof of concept code for that (although I am in a mood to use tkinter today - would have to read a lot to come up with a Qt4 example).
An example of what you're looking for is in mayavi2. For your purposes, mayavi2's "script record" functionality will generate a Python script that can then be trivially modified for other cases. I hear that it works pretty well.
I am working on a text-based game in Python 3.1 that would use timing as it's major source of game play. In order to do this effectively (rather than check the time every mainloop, my current method, which can be inaccurate, and slow if multiple people are playing the game at once) I was thinking about using the Threading.Timer class. Is it a bad thing to have multiple timers going at the same time? if so, how many timers is recommended?
For example, the user inputs to start the game. every second after the game starts it decides whether or not something happens, so there's a Timer(1) for every user playing at the same time. If something happens, the player has a certain time to react to it, so a timer must be set for that. If the user reacts quickly enough, that timer needs to end and it will set a new timer depending on what's going to happen next, etc
I think its a bad idea to use Timers in your case.
Using the delayed threads in python will result in more complex code, less accuracy, and quite possible worse performance. Basically, the rule is that if you think you need threads, you don't. Very few programs benefit from the use of threads.
I don't know what you are doing for input. You make reference to multiple players and I'm not sure whether thats on a single keyboard or perhaps networked. Regardless, your current strategy of a main loop may well be the best strategy. Although without seeing how your main loop operates its hard to say for certain.
It should be perfectly safe to have multiple timers going at the same time. Beware that it may not give much of a performance boost, as the CPython interpreter (the standard Python interpreter) uses a GIL (Global Interpreter Lock) which makes threading stuff a bit.... slow.