How to capture clicks on header in wxPython grids - python

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)

Related

Place a button inside a grid

In a gui I have a grid. In this grid each row represents an order. To the right of each row, I would like to place a 'cancel button'to cancel the order. When new rows are added this should automatically come with a cancel button.
I did some seaching but apart from this FAQ-question which states that you have to design something yourself (did not help me much). Al other material was based on usage of Tkinter which I do not want to do.
So Two questions:
(1) Does anyone know of a way to place a button in a grid cell in wxpython?
(2) If not, does anyone know of a solution for my requirement?
Thanks,
Django
There isn't really a "built-in" way to do this. You would need to create a custom Renderer. According to Robin Dunn (creator of wxPython) in this thread, you could create a button using wx.RendererNative.DrawPushButton.
I would also recommend taking a look at the wxPython demo as it has some other examples of custom renderers too.

AuiNotebook - Get clicked tab

I am currently using some wxPython's AuiNotebook in one of my projects and I have a problem that can't manage to solve. I think there should be a simple solution but can't manage to find it.
I have created a new class derived from wx.lib.agw.aui.AuiNotebook and I am trying to get the index of a tab at the moment it's clicked. I wrote something like that:
class NewNotebook(wx.lib.agw.aui.AuiNotebook):
# __init__ function an stuff...
def OnTabClicked(self, evt):
index = self.GetSelection()
print index
wx.lib.agw.aui.AuiNotebook.OnTabClicked(self, evt)
The aim was to capture the index of the tab clicked on and in some cases, have a special behavior, or just perform a regular click otherwise. However, I think that AuiNotebook.OnTabClicked actually changes the selection among different things. It would explain why index contains the value of the tab that was selected before the click.
I did not a find a way to get the selection of the new tab though. I looked for some information in the captured event but still could not find the one I wanted.
So, does someone know how I can get the selected tab before I call AuiNotebook.OnTabClicked?
There doesn't seem to be a builtin way to do this. The closest I found was something I helped with on the wxPython mailing list, but that had to do with double-clicking.
Here's one workaround that came to me though. When you first show the frame, set some kind of class property to the currently shown tab (i.e. self.currentTab = 0). Then catch the EVT_AUINOTEBOOK_PAGE_CHANGING or EVT_AUINOTEBOOK_PAGE_CHANGED event and update the property. For me, when I catch EVT_AUINOTEBOOK_PAGE_CHANGING, I always get the index of the tab I'm clicking on, at least on Windows.

Make Spinctrl selected when activated in WxPython

I have 4 spinctrls in my app. When I click on them, I want all their
content to be selected instantly. And another thing is, I need to make
them tab traversal. Can you help me with some sort of code to do this
task?
Thanks in advance.
You need to catch EVT_SPIN or EVT_SPINCTRL and in your handler, you can select all the values by calling each of the control's GetValue method. In the wxPython demo, it seems to support tab traversal. I'm not sure what's going on with yours. Did you try the FloatSpin widget as an alternative?

Call a Function in Another Frame (WxPython)

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.

How do I scroll a wxPython wx.html.HtmlWindow back down to where it was when the user clicked a link?

I am using a wxPython wx.html.HtmlWindow to display part of my interface. The user can scroll down a list of links in a window smaller than the list. When they click on a link, I need to repaint the web page, but I want to return the page position back to where they clicked it.
I've tried MouseEvent.GetLogicalPosition() on the event, but it wants a DC and the best I've been able to do is get the same information as GetPosition(), so I must not be feeding it the right one.
I also tried HtmlWindow.CalcScrolledPosition(), but apparently that isn't available in HtmlWindow because I get a NotImplementedError...
What I would like is a scroll position that can be derived from the MouseEvent, or the OnLinkClicked information.
I know about HtmlWindow.ScrollToAnchor(), but it's flaky and unaesthetic -- I would prefer to bypass it if possible so that I can scroll back exactly to where the user clicked.
Thanks!
how about having a look at the source of wxHtmlWindow for inspiration? for example at wxHtmlWindow::LoadPage(): it
// store[s the current] scroll position into history item:
int x, y;
GetViewStart(&x, &y);
(*m_History)[m_HistoryPos].SetPos(y);
this saved scroll position is used in wxHtmlWindow::HistoryBack():
Scroll(0, (*m_History)[m_HistoryPos].GetPos());
Refresh();
to go back to the saved position.
i would assume that this built-in "go-to-the-last-position-in-window" handling isn't the most "flaky and unaesthetic". could something similar work for you, too?
Maybe a bit late, but with some tips from ax, and some hints from here, I think that calling:
scrollpos = wx.html.HtmlWindow.GetViewStart()[1]
and storing that, and then later doing a call to:
wx.html.HtmlWindow.Scroll(0, scrollpos)
works for me. Of course, you do need to change wx.html.HtmlWindow to an actual reference to an instance.
Here is what I am doing to scroll page to previous position.
I do this to avoid blinking.
pos = self.GetViewStart()[1]
self.Freeze()
self.SetPage(src)
if save_scroll_pos:
self.Scroll(0, pos)
self.Thaw()
Usually, click events are trigged by MouseUp events. If you track the mouse position by capturing any MouseDown events, you will know where the last click (MouseUp) happened, and that should allow you to reconstruct things.
For this particular problem, you might have to do a bit more work in MouseDown like checking if they are within the wxHtmlWindow control and if so, then saving something like a line number.

Categories