Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Python SOLVED: wx Correct way to alter GUI on the fly

  1. Aug 22, 2016 #1
    Happy Monday folks!

    I've been working on a program where I need to change the GUI on the fly. Specifically I need to do 2 things.
    This program pulls information from an RSS xml feed and displays it.
    As information is added (or removed) from the RSS feed I need to add or remove the information from the GUI. I have written this right now to add little panel objects (which contain a static text), and when they are removed I call object.destroy() on them.
    Secondly I'd like to set it up to inform the user that new information is available in some manner. I have set this up now to change the taskbar icon of the program back and forth basically causing a flashing.

    Both of these events are triggered using Threading.timers

    Now the big issue. The program runs great for a random amount of time and then messes up in one way or another.
    With dealing with the Panels eventually the program will have the correct number of panels, but some of them will be missing their information (the static text appears blank)

    With the flashing on linux it eventually throws an xwindows error and crashes, on windows the program stops responding to any further inputs.

    Both timers don't actually make the changes, they acquire a thread lock shared through the entire program, queue up an event and return.
    The event when handled sets up the subsequent timer.


    Based on that this isn't working I'm guessing that I'm not doing this in a the correct manner (obviously) any suggestions on how I should be doing this or what might be going on with the program??

    thanks :smile:
     
  2. jcsd
  3. Aug 22, 2016 #2

    jedishrfu

    Staff: Mentor

    My guess would be you have a memory leak somewhere. You could test this by using a process monitor like on top on linux or the windows monitor and see if thats whats happening.

    Next, you'll have to see that any open connections or files are properly closed and not left dangling around.

    One common mistake that programmers make is to create a database connection and to read in results and then keep the connection open while they do other things with the data like populate a gui list and then forget to close it.

    Often the better approach is to open the connection, get all the data and place it in an array, close the connection (ie connection is opened for a minimal amount of time) and then iterate the array populating the gui. Even with a small amount of the data this is still better.

    You mentioned that you have network connections with multi-threading and that may be where things are getting lost.

    Here's a reference on python memory leaks:

    http://pympler.readthedocs.io/en/latest/tutorials/muppy_tutorial.html

    I saw during my search that some folks have issues with TKinter and its canvas component having memory leaks so you might want to check around.

    http://stackoverflow.com/questions/13519811/what-is-causing-this-memory-leak-with-tkinter-canvas

    mentions things about update loops and multiple threads being needlessly created.
     
    Last edited: Aug 22, 2016
  4. Aug 22, 2016 #3
    Thanks for the response Jedishrfu

    I think I solved it, ironically by trying to rewrite the dammed thing in PyQt instead of WX.

    For anyone who stumbles on this in the future, what I've discovered is it is not safe to alter the GUI from any thread other than the actual GUI thread. I had been aware of this, but apparently the method I was using to ensure this wasn't actually working the way I intended.

    What you need to do is have whatever thread that you want trigger an custom event that the gui thread has binded.

    Fun 3 days chasing my tail on this one...
     
  5. Aug 26, 2016 #4

    Ibix

    User Avatar
    Science Advisor

    It's been a while since I used wx, but something you might want to look into is wx.CallAfter(). (Specifically, I used wxPython - but I think this is a wx feature rather than wxPython specific). You write a function or method called (e.g.) changeGUI() and put all your Panel adding and destroying there. Then your "work" thread updates the data and calls wx.CallAfter(changeGUI), and the GUI thread calls your change function at its convenience.

    I think you can have arguments if you want - changeGUI(x,y,z) would be called as wx.CallAfter(changeGUI,x,y,z).
     
  6. Aug 27, 2016 #5
    You could use one timer to get RSS feeds then 1. store or cache them and 2. push them up to your GUI
    After some time you only need to get the latest news then compare it with the cached value, renew the cache and update your GUI.
    You may need to think of your software solution in terms of a design pattern, e.g MVC or the likes.
    For example,
    your Feeds and your cache = model
    all your methods to get data from your model as well as to dispatch messages to or update your GUI = controller
    and your GUI = view
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted



Similar Discussions: SOLVED: wx Correct way to alter GUI on the fly
  1. Vb.net\ Gui (Replies: 5)

  2. Java GUI (Replies: 3)

  3. Python wx vs qt (Replies: 2)

  4. Arduino and GUI (Replies: 2)

Loading...