Call a Function in Another Frame (WxPython) - python

In my wxpython app, I have a parent frame and a child frame. When I click on a button inside the child frame, I want it to send some data (list, string etc.) to the parent frame, close itself, show the parent and finally call a function in the parent frame. How can I do that? (especially function calling)
Thanks in advance.
SOLVED

You should have the button click generate an event containing the data. Then add an event handler to the parent frame that extracts the data from the event and calls the function. The wxPython wiki has a tutorial that covers events. The wx documentation also has an event handling overview.

You can use pubsub to do that too: http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/
Or you can just use a subclass of a Dialog instead and show it modally. Or you could use PostEvent to pass the event. There's an example here: http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/
Another method that I just thought of would be to use a socket server or similar and post your data to that and have your program check the server for new data. That's pretty convoluted for this use case though.

Related

How to capture clicks on header in wxPython grids

I am trying to sort columns in wxPython grids and for that I want to run a function when there is a left click in a column header. Now what is the right hierarchy to process the event and how would you run the function once it happens?
The class HeaderCtrl has the method EVT_HEADER_CLICK, but how can I include this method in my binds?
self.Bind(wx.EVT_HEADER_CLICK,self.sortData)
I think you want to use the wx.Grid.EVT_GRID_LABEL_LEFT_CLICK event.
See: http://www.blog.pythonlibrary.org/2010/04/04/wxpython-grid-tips-and-tricks/
Try
self.grid.Bind(wx.EVT_HEADER_CLICK,self.sortData)

Python GUI Events

I'm sure this question has been asked many times before, so I apologize in advance. I simply cannot find the answer via google or searching stack overflow.
I'm working in python with the wx library. I simply need a wx.EVT_CHAR to be thrown anytime a user presses a key, no matter the focus. How can this be accomplished? Is there a way to bind all widgets? Or a way to always throw an event when application receives a key press?
I tried binding the application itself, the main frame, and the main panel. None of these have accomplished the job of always throwing a wx.EVT_CHAR when a key is pressed.
I was able to solve my problem by writing a recursive method that sets every widget to receive characters and binds every widget to my callback function. It's pretty simple, but took me a bit of googling to realize that not every widget can inherently receive text events (such as a button). Hopefully this will save someone some time in the future. It should be noted that only widgets that are children or subchildren of the parent window passed will be bound to the callback method.
def __RecursiveBinding(self, parent):
try:
parent.Bind(wx.EVT_CHAR, self.CharInputCallback)
parent.SetWindowStyleFlag(wx.WANTS_CHARS)
parent.Refresh()
children = parent.GetChildren()
if(children):
for child in children:
self.__RecursiveBinding(child)

wxPython update a listbox live

I am developing a programme using python & wxPython. I have a listbox, and I need for it to be updated live to be used as a log.
I have done this simply with the Append() function, but the text added to the listbox is not shown until the end of the procedure, instead of being shown when the Append command is executed. I know this because after each insertion I print the size of the listbox.
def writeLog(self, text):
self.log.Append(text)
print self.log.GetStrings().__len__()
Right now, for checking purposes, I am calling a script that has the following code:
parent.writeLog("aaaaaa")
sleep(1)
parent.writeLog("aaaaaa")
sleep(1)
parent.writeLog("aaaaaa")
I have tried these answers but I couldn't make them work for me:
Update a ListBox in wxPython
wxPython: Update wx.ListBox list
So, How can I see the listBox updated in the screen right after the writeLog function is called? Is it possible? Thanks!
You have a few options here, the easiest perhaps is to call wx.Yield() when you want the ui to be updated, so after your Append calls
Another solution would be to to get any text that needs adding in a separate thread, and then send it back to the main thread via a custom event or pubsub which can then Append to the listbox

View All Binds, wxpython

Is there a way to view all binds of an object?
x=wx.Button(self,-1,"hi")
x.Bind(wx.EVT_BUTTON,self.Press)
###
print x.ShowAllBindingData() #Function doenst exists
[['EVT_BUTTON','Press']]
Is there anything like that
No, this is not possible. Mind you, if it were possible, it wouldn't be very useful because even if you don't call Bind() on the object itself, you could still process the event in different ways, e.g. by handling it at parent window level (for command events and the like only) or by pushing a custom event handler on top of the object or (this is probably C++-only though) overriding the virtual ProcessEvent() method directly.

PyQT events between multiple objects

I am creating a GUI program in Python/PyQT and would like to know how I can connect an event which happens in a child object to the parent?
For example, if someone clicks a 'Submit' button, how would i trigger something to happen in the parent object (lets say update a QLabel on the parent)
Any help would be greatly appreciated
L
It is done like in C++ Qt by connecting signals to slots, you will find all the information on this page (and here for the old way).
You must connect these methods every time you set new parent (and remove old connections!!)
http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qobject.html#connect
(If widget parent change and You still wont that new parent to recive signals)
But if your layout is static just give good names for your widgets. Then connect each signal to callable (any python function) and that function will change QLable.
In this case relation parent children change nothing since you refer to widgets by names not relations.

Categories