How to make wxPanel accept keyboard focus, when it has sibling widgets? Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Tapsa
Earned some good credits
Earned some good credits
Posts: 147
Joined: Tue Dec 06, 2011 5:52 pm
Location: Helsinki

How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by Tapsa »

I can make wxPanel get keyboard focus only if there are no sibling or child widgets etc, but as soon as I add sibling widgets such as text controls, wxPanel can no longer receive focus.

I have code that draws into wxPanel, and I am using keyboard to change what is being drawn.

Catching key events is not the only problem. Elsewhere I have scrolled panel. Once a text control inside it has has focus and I scroll so it goes out of sight. When I come back to the window from another app and click on anything in the scrolled panel (panel itself or control accepting focus) the focus will go straight to that text control that last had it, also scrolling the panel annoyingly.
catalin
Moderator
Moderator
Posts: 1618
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by catalin »

Override AcceptsFocus() to always return true. See wxPanel::AcceptsFocus() docs for more info.
Tapsa
Earned some good credits
Earned some good credits
Posts: 147
Joined: Tue Dec 06, 2011 5:52 pm
Location: Helsinki

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by Tapsa »

The documentation says about wxPanel::AcceptsFocus that
returns true only if there is no child window in the panel which can accept the focus
and my wxPanel that I draw onto indeed does not have child windows at all.

I tried this, and as expected, nothing changed.

Code: Select all

class APanel: public wxPanel
{
public:
    APanel(wxWindow *parent, long style = wxTAB_TRAVERSAL):
    wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style)
    {
    }
    bool AcceptsFocus() const {return true;}
};
The problem is that some parent window is stealing the focus and assigning it to another focusable child (sibling of the wxPanel I need to focus) every time I try to focus the wxPanel without children.
catalin
Moderator
Moderator
Posts: 1618
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by catalin »

Ok, I was expecting that to no longer pass the focus to its children.
Then use a wxWindow instead of wxPanel. It will no longer fwd focus.
And about non-child siblings, they should not steal focus, even from a wxPanel, once you clicked on it or gave the focus to it in some other way.
Tapsa
Earned some good credits
Earned some good credits
Posts: 147
Joined: Tue Dec 06, 2011 5:52 pm
Location: Helsinki

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by Tapsa »

After changing my wxPanels to wxWindows, they no longer accept keyboard focus even when they are alone, before creating any other child/sibling controls. It's time I go look in the wxPanel source codes.
catalin
Moderator
Moderator
Posts: 1618
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by catalin »

What wxW version are you using ?
Try using a wxWindow in minimal sample and see if it behaves different than in your app.
Tapsa
Earned some good credits
Earned some good credits
Posts: 147
Joined: Tue Dec 06, 2011 5:52 pm
Location: Helsinki

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by Tapsa »

I am using wx 3.1.0. This isn't a bug, but something that I want to do.

Code: Select all

class APanel: public wxPanel
{
public:
    APanel(wxWindow *parent, long style = wxTAB_TRAVERSAL):
    wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style) {}
    bool AcceptsFocus() const {return true;}
    bool AcceptsFocusFromKeyboard() const {return true;}
    bool AcceptsFocusRecursively() const {return true;}
    bool IsFocusable() const {return true;}
    bool CanAcceptFocus() const {return true;}
    bool CanAcceptFocusFromKeyboard() const {return true;}
};
Even this code doesn't help. As soon as I click on sibling wxTextCtrl, no matter how many times I click on the wxPanel, the flashing | remains in the wxTextCtrl and everything that I type on keyboard goes into that wxTextCtrl, not into my wxPanel that is designed to handle key down events.
catalin
Moderator
Moderator
Posts: 1618
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by catalin »

1. Open minimal sample.
2. Add a wxWindow.
3. Add a wxTextCtrl as a child of wxWindow.
How does that work?
Tapsa
Earned some good credits
Earned some good credits
Posts: 147
Joined: Tue Dec 06, 2011 5:52 pm
Location: Helsinki

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by Tapsa »

4. Add a wxPanel as child of wxWindow.

I don't believe this is a bug, rather no one has described a way to force wxPanel to always receive focus, not giving it to its siblings.
Anyway, when trying to compile minimal I get
include/wx/platform.h:136:22: fatal error: wx/setup.h: No such file or directory
I also tried catching the set focus event in wxPanel, but it never got there after a sibling wxTextCtrl etc was created.

This thread describes the same problem I have:
http://wxpython-users.wxwidgets.narkive ... us-problem
catalin
Moderator
Moderator
Posts: 1618
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by catalin »

Tapsa wrote:4. Add a wxPanel as child of wxWindow.
No. Why ? Don't use any wxPanel. Use wxWindow and paint on it. Obviously if you keep using wxPanel, any wxWindow ancestor is useless.
Just go with the 3 steps I described and see the focus behaviour. There is really nothing else I can add here.

It is not a bug, it's the way wxPanel is supposed to work.

You get that error when you have not compiled [that build target of] the library.

That is because, as you can clearly see, the focus event does not get to the wxPanel but too its first child that can accept focus. BTW, "siblings" are usually widgets that have the same parent, and not in a parent-child relationship.
Tapsa
Earned some good credits
Earned some good credits
Posts: 147
Joined: Tue Dec 06, 2011 5:52 pm
Location: Helsinki

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by Tapsa »

This way then:
1. Open minimal sample.
2. Add a wxWindow.
3. Add a wxTextCtrl as a child of wxWindow.
4. Add a wxWindow as a child of wxWindow.


If I directly use SetSizer on the wxFrame, I get ugly background, that is why an extra wxWindow is needed.
There is really nothing else I can add here.
I'll be waiting for others to comment. Else I have to forget about keyboard events, and add a bunch of buttons to make up for them. Why can't there just be a paint widget that wants keyboard focus. Perhaps I will make one giant wxTextCtrl and draw onto its background.
wxPanel is supposed to work
So how do I make a window that doesn't work this way?
Using wxWindow in place of wxPanel helps nothing based on my tests.
siblings are usually widgets that have the same parent
Did I not make this clear multiple times? Sibling and child have nothing to do with each other. Maybe you have not yet understood what I'm trying to achieve.
catalin
Moderator
Moderator
Posts: 1618
Joined: Wed Nov 12, 2008 7:23 am
Location: Romania

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by catalin »

Tapsa wrote:I get ugly background
You can set any background colour you want, including "standard" ones.
Tapsa wrote:Perhaps I will make one giant wxTextCtrl and draw onto its background.
Right, the only thing is that you cannot paint on a wxTextCtrl. But I guess you should indeed try that rather than simple changes to minimal sample.
Tapsa wrote:Using wxWindow in place of wxPanel helps nothing based on my tests.
For the n-th time, try in the minimal sample.
Tapsa wrote:Maybe you have not yet understood what I'm trying to achieve.
Yes, maybe I haven't.. Nevertheless, good luck!
Tapsa
Earned some good credits
Earned some good credits
Posts: 147
Joined: Tue Dec 06, 2011 5:52 pm
Location: Helsinki

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by Tapsa »

:D I have good news. Googling a little bit more I found this thread:
https://groups.google.com/forum/#!topic ... i_Rlrn_QHU
It shouldn't be necessary to call SetFocus().
Then I realized I can just call SetFocus in my left mouse click handler, and it works!
Mino260806
In need of some credit
In need of some credit
Posts: 1
Joined: Wed May 27, 2020 10:45 am

Re: How to make wxPanel accept keyboard focus, when it has sibling widgets?

Post by Mino260806 »

wxPanel::SetFocusIgnoringChildren() is exactly what you want! 8)
Post Reply