It seems that you're using an outdated browser. Some things may not work as they should (or don't work at all).
We suggest you upgrade newer and better browser like: Chrome, Firefox, Internet Explorer or Opera

×
low rated
I'm going out of my mind, even farther than usual, because I've been trying to implement something that should be extremely simple using wxWidgets, and should probably take less than an hour, but for some reason, I just can't get it to work at all, and I have barely any time to work on it, so I end up spending a couple hours or so, once every week or two, and months have gone by, yet I've made very little progress, and many times I make none at all!

I've already been to Stack Overflow, and as always, their advice is virtually useless, on the rare occasions that they actually reply to me (and I can't even post a follow-up there unless it's a relatively short "comment", because the only other way that I can see to do it is by posting an "answer", but I have no answers at all - only questions), so I thought I'd post here, since people on this website tend to be far more helpful, despite it not even being a programming website.

They did tell me to try using a GUI tool to automatically make the thing, bu that doesn't work well at all, because three were recommended, but a couple of them are incompatible or I have no reasonable way of installing them, and the one that I managed to get to run is wxFormBuilder, but it doesn't seem to have the necessary tools or capabilities, or otherwise I just can't figure out how to get it to work (for example, I can make various controls, but they don't appear correctly in the hierarchy, and even when I move them around, they still don't become children of the proper parents, and when I make something like a notebook, I can't even make tabs for it, etc.).

So what I REALLY need is for someone to just fix my tiny amount of code for me. Links to tutorials are also welcome, because I understand the teaching a man to fish philosophy, but at this point, I'm afraid I may just be incapable of learning how to fish and I'm starving to death, so I'm begging you to just PLEASE give me a FISH!!!

All I'm trying to do is make a window (or frame, or whatever) with a menu bar along the top, then fill the whole thing with a notebook with various tabs which will be added as needed. Then within the notebook I want to split it into a left and right section (using a splitter window, I suppose, unless there's a better way), such that it shows different content on each tab, except that in all cases, the left section has a customizable tree control, and the right section contains yet another notebook control. Within this notebook control, the content, and even its format, should be completely customizable for different tabs (I'll provide the code for each circumstance, but I just need the notebook and its tabs to appear).

So far, I've written the code for the main notebook, splitting it into a left and right part, and putting a tree on the left part, but I haven't put the smaller/nested notebook on the right part yet. But I haven't even gotten all of this working yet, because depending on how I set it up, it sometimes shows the tree and other times it doesn't display, and it sometimes shows different things on different tabs, but other times it changes nothing when I click the tabs. Sometimes I get an error that says I've assigned the sizer to the wrong control with the wrong parent or something, but when I fix that so that the error disappears, the tree stops displaying correctly, if it even did in the first place, which is also iffy.

In any case, I just can't get it all to show up correctly and act properly without errors, no matter what I try, and it seems like I've tried every possible combination, but a working example would be EXTREMELY helpful! Unfortunately, it seems like the entire Internet has VERY little information on wxWidgets, and even less on wxFormBuilder, especially for the controls that I'm specifically using, so it's like I have no way of getting the information I need, because it simply doesn't exist! Does everyone have these problems when using this garbage tool, or is it just me?

Anyway, here's the code that I had initially written:



wxPanel* parent = new wxPanel(this, wxID_ANY);

wxBoxSizer* vbox = new wxBoxSizer(wxVERTICAL);

wxNotebook* notebook = new wxNotebook(parent, wxID_ANY, wxDefaultPosition, this->GetSize());
wxPanel* notebookWindow = new wxPanel(notebook, wxID_ANY);

parent->SetSizer(vbox);
Center();
Maximize(true);

notebook->SetSize(this->GetSize());
notebook->AddPage(notebookWindow, wxT("Tab one"), true, 0);
notebook->AddPage(notebookWindow, wxT("Tab two"), true, 0);

wxSplitterWindow* splitterWindow = new wxSplitterWindow(notebookWindow, wxID_ANY);

wxTreeCtrl* tree = new wxTreeCtrl(splitterWindow, wxID_ANY, wxPoint(0, 0), wxSize(200, 1000), wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT | wxTR_HIDE_ROOT | wxTR_EDIT_LABELS);

wxTreeItemId rootID = tree->AddRoot(wxT("Root"));
wxTreeItemId item1ID = tree->AppendItem(rootID, wxT("Item 1"));
wxTreeItemId item2ID = tree->AppendItem(rootID, wxT("Item 2"));
wxTreeItemId item3ID = tree->AppendItem(rootID, wxT("Item 3"));
wxTreeItemId item4ID = tree->AppendItem(item2ID, wxT("Item 4"));

vbox->Add(splitterWindow, 1, wxALL | wxEXPAND, 5);



I was told that I needed to make different windows for each tab, or else it wouldn't change the content when I switched between them, which makes sense, so I changed some things around, and got this:



parent = new wxPanel(this, wxID_ANY);

wxBoxSizer* vbox1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* vbox2 = new wxBoxSizer(wxVERTICAL);

wxNotebook* notebook = new wxNotebook(parent, wxID_ANY, wxDefaultPosition, this->GetSize());

wxPanel* firstWindow = new wxPanel(notebook, wxID_ANY);
wxPanel* secondWindow = new wxPanel(notebook, wxID_ANY);

firstWindow->SetSizer(vbox1);
secondWindow->SetSizer(vbox2);

Center();
Maximize(true);

notebook->SetSize(this->GetSize());
notebook->AddPage(firstWindow, wxT("Tab one"), true, 0);
notebook->AddPage(secondWindow, wxT("Tab two"), true, 0);

wxSplitterWindow* splitterWindow = new wxSplitterWindow(firstWindow, wxID_ANY);

wxTreeCtrl* tree = new wxTreeCtrl(splitterWindow, wxID_ANY, wxPoint(0, 0), wxSize(200, 1000), wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT | wxTR_HIDE_ROOT | wxTR_EDIT_LABELS);

wxTreeItemId rootID = tree->AddRoot(wxT("Root"));
wxTreeItemId item1ID = tree->AppendItem(rootID, wxT("Item 1"));
wxTreeItemId item2ID = tree->AppendItem(rootID, wxT("Item 2"));
wxTreeItemId item3ID = tree->AppendItem(rootID, wxT("Item 3"));
wxTreeItemId item4ID = tree->AppendItem(item2ID, wxT("Item 4"));

vbox1->Add(firstWindow, 1, wxALL | wxEXPAND, 5);
vbox2->Add(secondWindow, 1, wxALL | wxEXPAND, 5);



But that caused other problems with the tree not appearing correctly, and so on. Keep in mind that I'm just making a couple of test tabs now, and eventually I'll be making them programmatically, to add as many as needed whenever necessary at run time, but for now, this kind of simple example should work fine, just to get the interface working. But what have I done wrong? Could someone just fix this code to get it to work, also with the nested notebook placed to the right of the tree control, in the right window within the splitter window, PLEASE?! Thank you very much if you can fix this, because I'm desperate!
No posts in this topic were marked as the solution yet. If you can help, add your reply
Can you provide a minimal compilable example, e.g. on github/bitbucket/gitlab or some other file sharing site? It's been over 10 years since I did a lot of wx programming (the last GUI project I did from scratch I used Qt instead, and I guess I don't see the advantage of wx as much as I used to, not that I like Qt all that much, either). In any case, I'll be away from the computer for the rest of the day, so it would be awhile before I could respond. My guess is that there is an issue with one of your event handlers (either missing or incorrect), but I can't really look at it more closely without knowing what "other" code is involved.

As to the form builders, I've only used them to create xrc files, not code. All that was hand-made, so I can't comment on the quality of the generated code.
Well supposedly the GUI editors (or I guess they're called form builders) should give correct code, I would think.

Unfortunately, I can't provide a complete program, because I'm on a different computer right now, and I don't have access to that stuff at the moment, and this computer doesn't even have any languages or anything installed (and I'm running Linux, but I wrote that in C++ .NET on Windows). Also, the whole program has some proprietary stuff in it, so I'd have to make something with just this experimental part and nothing else in it, and as I said, I don't have access to it right now, anyway.

However, all I really need is a simple program that displays the interface which I need, and I'll take it from there and complete it the rest of the way. So that's almost all of the code that you'd need, aside from the default stuff that it puts in just to make it a valid C++ program with an event handler, included files, etc.

EDIT: And by the way, I can't use Qt, because as I understand it, there's licensing involved if I want to make anything and potentially distribute it, but I need something completely free with absolutely no strings attached (and it needs to be cross-platform), so I chose wxWidgets, because frankly, I don't know of anything better (if anything at all) which has all of my requirements.
Post edited March 11, 2023 by HeresMyAccount
OK, well, I finally had a little more time to look at this. In general, you don't seem to matching the object hierarchy to your described, desired hierarchy. You fixed the first obvious one in your second example, but you still add firstWindow to vbox1 and secondWindow to vbox2, even though they are actually the windows containing these respective sizers. What you should probably be adding to vbox1 is the splitterwindow. I am also unsure how you're activating the splitterwindow correctly. Missing code (or did I miss something due to my encroaching blindness)? From the documentation:

After using this constructor, you must create either one or two subwindows with the splitter window as parent, and then call one of Initialize(), SplitVertically() and SplitHorizontally() in order to set the pane(s). You can create two windows, with one hidden when not being shown; or you can create and delete the second pane on demand.
This is the doxygen documentation that comes with wxWidgets. Do you have this easily available? There is probably a web page out there with it, but I don't feel like looking. I have it installed by default on my system. It seems fairly complete. A similar comment was in the wxNotebook documentation, which might've saved you some time in coming up with the second iteration of your code.

As to Qt, well, I don't know if the LGPL version would be sufficient, but if it's for a commercial product, and you need professional assistance, you may be better off getting your company to pony up the cash for a commercial license. I don't really like Qt that much myself (see e.g. https://github.com/darktjm/grok/blob/master/QT-README.md for some of my gripes), so I won't press this point further.
Post edited March 14, 2023 by darktjm
Thanks for the tip, I'll look into all of that stuff when I get time (which should be in about a week - it looks like neither of us has much spare time).

I'm not sure I've heard of doxygen but I'll look that up too. Thanks.

If I remember correctly, when I looked into Qt, it said that it either must be used for an open source project or otherwise must be purchased or something. The thing is, I don't have a company, but I'm just doing this as a hobby. However, I'm a very private person, and I do all of my coding (and pretty much everything else, for that matter) completely anonymously, so I can't very well buy something and put my name on a license or whatever, and I'm not about to provide my source code if I ever distribute anything, so i just wanted something with no strings attached, hence the wxWidgets.
avatar
HeresMyAccount: If I remember correctly, when I looked into Qt, it said that it either must be used for an open source project or otherwise must be purchased or something.
I know I said I'd stop talking about Qt, but just to clarify: Qt used to have a more restrictive license (GPL?+Commercial). In the mean time, much of Qt has been made LGPL+Commerical instead, meaning that you technically can use it and link to it as long as you don't make any changes to Qt itself. You simply distribute Qt as shared libraries built from public sources that you reference (or depend on the target to supply them) rather than statically linking. Do not take what I say as legal advice, but the general consensus is that Qt is safe if you only use the LGPL parts (which should include most of what you are doing; it's only the QUiLoader stuff that was GPL last time I looked).

In any case, switching to Qt would not likely solve all of your problems, and would instead just introduce a whole new set of problems.
Try this:

void MyFrame::AddContent()
{
wxNotebook * notebook = new wxNotebook(this, wxID_ANY);

auto clientSizer = new wxBoxSizer(wxVERTICAL);
clientSizer->Add(notebook, 1, wxEXPAND); //Fill entire sizer
SetSizer(clientSizer);

AddTabPage(wxT("Tab one"), notebook);
AddTabPage(wxT("Tab two"), notebook);
}

void MyFrame::AddTabPage(const wxString& tabName, wxNotebook* notebook)
{
wxSplitterWindow* splitterWindow = new wxSplitterWindow(notebook, wxID_ANY);

wxTreeCtrl* tree = new wxTreeCtrl(splitterWindow, wxID_ANY, wxDefaultPosition, wxSize(200, 0), wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT | wxTR_HIDE_ROOT | wxTR_EDIT_LABELS);
wxTreeItemId rootID = tree->AddRoot(wxT("Root"));
wxTreeItemId item1ID = tree->AppendItem(rootID, wxT("Item 1"));
wxTreeItemId item2ID = tree->AppendItem(rootID, wxT("Item 2"));
wxTreeItemId item3ID = tree->AppendItem(rootID, wxT("Item 3"));
wxTreeItemId item4ID = tree->AppendItem(item2ID, wxT("Item 4"));

wxNotebook* nestedTabs = new wxNotebook(splitterWindow, wxID_ANY, wxDefaultPosition);
nestedTabs->AddPage(new wxPanel(nestedTabs), wxT("Tab A"));
nestedTabs->AddPage(new wxPanel(nestedTabs), wxT("Tab B"));

splitterWindow->SplitVertically(tree, nestedTabs);

notebook->AddPage(splitterWindow, tabName);
}
Post edited March 14, 2023 by binteon
Thanks binteon! I'll try that as soon as I get some time to do so (which unfortunately may be the middle of next week - I really wish I had more time), but it looks very good!
I finally got a chance to implement it and it works great! Thanks so much!